Bug 1386483 - Split the wr_dp_push_clip method into two to allow reusing clips. r?jrmuizel draft
authorKartikaya Gupta <kgupta@mozilla.com>
Tue, 08 Aug 2017 15:43:17 -0400
changeset 642817 0b41784ec99d54ba9ca5764c17540a18dc353fe3
parent 642518 a921bfb8a2cf3db4d9edebe9b35799a3f9d035da
child 642818 62c90eabd3ba2b5eaf60afe5cac74854c36de3c6
push id72874
push userkgupta@mozilla.com
push dateTue, 08 Aug 2017 19:43:50 +0000
reviewersjrmuizel
bugs1386483
milestone57.0a1
Bug 1386483 - Split the wr_dp_push_clip method into two to allow reusing clips. r?jrmuizel MozReview-Commit-ID: 90BEJGs8wGg
gfx/layers/wr/ScrollingLayersHelper.cpp
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/WebRenderAPI.h
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi_generated.h
layout/painting/nsDisplayList.cpp
--- a/gfx/layers/wr/ScrollingLayersHelper.cpp
+++ b/gfx/layers/wr/ScrollingLayersHelper.cpp
@@ -118,17 +118,18 @@ ScrollingLayersHelper::PushLayerLocalCli
     // this layer has a mask, but no clip rect. so let's use the transformed
     // visible bounds as the clip rect.
     clip = Some(layer->GetLocalTransformTyped().TransformBounds(mLayer->Bounds()));
   }
   if (clip) {
     Maybe<wr::WrImageMask> mask = mLayer->BuildWrMaskLayer(aStackingContext);
     LayerRect clipRect = ViewAs<LayerPixel>(clip.ref(),
         PixelCastJustification::MovingDownToChildren);
-    mBuilder->PushClip(aStackingContext.ToRelativeLayoutRect(clipRect), mask.ptrOr(nullptr));
+    mBuilder->PushClip(mBuilder->DefineClip(
+        aStackingContext.ToRelativeLayoutRect(clipRect), nullptr, mask.ptrOr(nullptr)));
     mPushedLayerLocalClip = true;
   }
 }
 
 void
 ScrollingLayersHelper::PushLayerClip(const LayerClip& aClip,
                                      const StackingContextHelper& aSc)
 {
@@ -136,17 +137,18 @@ ScrollingLayersHelper::PushLayerClip(con
         PixelCastJustification::MovingDownToChildren));
   Maybe<wr::WrImageMask> mask;
   if (Maybe<size_t> maskLayerIndex = aClip.GetMaskLayerIndex()) {
     Layer* maskLayer = mLayer->GetLayer()->GetAncestorMaskLayerAt(maskLayerIndex.value());
     WebRenderLayer* maskWrLayer = WebRenderLayer::ToWebRenderLayer(maskLayer);
     // TODO: check this transform is correct in all cases
     mask = maskWrLayer->RenderMaskLayer(aSc, maskLayer->GetTransform());
   }
