Bug 1267438 - Support adding ancestor mask layers from places other than SetupScrollingMetadata. r=mstange
MozReview-Commit-ID: DwdbSRdEMEc
--- a/gfx/layers/Layers.h
+++ b/gfx/layers/Layers.h
@@ -1083,28 +1083,37 @@ public:
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) MaskLayer", this));
mMaskLayer = aMaskLayer;
Mutated();
}
}
/**
* CONSTRUCTION PHASE ONLY
- * Add a FrameMetrics-associated mask layer.
+ * Add mask layers associated with LayerClips.
*/
void SetAncestorMaskLayers(const nsTArray<RefPtr<Layer>>& aLayers) {
if (aLayers != mAncestorMaskLayers) {
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) AncestorMaskLayers", this));
mAncestorMaskLayers = aLayers;
Mutated();
}
}
/**
* CONSTRUCTION PHASE ONLY
+ * Add a mask layer associated with a LayerClip.
+ */
+ void AddAncestorMaskLayer(const RefPtr<Layer>& aLayer) {
+ mAncestorMaskLayers.AppendElement(aLayer);
+ Mutated();
+ }
+
+ /**
+ * CONSTRUCTION PHASE ONLY
* Tell this layer what its transform should be. The transformation
* is applied when compositing the layer into its parent container.
*/
void SetBaseTransform(const gfx::Matrix4x4& aMatrix)
{
NS_ASSERTION(!aMatrix.IsSingular(),
"Shouldn't be trying to draw with a singular matrix!");
mPendingTransform = nullptr;
@@ -1347,16 +1356,19 @@ public:
// Ancestor mask layers are associated with FrameMetrics, but for simplicity
// in maintaining the layer tree structure we attach them to the layer.
size_t GetAncestorMaskLayerCount() const {
return mAncestorMaskLayers.Length();
}
Layer* GetAncestorMaskLayerAt(size_t aIndex) const {
return mAncestorMaskLayers.ElementAt(aIndex);
}
+ const nsTArray<RefPtr<Layer>>& GetAllAncestorMaskLayers() const {
+ return mAncestorMaskLayers;
+ }
bool HasMaskLayers() const {
return GetMaskLayer() || mAncestorMaskLayers.Length() > 0;
}
/*
* Get the combined clip rect of the Layer clip and all clips on FrameMetrics.
* This is intended for use in Layout. The compositor needs to apply async
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -2174,16 +2174,17 @@ ContainerState::CreatePaintedLayer(Paint
PaintedDisplayItemLayerUserData*
ContainerState::RecyclePaintedLayer(PaintedLayer* aLayer,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
bool& didResetScrollPositionForLayerPixelAlignment)
{
// Clear clip rect and mask layer so we don't accidentally stay clipped.
// We will reapply any necessary clipping.
aLayer->SetMaskLayer(nullptr);
+ aLayer->SetAncestorMaskLayers({});
aLayer->ClearExtraDumpInfo();
PaintedDisplayItemLayerUserData* data =
static_cast<PaintedDisplayItemLayerUserData*>(
aLayer->GetUserData(&gPaintedDisplayItemLayerUserData));
NS_ASSERTION(data, "Recycled PaintedLayers must have user data");
// This gets called on recycled PaintedLayers that are going to be in the
@@ -4620,18 +4621,21 @@ ContainerState::SetupScrollingMetadata(N
if (aEntry->mBaseScrollMetadata) {
metricsArray.AppendElement(*aEntry->mBaseScrollMetadata);
// The base FrameMetrics was not computed by the nsIScrollableframe, so it
// should not have a mask layer.
MOZ_ASSERT(!aEntry->mBaseScrollMetadata->HasMaskLayer());
}
- // Any extra mask layers we need to attach to FrameMetrics.
- nsTArray<RefPtr<Layer>> maskLayers;
+ // Any extra mask layers we need to attach to ScrollMetadatas.
+ // The list may already contain an entry added for the layer's scrolled clip
+ // so add to it rather than overwriting it (we clear the list when recycling
+ // a layer).
+ nsTArray<RefPtr<Layer>> maskLayers(aEntry->mLayer->GetAllAncestorMaskLayers());
for (const DisplayItemScrollClip* scrollClip = aEntry->mScrollClip;
scrollClip && scrollClip != mContainerScrollClip;
scrollClip = scrollClip->mParent) {
if (!scrollClip->mIsAsyncScrollable) {
// This scroll clip was created for a scroll frame that didn't know
// whether it needs to be async scrollable for scroll handoff. It was
// not activated, so we don't need to create a frame metrics for it.
@@ -5091,16 +5095,17 @@ FrameLayerBuilder::BuildContainerLayerFo
// The old layer for this item is actually our PaintedLayer
// because we rendered its layer into that PaintedLayer. So we
// don't actually have a retained container layer.
} else {
NS_ASSERTION(oldLayer->GetType() == Layer::TYPE_CONTAINER,
"Wrong layer type");
containerLayer = static_cast<ContainerLayer*>(oldLayer);
containerLayer->SetMaskLayer(nullptr);
+ containerLayer->SetAncestorMaskLayers({});
}
}
}
if (!containerLayer) {
// No suitable existing layer was found.
containerLayer = aManager->CreateContainerLayer();
if (!containerLayer)
return nullptr;