Bug 1372912 - Push clips for all the scroll metadata scrollclips. r?jrmuizel draft
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 15 Jun 2017 17:02:18 -0400
changeset 594984 37386a6d16f51351a0ab60a8c7ce0734b5ecf48b
parent 594983 a9ea6675c59642476587c1275a0bcaf6f60f704e
child 594985 e4ecb253636daec99b0574d42d099ef883d84670
push id64210
push userkgupta@mozilla.com
push dateThu, 15 Jun 2017 21:03:35 +0000
reviewersjrmuizel
bugs1372912
milestone56.0a1
Bug 1372912 - Push clips for all the scroll metadata scrollclips. r?jrmuizel Each layer has a stack of scroll metadata objects, which represent the set of scrollframes that got flattened into the layer. Effectively the metadata objects provide the scroll information for the chain of scrollframes containing that layer's content. Each of these scrollframes may have a clip, and so we need to push those clips to WR. We need to take care to insert these clips at the right point in the stack, so that they are interleaved correctly with the PushScrollLayer calls that we use to inform WR of the scrolling clips for the scrollframes. This patch implements this behaviour. MozReview-Commit-ID: HD3OO5TZHSr
gfx/layers/wr/ScrollingLayersHelper.cpp
--- a/gfx/layers/wr/ScrollingLayersHelper.cpp
+++ b/gfx/layers/wr/ScrollingLayersHelper.cpp
@@ -26,16 +26,26 @@ ScrollingLayersHelper::ScrollingLayersHe
     // If APZ is disabled then we don't need to push the scrolling clips. We
     // still want to push the layer's local clip though.
     PushLayerLocalClip(aStackingContext);
     return;
   }
 
   Layer* layer = mLayer->GetLayer();
   for (uint32_t i = layer->GetScrollMetadataCount(); i > 0; i--) {
+    const ScrollMetadata& metadata = layer->GetScrollMetadata(i - 1);
+    // The scroll clip on a given metadata is affected by all async transforms
+    // from metadatas "above" it, but not the async transform on the metadata
+    // itself. Therefore we need to push this clip before we push the
+    // corresponding scroll layer, so that when we set an async scroll position
+    // on the scroll layer, the clip isn't affected by it.
+    if (const Maybe<LayerClip>& clip = metadata.GetScrollClip()) {
+      PushLayerClip(clip.ref(), aStackingContext);
+    }
+
     const FrameMetrics& fm = layer->GetFrameMetrics(i - 1);
     if (!fm.IsScrollable()) {
       continue;
     }
     LayerRect contentRect = ViewAs<LayerPixel>(
         fm.GetExpandedScrollableRect() * fm.GetDevPixelsPerCSSPixel(),
         PixelCastJustification::WebRenderHasUnitResolution);
     // TODO: check coordinate systems are sane here
@@ -129,19 +139,22 @@ ScrollingLayersHelper::~ScrollingLayersH
     return;
   }
   if (layer->GetIsFixedPosition()) {
     mBuilder->PopClipAndScrollInfo();
   }
   if (layer->GetScrolledClip()) {
     mBuilder->PopClip();
   }
-  for (int32_t i = layer->GetScrollMetadataCount(); i > 0; i--) {
-    const FrameMetrics& fm = layer->GetFrameMetrics(i - 1);
-    if (!fm.IsScrollable()) {
-      continue;
+  for (uint32_t i = 0; i < layer->GetScrollMetadataCount(); i++) {
+    const FrameMetrics& fm = layer->GetFrameMetrics(i);
+    if (fm.IsScrollable()) {
+      mBuilder->PopScrollLayer();
     }
-    mBuilder->PopScrollLayer();
+    const ScrollMetadata& metadata = layer->GetScrollMetadata(i);
+    if (metadata.GetScrollClip()) {
+      mBuilder->PopClip();
+    }
   }
 }
 
 } // namespace layers
 } // namespace mozilla