-  mBuilder->PushClip(aSc.ToRelativeLayoutRect(clipRect), mask.ptrOr(nullptr));
+  mBuilder->PushClip(mBuilder->DefineClip(
+      aSc.ToRelativeLayoutRect(clipRect), nullptr, mask.ptrOr(nullptr)));
 }
 
 ScrollingLayersHelper::~ScrollingLayersHelper()
 {
   Layer* layer = mLayer->GetLayer();
   if (!mLayer->WrManager()->AsyncPanZoomEnabled()) {
     if (mPushedLayerLocalClip) {
       mBuilder->PopClip();
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -646,25 +646,38 @@ DisplayListBuilder::PushStackingContext(
 
 void
 DisplayListBuilder::PopStackingContext()
 {
   WRDL_LOG("PopStackingContext\n");
   wr_dp_pop_stacking_context(mWrState);
 }
 
-void
-DisplayListBuilder::PushClip(const wr::LayoutRect& aClipRect,
-                             const wr::WrImageMask* aMask)
+wr::WrClipId
+DisplayListBuilder::DefineClip(const wr::LayoutRect& aClipRect,
+                               const nsTArray<wr::WrComplexClipRegion>* aComplex,
+                               const wr::WrImageMask* aMask)
 {
-  uint64_t clip_id = wr_dp_push_clip(mWrState, aClipRect, nullptr, 0, aMask);
-  WRDL_LOG("PushClip id=%" PRIu64 " r=%s m=%p b=%s\n", clip_id,
+  uint64_t clip_id = wr_dp_define_clip(mWrState, aClipRect,
+      aComplex ? aComplex->Elements() : nullptr,
+      aComplex ? aComplex->Length() : 0,
+      aMask);
+  WRDL_LOG("DefineClip id=%" PRIu64 " r=%s m=%p b=%s complex=%d\n", clip_id,
       Stringify(aClipRect).c_str(), aMask,
-      aMask ? Stringify(aMask->rect).c_str() : "none");
-  mClipIdStack.push_back(wr::WrClipId { clip_id });
+      aMask ? Stringify(aMask->rect).c_str() : "none",
+      aComplex ? aComplex->Length() : 0);
+  return wr::WrClipId { clip_id };
+}
+
+void
+DisplayListBuilder::PushClip(const wr::WrClipId& aClipId)
+{
+  wr_dp_push_clip(mWrState, aClipId.id);
+  WRDL_LOG("PushClip id=%" PRIu64 "\n", aClipId.id);
+  mClipIdStack.push_back(aClipId);
 }
 
 void
 DisplayListBuilder::PopClip()
 {
   WRDL_LOG("PopClip id=%" PRIu64 "\n", mClipIdStack.back().id);
   mClipIdStack.pop_back();
   wr_dp_pop_clip(mWrState);
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -169,18 +169,20 @@ public:
                            const uint64_t& aAnimationId,
                            const float* aOpacity,
                            const gfx::Matrix4x4* aTransform,
                            wr::TransformStyle aTransformStyle,
                            const wr::MixBlendMode& aMixBlendMode,
                            const nsTArray<wr::WrFilterOp>& aFilters);
   void PopStackingContext();
 
-  void PushClip(const wr::LayoutRect& aClipRect,
-                const wr::WrImageMask* aMask);
+  wr::WrClipId DefineClip(const wr::LayoutRect& aClipRect,
+                          const nsTArray<wr::WrComplexClipRegion>* aComplex = nullptr,
+                          const wr::WrImageMask* aMask = nullptr);
+  void PushClip(const wr::WrClipId& aClipId);
   void PopClip();
 
   void PushBuiltDisplayList(wr::BuiltDisplayList &dl);
 
   void PushScrollLayer(const layers::FrameMetrics::ViewID& aScrollId,
                        const wr::LayoutRect& aContentRect, // TODO: We should work with strongly typed rects
                        const wr::LayoutRect& aClipRect);
   void PopScrollLayer();
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -986,42 +986,48 @@ pub extern "C" fn wr_dp_push_stacking_co
 
 #[no_mangle]
 pub extern "C" fn wr_dp_pop_stacking_context(state: &mut WrState) {
     assert!(unsafe { !is_in_render_thread() });
     state.frame_builder.dl_builder.pop_stacking_context();
 }
 
 #[no_mangle]
-pub extern "C" fn wr_dp_push_clip(state: &mut WrState,
-                                  rect: LayoutRect,
-                                  complex: *const WrComplexClipRegion,
-                                  complex_count: usize,
-                                  mask: *const WrImageMask)
-                                  -> u64 {
+pub extern "C" fn wr_dp_define_clip(state: &mut WrState,
+                                    rect: LayoutRect,
+                                    complex: *const WrComplexClipRegion,
+                                    complex_count: usize,
+                                    mask: *const WrImageMask)
+                                    -> u64 {
     assert!(unsafe { is_in_main_thread() });
     let clip_rect: LayoutRect = rect.into();
     let complex_slice = make_slice(complex, complex_count);
     let complex_iter = complex_slice.iter().map(|x| x.into());
     let mask : Option<ImageMask> = unsafe { mask.as_ref() }.map(|x| x.into());
 
     let clip_id = state.frame_builder.dl_builder.define_clip(None, clip_rect, complex_iter, mask);
-    state.frame_builder.dl_builder.push_clip_id(clip_id);
     // return the u64 id value from inside the ClipId::Clip(..)
     match clip_id {
         ClipId::Clip(id, nesting_index, pipeline_id) => {
             assert!(pipeline_id == state.pipeline_id);
             assert!(nesting_index == 0);
             id
         },
         _ => panic!("Got unexpected clip id type"),
     }
 }
 
 #[no_mangle]
+pub extern "C" fn wr_dp_push_clip(state: &mut WrState,
+                                  clip_id: u64) {
+    assert!(unsafe { is_in_main_thread() });
+    state.frame_builder.dl_builder.push_clip_id(ClipId::Clip(clip_id, 0, state.pipeline_id));
+}
+
+#[no_mangle]
 pub extern "C" fn wr_dp_pop_clip(state: &mut WrState) {
     assert!(unsafe { !is_in_render_thread() });
     state.frame_builder.dl_builder.pop_clip_id();
 }
 
 #[no_mangle]
 pub extern "C" fn wr_dp_push_scroll_layer(state: &mut WrState,
                                           scroll_id: u64,
--- a/gfx/webrender_bindings/webrender_ffi_generated.h
+++ b/gfx/webrender_bindings/webrender_ffi_generated.h
@@ -1,13 +1,13 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* Generated with cbindgen:0.1.19 */
+/* Generated with cbindgen:0.1.20 */
 
 /* DO NOT MODIFY THIS MANUALLY! This file was generated using cbindgen.
  * To generate this file:
  *   1. Get the latest cbindgen using `cargo install --force cbindgen`
  *      a. Alternatively, you can clone `https://github.com/rlhunt/cbindgen` and use a tagged release
  *   2. Run `cbindgen toolkit/library/rust/ --crate webrender_bindings -o gfx/webrender_bindings/webrender_ffi_generated.h`
  */
 
@@ -757,16 +757,24 @@ WR_FUNC;
 
 WR_INLINE
 void wr_dp_begin(WrState *aState,
                  uint32_t aWidth,
                  uint32_t aHeight)
 WR_FUNC;
 
 WR_INLINE
+uint64_t wr_dp_define_clip(WrState *aState,
+                           LayoutRect aRect,
+                           const WrComplexClipRegion *aComplex,
+                           size_t aComplexCount,
+                           const WrImageMask *aMask)
+WR_FUNC;
+
+WR_INLINE
 void wr_dp_end(WrState *aState)
 WR_FUNC;
 
 WR_INLINE
 void wr_dp_pop_clip(WrState *aState)
 WR_FUNC;
 
 WR_INLINE
@@ -846,21 +854,18 @@ WR_FUNC;
 
 WR_INLINE
 void wr_dp_push_built_display_list(WrState *aState,
                                    BuiltDisplayListDescriptor aDlDescriptor,
                                    WrVecU8 *aDlData)
 WR_FUNC;
 
 WR_INLINE
-uint64_t wr_dp_push_clip(WrState *aState,
-                         LayoutRect aRect,
-                         const WrComplexClipRegion *aComplex,
-                         size_t aComplexCount,
-                         const WrImageMask *aMask)
+void wr_dp_push_clip(WrState *aState,
+                     uint64_t aClipId)
 WR_FUNC;
 
 WR_INLINE
 void wr_dp_push_clip_and_scroll_info(WrState *aState,
                                      uint64_t aScrollId,
                                      const uint64_t *aClipId)
 WR_FUNC;
 
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -8929,17 +8929,18 @@ nsDisplayMask::CreateWebRenderCommands(m
   bool snap;
   float appUnitsPerDevPixel = mFrame->PresContext()->AppUnitsPerDevPixel();
   nsRect displayBound = GetBounds(aDisplayListBuilder, &snap);
   LayerRect bounds = ViewAs<LayerPixel>(LayoutDeviceRect::FromAppUnits(displayBound, appUnitsPerDevPixel),
                                         PixelCastJustification::WebRenderHasUnitResolution);
 
   Maybe<wr::WrImageMask> mask = aManager->BuildWrMaskImage(this, aBuilder, aSc, aDisplayListBuilder, bounds);
   if (mask) {
-    aBuilder.PushClip(aSc.ToRelativeLayoutRect(bounds), mask.ptr());
+    aBuilder.PushClip(aBuilder.DefineClip(
+        aSc.ToRelativeLayoutRect(bounds), nullptr, mask.ptr()));
   }
 
   nsDisplaySVGEffects::CreateWebRenderCommands(aBuilder, aSc, aParentCommands, aManager, aDisplayListBuilder);
 
   if (mask) {
     aBuilder.PopClip();
   }