Bug 1267438 - Use the scrolled clip in AsyncCompositionManager. r=mstange draft
authorBotond Ballo <botond@mozilla.com>
Wed, 04 May 2016 18:52:56 -0400
changeset 364620 508f14af8caca19e296fd90b3bd19b6d16902d1c
parent 364619 4746e1cebf87e6eeda886041c745cfcce985db80
child 364621 66dc2ae14acf2ae399e810785ccd7ee51550445d
push id17504
push userbballo@mozilla.com
push dateFri, 06 May 2016 23:44:30 +0000
Bug 1267438 - Use the scrolled clip in AsyncCompositionManager. r=mstange MozReview-Commit-ID: LjV8bEhCexE
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -831,52 +831,64 @@ AsyncCompositionManager::ApplyAsyncConte
   AsyncTransformComponentMatrix combinedAsyncTransform;
   bool hasAsyncTransform = false;
   ScreenMargin fixedLayerMargins;
   // Each layer has multiple clips:
   //  - Its local clip, which is fixed to the layer contents, i.e. it moves
   //    with those async transforms which the layer contents move with.
+  //  - Its scrolled clip, which moves with all async transforms.
   //  - For each ScrollMetadata on the layer, a scroll clip. This includes
   //    the composition bounds and any other clips induced by layout. This
   //    moves with async transforms from ScrollMetadatas above it.
   // In this function, these clips are combined into two shadow clip parts:
   //  - The fixed clip, which consists of the local clip only, initially
   //    transformed by all async transforms.
-  //  - The scrolled clip, which consists of the scroll clips, transformed by
+  //  - The scrolled clip, which consists of the other clips, transformed by
   //    the appropriate transforms.
   // These two parts are kept separate for now, because for fixed layers, we
   // need to adjust the fixed clip (to cancel out some async transforms).
   // The parts are kept in a cache which is cleared at the beginning of every
   // composite.
   // The final shadow clip for the layer is the intersection of the (possibly
   // adjusted) fixed clip and the scrolled clip.
   ClipParts& clipParts = mClipPartsCache[aLayer];
   clipParts.mFixedClip = aLayer->GetClipRect();
+  clipParts.mScrolledClip = aLayer->GetScrolledClipRect();
   // If we are a perspective transform ContainerLayer, apply the clip deferred
   // from our child (if there is any) before we iterate over our frame metrics,
   // because this clip is subject to all async transforms of this layer.
   // Since this clip came from the a scroll clip on the child, it becomes part
   // of our scrolled clip.
-  clipParts.mScrolledClip = clipDeferredFromChildren;
+  clipParts.mScrolledClip = IntersectMaybeRects(
+      clipDeferredFromChildren, clipParts.mScrolledClip);
   // The transform of a mask layer is relative to the masked layer's parent
   // layer. So whenever we apply an async transform to a layer, we need to
   // apply that same transform to the layer's own mask layer.
   // A layer can also have "ancestor" mask layers for any rounded clips from
   // its ancestor scroll frames. A scroll frame mask layer only needs to be
   // async transformed for async scrolls of this scroll frame's ancestor
   // scroll frames, not for async scrolls of this scroll frame itself.
   // In the loop below, we iterate over scroll frames from inside to outside.
   // At each iteration, this array contains the layer's ancestor mask layers
   // of all scroll frames inside the current one.
   nsTArray<Layer*> ancestorMaskLayers;
+  // The layer's scrolled clip can have an ancestor mask layer as well,
+  // which is moved by all async scrolls on this layer.
+  if (const Maybe<LayerClip>& scrolledClip = aLayer->GetScrolledClip()) {
+    if (scrolledClip->GetMaskLayerIndex()) {
+      ancestorMaskLayers.AppendElement(
+          aLayer->GetAncestorMaskLayerAt(*scrolledClip->GetMaskLayerIndex()));
+    }
+  }
   for (uint32_t i = 0; i < aLayer->GetScrollMetadataCount(); i++) {
     AsyncPanZoomController* controller = aLayer->GetAsyncPanZoomController(i);
     if (!controller) {
     hasAsyncTransform = true;