Bug 1267438 - Support adding ancestor mask layers from places other than SetupScrollingMetadata. r=mstange
authorBotond Ballo <botond@mozilla.com>
Fri, 06 May 2016 19:34:16 -0400
changeset 365138 1c8e4840f8b40b7e02b9274e446e278e8c907053
parent 365137 641eef89309781af7a63df344d0e1f495ba5efd8
child 365139 4aa07089ce57c4e66e6f4f4cacc915118ea39429
push id17650
push usermartin.thomson@gmail.com
push dateTue, 10 May 2016 05:06:10 +0000
reviewersmstange
bugs1267438
milestone49.0a1
Bug 1267438 - Support adding ancestor mask layers from places other than SetupScrollingMetadata. r=mstange MozReview-Commit-ID: DwdbSRdEMEc
gfx/layers/Layers.h
layout/base/FrameLayerBuilder.cpp
--- 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
@@ -4621,18 +4622,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.
@@ -5092,16 +5096,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;