Bug 1368496 - Propagate the layer's "scrolled clip" to WebRender. r=jrmuizel
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 08 Jun 2017 11:34:00 -0400
changeset 363027 6ca11746a8fc0914f47c00b526155348a9db8087
parent 363026 de72271be8b87e1472bc11825d4bc485a75d061f
child 363028 fd266694b1f8a5d81ce30382bde54d505139329e
push id31994
push usercbook@mozilla.com
push dateFri, 09 Jun 2017 10:56:24 +0000
treeherdermozilla-central@7c9d96bbc400 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1368496
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1368496 - Propagate the layer's "scrolled clip" to WebRender. r=jrmuizel If the layer has a "scrolled clip", that clip scrolls with the content of the layers (it moves if any of the scrollable frames defined by that layer are scrolled). MozReview-Commit-ID: 37hvXWO930f
gfx/layers/wr/ScrollingLayersHelper.cpp
--- a/gfx/layers/wr/ScrollingLayersHelper.cpp
+++ b/gfx/layers/wr/ScrollingLayersHelper.cpp
@@ -46,25 +46,47 @@ ScrollingLayersHelper::ScrollingLayersHe
     // a nominal top-left of 0,0 (maybe different for RTL pages?) and so to
     // get it in the same coordinate space we're going to shift it by the
     // composition bounds top-left.
     contentRect.MoveBy(clipBounds.TopLeft());
     mBuilder->PushScrollLayer(fm.GetScrollId(),
         aStackingContext.ToRelativeWrRect(contentRect),
         aStackingContext.ToRelativeWrRect(clipBounds));
   }
+
+  // The scrolled clip on the layer is "inside" all of the scrollable metadatas
+  // on that layer. That is, the clip scrolls along with the content in
+  // child layers. So we need to apply this after pushing all the scroll layers,
+  // which we do above.
+  if (Maybe<LayerClip> scrolledClip = layer->GetScrolledClip()) {
+    LayerRect clipRect = IntRectToRect(ViewAs<LayerPixel>(
+        scrolledClip->GetClipRect(),
+        PixelCastJustification::MovingDownToChildren));
+    Maybe<WrImageMask> mask;
+    if (Maybe<size_t> maskLayerIndex = scrolledClip->GetMaskLayerIndex()) {
+      Layer* maskLayer = layer->GetAncestorMaskLayerAt(maskLayerIndex.value());
+      WebRenderLayer* maskWrLayer = WebRenderLayer::ToWebRenderLayer(maskLayer);
+      // TODO: check this transform is correct in all cases
+      mask = maskWrLayer->RenderMaskLayer(maskLayer->GetTransform());
+    }
+    mBuilder->PushClip(aStackingContext.ToRelativeWrRect(clipRect),
+        mask.ptrOr(nullptr));
+  }
 }
 
 ScrollingLayersHelper::~ScrollingLayersHelper()
 {
   if (!mLayer->WrManager()->AsyncPanZoomEnabled()) {
     return;
   }
 
   Layer* layer = mLayer->GetLayer();
+  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;
     }
     mBuilder->PopScrollLayer();
   }
 }