Bug 1345907 - Use clip region instead of clip rect r=kats
authorRyan Hunt <rhunt@eqrion.net>
Thu, 09 Mar 2017 11:57:06 -0500
changeset 347289 e659fa15902a786f9a57490238f7ce8532d59fa6
parent 347288 b5e63c01714849bdd9ac8e0dc0035fc60cfff48b
child 347290 d00975e8c2d10c69360074446d1f5472dfa7723e
push id31493
push userkwierso@gmail.com
push dateMon, 13 Mar 2017 20:10:14 +0000
treeherdermozilla-central@7781e4e0a332 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1345907
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 1345907 - Use clip region instead of clip rect r=kats
gfx/layers/wr/WebRenderBorderLayer.cpp
gfx/layers/wr/WebRenderCanvasLayer.cpp
gfx/layers/wr/WebRenderColorLayer.cpp
gfx/layers/wr/WebRenderContainerLayer.cpp
gfx/layers/wr/WebRenderImageLayer.cpp
gfx/layers/wr/WebRenderPaintedLayer.cpp
gfx/thebes/gfxUtils.cpp
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/WebRenderAPI.h
gfx/webrender_bindings/src/bindings.rs
gfx/webrender_bindings/webrender_ffi.h
layout/generic/nsBulletFrame.cpp
layout/painting/nsCSSRenderingBorders.cpp
layout/painting/nsDisplayList.cpp
--- a/gfx/layers/wr/WebRenderBorderLayer.cpp
+++ b/gfx/layers/wr/WebRenderBorderLayer.cpp
@@ -31,17 +31,17 @@ WebRenderBorderLayer::CreateWebRenderCom
 {
   aBuilder.PushStackingContext(wr::ToWrRect(aRelBounds),
                                wr::ToWrRect(aOverflow),
                                nullptr,
                                1.0f,
                                aLayer->GetLayer()->GetTransform(),
                                WrMixBlendMode::Normal);
 
-  aBuilder.PushBorder(wr::ToWrRect(aRect), wr::ToWrRect(aClipRect),
+  aBuilder.PushBorder(wr::ToWrRect(aRect), aBuilder.BuildClipRegion(wr::ToWrRect(aClipRect)),
                       wr::ToWrBorderSide(aWidths[0], aColors[0], aBorderStyles[0]),
                       wr::ToWrBorderSide(aWidths[1], aColors[1], aBorderStyles[1]),
                       wr::ToWrBorderSide(aWidths[2], aColors[2], aBorderStyles[2]),
                       wr::ToWrBorderSide(aWidths[3], aColors[3], aBorderStyles[3]),
                       wr::ToWrBorderRadius(aCorners[0], aCorners[1],
                                            aCorners[3], aCorners[2]));
 
   aBuilder.PopStackingContext();
@@ -61,17 +61,17 @@ WebRenderBorderLayer::RenderLayer(wr::Di
 
   aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
                                wr::ToWrRect(overflow),
                                nullptr,
                                1.0f,
                                //GetAnimations(),
                                GetTransform(),
                                WrMixBlendMode::Normal);
-  aBuilder.PushBorder(wr::ToWrRect(rect), wr::ToWrRect(clip),
+  aBuilder.PushBorder(wr::ToWrRect(rect), aBuilder.BuildClipRegion(wr::ToWrRect(clip)),
                       wr::ToWrBorderSide(mWidths[0], mColors[0], mBorderStyles[0]),
                       wr::ToWrBorderSide(mWidths[1], mColors[1], mBorderStyles[1]),
                       wr::ToWrBorderSide(mWidths[2], mColors[2], mBorderStyles[2]),
                       wr::ToWrBorderSide(mWidths[3], mColors[3], mBorderStyles[3]),
                       wr::ToWrBorderRadius(mCorners[0], mCorners[1], mCorners[3], mCorners[2]));
   aBuilder.PopStackingContext();
 }
 
--- a/gfx/layers/wr/WebRenderCanvasLayer.cpp
+++ b/gfx/layers/wr/WebRenderCanvasLayer.cpp
@@ -64,16 +64,17 @@ WebRenderCanvasLayer::RenderLayer(wr::Di
   gfx::Rect rect(0, 0, mBounds.width, mBounds.height);
   rect = RelativeToVisible(rect);
   gfx::Rect clip = GetWrClipRect(rect);
 
   gfx::Rect relBounds = GetWrRelBounds();
 
   gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
   Maybe<WrImageMask> mask = buildMaskLayer();
+  WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(clip));
   wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
   WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
 
   DumpLayerInfo("CanvasLayer", rect);
   if (gfxPrefs::LayersDump()) {
     printf_stderr("CanvasLayer %p texture-filter=%s\n",
                   this->GetLayer(),
                   Stringify(filter).c_str());
@@ -86,17 +87,17 @@ WebRenderCanvasLayer::RenderLayer(wr::Di
 
   aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
                                wr::ToWrRect(overflow),
                                mask.ptrOr(nullptr),
                                1.0f,
                                //GetAnimations(),
                                transform,
                                mixBlendMode);
-  aBuilder.PushImage(wr::ToWrRect(rect), wr::ToWrRect(clip), nullptr, filter, key);
+  aBuilder.PushImage(wr::ToWrRect(rect), clipRegion, filter, key);
   aBuilder.PopStackingContext();
 }
 
 void
 WebRenderCanvasLayer::AttachCompositable()
 {
   mCanvasClient->Connect();
 }
--- a/gfx/layers/wr/WebRenderColorLayer.cpp
+++ b/gfx/layers/wr/WebRenderColorLayer.cpp
@@ -25,24 +25,25 @@ WebRenderColorLayer::RenderLayer(wr::Dis
   Rect rect = GetWrBoundsRect();
   Rect clip = GetWrClipRect(rect);
 
   gfx::Rect relBounds = GetWrRelBounds();
   gfx::Rect overflow(0, 0, relBounds.width, relBounds.height);
   WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
 
   Maybe<WrImageMask> mask = buildMaskLayer();
+  WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(clip));
 
   DumpLayerInfo("ColorLayer", rect);
 
   aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
                               wr::ToWrRect(overflow),
                               mask.ptrOr(nullptr),
                               1.0f,
                               //GetAnimations(),
                               transform,
                               mixBlendMode);
-  aBuilder.PushRect(wr::ToWrRect(rect), wr::ToWrRect(clip), wr::ToWrColor(mColor));
+  aBuilder.PushRect(wr::ToWrRect(rect), clipRegion, wr::ToWrColor(mColor));
   aBuilder.PopStackingContext();
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderContainerLayer.cpp
+++ b/gfx/layers/wr/WebRenderContainerLayer.cpp
@@ -53,21 +53,23 @@ WebRenderContainerLayer::RenderLayer(wr:
 void
 WebRenderRefLayer::RenderLayer(wr::DisplayListBuilder& aBuilder)
 {
   WrScrollFrameStackingContextGenerator scrollFrames(this);
 
   gfx::Rect relBounds = TransformedVisibleBoundsRelativeToParent();
   gfx::Matrix4x4 transform;// = GetTransform();
 
+  WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(relBounds));
+
   if (gfxPrefs::LayersDump()) {
     printf_stderr("RefLayer %p (%" PRIu64 ") using bounds/overflow=%s, transform=%s\n",
                   this->GetLayer(),
                   mId,
                   Stringify(relBounds).c_str(),
                   Stringify(transform).c_str());
   }
 
-  aBuilder.PushIFrame(wr::ToWrRect(relBounds), wr::ToWrRect(relBounds), wr::AsPipelineId(mId));
+  aBuilder.PushIFrame(wr::ToWrRect(relBounds), clipRegion, wr::AsPipelineId(mId));
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderImageLayer.cpp
+++ b/gfx/layers/wr/WebRenderImageLayer.cpp
@@ -131,16 +131,17 @@ WebRenderImageLayer::RenderLayer(wr::Dis
 
   Matrix4x4 transform = GetTransform();
   Rect rect(0, 0, size.width, size.height);
   Rect clip = GetWrClipRect(rect);
   Rect relBounds = GetWrRelBounds();
   Rect overflow(0, 0, relBounds.width, relBounds.height);
 
   Maybe<WrImageMask> mask = buildMaskLayer();
+  WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(clip));
   wr::ImageRendering filter = wr::ToImageRendering(mSamplingFilter);
   WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
 
   DumpLayerInfo("Image Layer", rect);
   if (gfxPrefs::LayersDump()) {
     printf_stderr("ImageLayer %p texture-filter=%s \n",
                   GetLayer(),
                   Stringify(filter).c_str());
@@ -153,16 +154,16 @@ WebRenderImageLayer::RenderLayer(wr::Dis
 
   aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
                             wr::ToWrRect(overflow),
                             mask.ptrOr(nullptr),
                             1.0f,
                             //GetAnimations(),
                             transform,
                             mixBlendMode);
-  aBuilder.PushImage(wr::ToWrRect(rect), wr::ToWrRect(clip), nullptr, filter, key);
+  aBuilder.PushImage(wr::ToWrRect(rect), clipRegion, filter, key);
   aBuilder.PopStackingContext();
 
   //mContainer->SetImageFactory(originalIF);
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/wr/WebRenderPaintedLayer.cpp
+++ b/gfx/layers/wr/WebRenderPaintedLayer.cpp
@@ -191,29 +191,30 @@ WebRenderPaintedLayer::RenderLayer(wr::D
   // Since we are creating a stacking context below using the visible region of
   // this layer, we need to make sure the image display item has coordinates
   // relative to the visible region.
   Rect rect(0, 0, size.width, size.height);
   Rect clip = GetWrClipRect(rect);
   Maybe<WrImageMask> mask = buildMaskLayer();
   Rect relBounds = GetWrRelBounds();
   Rect overflow(0, 0, relBounds.width, relBounds.height);
+  WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(clip));
   WrMixBlendMode mixBlendMode = wr::ToWrMixBlendMode(GetMixBlendMode());
 
   DumpLayerInfo("PaintedLayer", rect);
 
   WrImageKey key;
   key.mNamespace = WrBridge()->GetNamespace();
   key.mHandle = WrBridge()->GetNextResourceId();
   WrBridge()->AddWebRenderParentCommand(OpAddExternalImage(mExternalImageId, key));
   aBuilder.PushStackingContext(wr::ToWrRect(relBounds),
                               wr::ToWrRect(overflow),
                               mask.ptrOr(nullptr),
                               1.0f,
                               //GetAnimations(),
                               transform,
                               mixBlendMode);
-  aBuilder.PushImage(wr::ToWrRect(rect), wr::ToWrRect(clip), nullptr, wr::ImageRendering::Auto, key);
+  aBuilder.PushImage(wr::ToWrRect(rect), clipRegion, wr::ImageRendering::Auto, key);
   aBuilder.PopStackingContext();
 }
 
 } // namespace layers
 } // namespace mozilla
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -1477,30 +1477,32 @@ WebRenderGlyphHelper::BuildWebRenderComm
   wr::ByteBuffer fontBuffer(mFontDataLength, mFontData);
 
   WrFontKey key;
   key.mNamespace = aBridge->GetNamespace();
   key.mHandle = aBridge->GetNextResourceId();
 
   aBridge->SendAddRawFont(key, fontBuffer, mIndex);
 
+  WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(aClip));
+
   for (size_t i = 0; i < aGlyphs.Length(); i++) {
     GlyphArray glyph_array = aGlyphs[i];
     nsTArray<gfx::Glyph>& glyphs = glyph_array.glyphs();
 
     nsTArray<WrGlyphInstance> wr_glyph_instances;
     wr_glyph_instances.SetLength(glyphs.Length());
 
     for (size_t j = 0; j < glyphs.Length(); j++) {
       wr_glyph_instances[j].index = glyphs[j].mIndex;
       wr_glyph_instances[j].x = glyphs[j].mPosition.x - aOffset.x;
       wr_glyph_instances[j].y = glyphs[j].mPosition.y - aOffset.y;
     }
     aBuilder.PushText(wr::ToWrRect(aBounds),
-                      wr::ToWrRect(aClip),
+                      clipRegion,
                       glyph_array.color().value(),
                       key,
                       Range<const WrGlyphInstance>(wr_glyph_instances.Elements(), wr_glyph_instances.Length()),
                       mGlyphSize);
 
   }
 }
 
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -469,40 +469,40 @@ DisplayListBuilder::PushScrollLayer(cons
 void
 DisplayListBuilder::PopScrollLayer()
 {
   wr_dp_pop_scroll_layer(mWrState);
 }
 
 void
 DisplayListBuilder::PushRect(const WrRect& aBounds,
-                             const WrRect& aClip,
+                             const WrClipRegion& aClip,
                              const WrColor& aColor)
 {
   wr_dp_push_rect(mWrState, aBounds, aClip, aColor);
 }
 
 void
 DisplayListBuilder::PushLinearGradient(const WrRect& aBounds,
-                                       const WrRect& aClip,
+                                       const WrClipRegion& aClip,
                                        const WrPoint& aStartPoint,
                                        const WrPoint& aEndPoint,
                                        const nsTArray<WrGradientStop>& aStops,
                                        wr::GradientExtendMode aExtendMode)
 {
   wr_dp_push_linear_gradient(mWrState,
                              aBounds, aClip,
                              aStartPoint, aEndPoint,
                              aStops.Elements(), aStops.Length(),
                              aExtendMode);
 }
 
 void
 DisplayListBuilder::PushRadialGradient(const WrRect& aBounds,
-                                       const WrRect& aClip,
+                                       const WrClipRegion& aClip,
                                        const WrPoint& aStartCenter,
                                        const WrPoint& aEndCenter,
                                        float aStartRadius,
                                        float aEndRadius,
                                        const nsTArray<WrGradientStop>& aStops,
                                        wr::GradientExtendMode aExtendMode)
 {
   wr_dp_push_radial_gradient(mWrState,
@@ -510,64 +510,63 @@ DisplayListBuilder::PushRadialGradient(c
                              aStartCenter, aEndCenter,
                              aStartRadius, aEndRadius,
                              aStops.Elements(), aStops.Length(),
                              aExtendMode);
 }
 
 void
 DisplayListBuilder::PushImage(const WrRect& aBounds,
-                              const WrRect& aClip,
-                              const WrImageMask* aMask,
+                              const WrClipRegion& aClip,
                               wr::ImageRendering aFilter,
                               wr::ImageKey aImage)
 {
-  wr_dp_push_image(mWrState, aBounds, aClip, aMask, aFilter, aImage);
+  wr_dp_push_image(mWrState, aBounds, aClip, aFilter, aImage);
 }
 
 void
 DisplayListBuilder::PushIFrame(const WrRect& aBounds,
-                               const WrRect& aClip,
+                               const WrClipRegion& aClip,
                                PipelineId aPipeline)
 {
   wr_dp_push_iframe(mWrState, aBounds, aClip, aPipeline);
 }
 
 void
 DisplayListBuilder::PushBorder(const WrRect& aBounds,
-                               const WrRect& aClip,
+                               const WrClipRegion& aClip,
                                const WrBorderSide& aTop,
                                const WrBorderSide& aRight,
                                const WrBorderSide& aBottom,
                                const WrBorderSide& aLeft,
                                const WrBorderRadius& aRadius)
 {
   wr_dp_push_border(mWrState, aBounds, aClip,
                     aTop, aRight, aBottom, aLeft,
                     aRadius);
 }
 
 void
 DisplayListBuilder::PushText(const WrRect& aBounds,
-                             const WrRect& aClip,
+                             const WrClipRegion& aClip,
                              const gfx::Color& aColor,
                              wr::FontKey aFontKey,
                              Range<const WrGlyphInstance> aGlyphBuffer,
                              float aGlyphSize)
 {
   wr_dp_push_text(mWrState, aBounds, aClip,
                   ToWrColor(aColor),
                   aFontKey,
                   &aGlyphBuffer[0], aGlyphBuffer.length(),
                   aGlyphSize);
 }
 
 void
 DisplayListBuilder::PushBoxShadow(const WrRect& aRect,
-                                  const WrRect& aClip,
+                                  const WrClipRegion& aClip,
                                   const WrRect& aBoxBounds,
                                   const WrPoint& aOffset,
                                   const WrColor& aColor,
                                   const float& aBlurRadius,
                                   const float& aSpreadRadius,
                                   const float& aBorderRadius,
                                   const WrBoxShadowClipMode& aClipMode)
 {
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -145,62 +145,61 @@ public:
   void PushScrollLayer(const WrRect& aBounds, // TODO: We should work with strongly typed rects
                        const WrRect& aOverflow,
                        const WrImageMask* aMask); // TODO: needs a wrapper.
 
   void PopScrollLayer();
 
 
   void PushRect(const WrRect& aBounds,
-                const WrRect& aClip,
+                const WrClipRegion& aClip,
                 const WrColor& aColor);
 
   void PushLinearGradient(const WrRect& aBounds,
-                          const WrRect& aClip,
+                          const WrClipRegion& aClip,
                           const WrPoint& aStartPoint,
                           const WrPoint& aEndPoint,
                           const nsTArray<WrGradientStop>& aStops,
                           wr::GradientExtendMode aExtendMode);
 
   void PushRadialGradient(const WrRect& aBounds,
-                          const WrRect& aClip,
+                          const WrClipRegion& aClip,
                           const WrPoint& aStartCenter,
                           const WrPoint& aEndCenter,
                           float aStartRadius,
                           float aEndRadius,
                           const nsTArray<WrGradientStop>& aStops,
                           wr::GradientExtendMode aExtendMode);
 
   void PushImage(const WrRect& aBounds,
-                 const WrRect& aClip,
-                 const WrImageMask* aMask,
+                 const WrClipRegion& aClip,
                  wr::ImageRendering aFilter,
                  wr::ImageKey aImage);
 
   void PushIFrame(const WrRect& aBounds,
-                  const WrRect& aClip,
+                  const WrClipRegion& aClip,
                   wr::PipelineId aPipeline);
 
   void PushBorder(const WrRect& aBounds,
-                  const WrRect& aClip,
+                  const WrClipRegion& aClip,
                   const WrBorderSide& aTop,
                   const WrBorderSide& aRight,
                   const WrBorderSide& aBbottom,
                   const WrBorderSide& aLeft,
                   const WrBorderRadius& aRadius);
 
   void PushText(const WrRect& aBounds,
-                const WrRect& aClip,
+                const WrClipRegion& aClip,
                 const gfx::Color& aColor,
                 wr::FontKey aFontKey,
                 Range<const WrGlyphInstance> aGlyphBuffer,
                 float aGlyphSize);
 
   void PushBoxShadow(const WrRect& aRect,
-                     const WrRect& aClip,
+                     const WrClipRegion& aClip,
                      const WrRect& aBoxBounds,
                      const WrPoint& aOffset,
                      const WrColor& aColor,
                      const float& aBlurRadius,
                      const float& aSpreadRadius,
                      const float& aBorderRadius,
                      const WrBoxShadowClipMode& aClipMode);
 
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -790,122 +790,116 @@ pub extern fn wr_api_delete_image(api: &
 pub extern fn wr_api_send_external_event(api: &mut RenderApi, evt: usize) {
     assert!(unsafe { is_in_compositor_thread() });
 
     api.send_external_event(ExternalEvent::from_raw(evt));
 }
 
 
 #[no_mangle]
-pub extern fn wr_dp_push_rect(state: &mut WrState, rect: WrRect, clip: WrRect, color: WrColor) {
+pub extern fn wr_dp_push_rect(state: &mut WrState, rect: WrRect, clip: WrClipRegion, color: WrColor) {
     assert!( unsafe { is_in_main_thread() });
-    let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(), Vec::new(), None);
 
     state.frame_builder.dl_builder.push_rect(
                                     rect.to_rect(),
-                                    clip_region,
+                                    clip.to_clip_region(),
                                     color.to_color());
 }
 
 #[no_mangle]
-pub extern fn wr_dp_push_box_shadow(state: &mut WrState, rect: WrRect, clip: WrRect,
+pub extern fn wr_dp_push_box_shadow(state: &mut WrState, rect: WrRect, clip: WrClipRegion,
                                     box_bounds: WrRect, offset: WrPoint, color: WrColor,
                                     blur_radius: f32, spread_radius: f32, border_radius: f32,
                                     clip_mode: WrBoxShadowClipMode) {
     assert!( unsafe { is_in_main_thread() });
-    let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(), Vec::new(), None);
+
     state.frame_builder.dl_builder.push_box_shadow(rect.to_rect(),
-                                                   clip_region,
+                                                   clip.to_clip_region(),
                                                    box_bounds.to_rect(),
                                                    offset.to_point(),
                                                    color.to_color(),
                                                    blur_radius,
                                                    spread_radius,
                                                    border_radius,
                                                    clip_mode.to_box_shadow_clip_mode());
 }
 
 #[no_mangle]
-pub extern fn wr_dp_push_border(state: &mut WrState, rect: WrRect, clip: WrRect,
+pub extern fn wr_dp_push_border(state: &mut WrState, rect: WrRect, clip: WrClipRegion,
                                 top: WrBorderSide, right: WrBorderSide, bottom: WrBorderSide, left: WrBorderSide,
                                 radius: WrBorderRadius) {
     assert!( unsafe { is_in_main_thread() });
-    let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(), Vec::new(), None);
+
     let border_widths = BorderWidths {
         left: left.width,
         top: top.width,
         right: right.width,
         bottom: bottom.width
     };
     let border_details = BorderDetails::Normal(NormalBorder {
         left: left.to_border_side(),
         right: right.to_border_side(),
         top: top.to_border_side(),
         bottom: bottom.to_border_side(),
         radius: radius.to_border_radius(),
     });
     state.frame_builder.dl_builder.push_border(
                                     rect.to_rect(),
-                                    clip_region,
+                                    clip.to_clip_region(),
                                     border_widths,
                                     border_details);
 }
 
 #[no_mangle]
-pub extern fn wr_dp_push_linear_gradient(state: &mut WrState, rect: WrRect, clip: WrRect,
+pub extern fn wr_dp_push_linear_gradient(state: &mut WrState, rect: WrRect, clip: WrClipRegion,
                                          start_point: WrPoint, end_point: WrPoint,
                                          stops: * const WrGradientStop, stops_count: usize,
                                          extend_mode: WrGradientExtendMode) {
     assert!( unsafe { is_in_main_thread() });
 
     let stops = WrGradientStop::to_gradient_stops(unsafe { slice::from_raw_parts(stops, stops_count) });
-    let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(), Vec::new(), None);
 
     state.frame_builder.dl_builder.push_gradient(
                                     rect.to_rect(),
-                                    clip_region,
+                                    clip.to_clip_region(),
                                     start_point.to_point(),
                                     end_point.to_point(),
                                     stops,
                                     extend_mode.to_gradient_extend_mode()
                                     );
 }
 
 #[no_mangle]
-pub extern fn wr_dp_push_radial_gradient(state: &mut WrState, rect: WrRect, clip: WrRect,
+pub extern fn wr_dp_push_radial_gradient(state: &mut WrState, rect: WrRect, clip: WrClipRegion,
                                          start_center: WrPoint, end_center: WrPoint,
                                          start_radius: f32, end_radius: f32,
                                          stops: * const WrGradientStop, stops_count: usize,
                                          extend_mode: WrGradientExtendMode) {
     assert!( unsafe { is_in_main_thread() });
 
     let stops = WrGradientStop::to_gradient_stops(unsafe { slice::from_raw_parts(stops, stops_count) });
-    let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(), Vec::new(), None);
 
     state.frame_builder.dl_builder.push_radial_gradient(
                                     rect.to_rect(),
-                                    clip_region,
+                                    clip.to_clip_region(),
                                     start_center.to_point(),
                                     start_radius,
                                     end_center.to_point(),
                                     end_radius,
                                     stops,
                                     extend_mode.to_gradient_extend_mode()
                                     );
 }
 
 #[no_mangle]
-pub extern fn wr_dp_push_iframe(state: &mut WrState, rect: WrRect, clip: WrRect, pipeline_id: PipelineId) {
+pub extern fn wr_dp_push_iframe(state: &mut WrState, rect: WrRect, clip: WrClipRegion, pipeline_id: PipelineId) {
     assert!( unsafe { is_in_main_thread() });
 
-    let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(),
-                                                                     Vec::new(),
-                                                                     None);
     state.frame_builder.dl_builder.push_iframe(rect.to_rect(),
-                                               clip_region,
+                                               clip.to_clip_region(),
                                                pipeline_id);
 }
 
 #[repr(C)]
 struct WrItemRange
 {
     start: usize,
     length: usize,
@@ -1159,31 +1153,24 @@ impl From<ClipRegion> for WrClipRegion
                 image_mask: blank,
                 has_image_mask: false,
             }
         }
     }
 }
 
 #[no_mangle]
-pub extern fn wr_dp_push_image(state:&mut WrState, bounds: WrRect, clip : WrRect, mask: *const WrImageMask, filter: ImageRendering, key: ImageKey) {
+pub extern fn wr_dp_push_image(state:&mut WrState, bounds: WrRect, clip: WrClipRegion, image_rendering: ImageRendering, key: ImageKey) {
     assert!( unsafe { is_in_main_thread() });
 
     let bounds = bounds.to_rect();
-    let clip = clip.to_rect();
 
-    //println!("push_image bounds {:?} clip {:?}", bounds, clip);
-    // convert from the C type to the Rust type, mapping NULL to None
-    let mask = unsafe { mask.as_ref().map(|m| m.to_image_mask()) };
-    let image_rendering = filter;
-
-    let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip, Vec::new(), mask);
     state.frame_builder.dl_builder.push_image(
         bounds,
-        clip_region,
+        clip.to_clip_region(),
         bounds.size,
         bounds.size,
         image_rendering,
         key
     );
 }
 #[no_mangle]
 pub extern fn wr_api_generate_font_key(api: &mut RenderApi) -> FontKey
@@ -1207,38 +1194,36 @@ pub extern fn wr_api_add_raw_font(api: &
 
     api.add_raw_font(key, font_vector);
 }
 
 
 #[no_mangle]
 pub extern fn wr_dp_push_text(state: &mut WrState,
                               bounds: WrRect,
-                              clip: WrRect,
+                              clip: WrClipRegion,
                               color: WrColor,
                               font_key: FontKey,
                               glyphs: *mut GlyphInstance,
                               glyph_count: u32,
                               glyph_size: f32)
 {
     assert!( unsafe { is_in_main_thread() });
 
     let glyph_slice = unsafe {
         slice::from_raw_parts(glyphs, glyph_count as usize)
     };
     let mut glyph_vector = Vec::new();
     glyph_vector.extend_from_slice(&glyph_slice);
 
     let colorf = ColorF::new(color.r, color.g, color.b, color.a);
 
-    let clip_region = state.frame_builder.dl_builder.new_clip_region(&clip.to_rect(), Vec::new(), None);
-
     let glyph_options = None; // TODO
     state.frame_builder.dl_builder.push_text(bounds.to_rect(),
-                                             clip_region,
+                                             clip.to_clip_region(),
                                              glyph_vector,
                                              font_key,
                                              colorf,
                                              Au::from_f32_px(glyph_size),
                                              Au::from_px(0),
                                              glyph_options);
 }
 
--- a/gfx/webrender_bindings/webrender_ffi.h
+++ b/gfx/webrender_bindings/webrender_ffi.h
@@ -561,65 +561,65 @@ WR_FUNC;
 WR_INLINE WrClipRegion
 wr_dp_new_clip_region(WrState* wrState,
                       WrRect main,
                       const WrComplexClipRegion* complex, size_t complexCount,
                       const WrImageMask* image_mask)
 WR_FUNC;
 
 WR_INLINE void
-wr_dp_push_rect(WrState* wrState, WrRect bounds, WrRect clip,
+wr_dp_push_rect(WrState* wrState, WrRect bounds, WrClipRegion clip,
                 WrColor color)
 WR_FUNC;
 
 WR_INLINE void
-wr_dp_push_text(WrState* wrState, WrRect bounds, WrRect clip, WrColor color,
+wr_dp_push_text(WrState* wrState, WrRect bounds, WrClipRegion clip, WrColor color,
                 WrFontKey font_Key, const WrGlyphInstance* glyphs,
                 uint32_t glyph_count, float glyph_size)
 WR_FUNC;
 
 WR_INLINE void
-wr_dp_push_border(WrState* wrState, WrRect bounds, WrRect clip,
+wr_dp_push_border(WrState* wrState, WrRect bounds, WrClipRegion clip,
                   WrBorderSide top, WrBorderSide right, WrBorderSide bottom, WrBorderSide left,
                   WrBorderRadius radius)
 WR_FUNC;
 
 WR_INLINE void
-wr_dp_push_linear_gradient(WrState* wrState, WrRect bounds, WrRect clip,
+wr_dp_push_linear_gradient(WrState* wrState, WrRect bounds, WrClipRegion clip,
                            WrPoint startPoint, WrPoint endPoint,
                            const WrGradientStop* stops, size_t stopsCount,
                            WrGradientExtendMode extendMode)
 WR_FUNC;
 
 WR_INLINE void
-wr_dp_push_radial_gradient(WrState* wrState, WrRect bounds, WrRect clip,
+wr_dp_push_radial_gradient(WrState* wrState, WrRect bounds, WrClipRegion clip,
                            WrPoint startCenter, WrPoint endCenter,
                            float startRadius, float endRadius,
                            const WrGradientStop* stops, size_t stopsCount,
                            WrGradientExtendMode extendMode)
 WR_FUNC;
 
 WR_INLINE void
-wr_dp_push_image(WrState* wrState, WrRect bounds, WrRect clip,
-                 const WrImageMask* mask, WrImageRendering filter, WrImageKey key)
+wr_dp_push_image(WrState* wrState, WrRect bounds, WrClipRegion clip,
+                 WrImageRendering filter, WrImageKey key)
 WR_FUNC;
 
 WR_INLINE void
-wr_dp_push_iframe(WrState* wrState, WrRect bounds, WrRect clip, WrPipelineId layers_id)
+wr_dp_push_iframe(WrState* wrState, WrRect bounds, WrClipRegion clip, WrPipelineId layers_id)
 WR_FUNC;
 
 // It is the responsibility of the caller to manage the dst_buffer memory
 // and also free it at the proper time.
 WR_INLINE const uint8_t*
 wr_renderer_readback(uint32_t width, uint32_t height,
                      uint8_t* dst_buffer, size_t buffer_length)
 WR_FUNC;
 
 WR_INLINE void
-wr_dp_push_box_shadow(WrState* wrState, WrRect rect, WrRect clip,
+wr_dp_push_box_shadow(WrState* wrState, WrRect rect, WrClipRegion clip,
                       WrRect box_bounds, WrPoint offset, WrColor color,
                       float blur_radius, float spread_radius, float border_radius,
                       WrBoxShadowClipMode clip_mode)
 WR_FUNC;
 
 WR_INLINE WrIdNamespace
 wr_api_get_namespace(WrAPI* api)
 WR_FUNC;
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -460,25 +460,26 @@ BulletRenderer::CreateWebRenderCommandsF
   uint64_t externalImageId = layer->SendImageContainer(container);
 
   const int32_t appUnitsPerDevPixel = aItem->Frame()->PresContext()->AppUnitsPerDevPixel();
   Rect destRect =
     NSRectToRect(mDest, appUnitsPerDevPixel);
   Rect destRectTransformed = aLayer->RelativeToParent(destRect);
   IntRect dest = RoundedToInt(destRectTransformed);
 
+  WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(dest));
+
   WrImageKey key;
   key.mNamespace = layer->WrBridge()->GetNamespace();
   key.mHandle = layer->WrBridge()->GetNextResourceId();
   aParentCommands.AppendElement(layers::OpAddExternalImage(
                                 externalImageId,
                                 key));
   aBuilder.PushImage(wr::ToWrRect(dest),
-                     wr::ToWrRect(dest),
-                     nullptr,
+                     clipRegion,
                      WrImageRendering::Auto,
                      key);
 }
 
 void
 BulletRenderer::CreateWebRenderCommandsForPath(nsDisplayItem* aItem,
                                                wr::DisplayListBuilder& aBuilder,
                                                layers::WebRenderDisplayItemLayer* aLayer)
--- a/layout/painting/nsCSSRenderingBorders.cpp
+++ b/layout/painting/nsCSSRenderingBorders.cpp
@@ -3536,17 +3536,18 @@ nsCSSBorderRenderer::CreateWebRenderComm
                                              layers::WebRenderDisplayItemLayer* aLayer)
 {
   Rect outlineTransformedRect = aLayer->RelativeToParent(mOuterRect);
   WrBorderSide side[4];
   NS_FOR_CSS_SIDES(i) {
     side[i] = wr::ToWrBorderSide(mBorderWidths[i], ToDeviceColor(mBorderColors[i]), mBorderStyles[i]);
   }
 
+  WrClipRegion clipRegion = aBuilder.BuildClipRegion(wr::ToWrRect(outlineTransformedRect));
   WrBorderRadius borderRadius = wr::ToWrBorderRadius(LayerSize(mBorderRadii[0].width, mBorderRadii[0].height),
                                                      LayerSize(mBorderRadii[1].width, mBorderRadii[1].height),
                                                      LayerSize(mBorderRadii[3].width, mBorderRadii[3].height),
                                                      LayerSize(mBorderRadii[2].width, mBorderRadii[2].height));
   aBuilder.PushBorder(wr::ToWrRect(outlineTransformedRect),
-                      wr::ToWrRect(outlineTransformedRect),
+                      clipRegion,
                       side[0], side[1], side[2], side[3],
                       borderRadius);
 }
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -4442,22 +4442,22 @@ nsDisplayCaret::CreateWebRenderCommands(
   Rect caretTransformedRect = aLayer->RelativeToParent(devCaretRect);
   Rect hookTransformedRect = aLayer->RelativeToParent(devHookRect);
 
   IntRect caret = RoundedToInt(caretTransformedRect);
   IntRect hook = RoundedToInt(hookTransformedRect);
 
   // Note, WR will pixel snap anything that is layout aligned.
   aBuilder.PushRect(wr::ToWrRect(caret),
-                    wr::ToWrRect(caret),
+                    aBuilder.BuildClipRegion(wr::ToWrRect(caret)),
                     wr::ToWrColor(color));
 
   if (!devHookRect.IsEmpty()) {
     aBuilder.PushRect(wr::ToWrRect(hook),
-                      wr::ToWrRect(hook),
+                      aBuilder.BuildClipRegion(wr::ToWrRect(hook)),
                       wr::ToWrColor(color));
   }
 }
 
 LayerState
 nsDisplayCaret::GetLayerState(nsDisplayListBuilder* aBuilder,
                               LayerManager* aManager,
                               const ContainerLayerParameters& aParameters)
@@ -4885,17 +4885,17 @@ nsDisplayBoxShadowOuter::CreateWebRender
 
       float blurRadius = float(shadow->mRadius) / float(appUnitsPerDevPixel);
       // TODO: support non-uniform border radius.
       float borderRadius = hasBorderRadius ? borderRadii.TopLeft().width
                                            : 0.0;
       float spreadRadius = float(shadow->mSpread) / float(appUnitsPerDevPixel);
 
       aBuilder.PushBoxShadow(wr::ToWrRect(deviceBoxRect),
-                             wr::ToWrRect(deviceClipRect),
+                             aBuilder.BuildClipRegion(wr::ToWrRect(deviceClipRect)),
                              wr::ToWrRect(deviceBoxRect),
                              wr::ToWrPoint(shadowOffset),
                              wr::ToWrColor(shadowColor),
                              blurRadius,
                              spreadRadius,
                              borderRadius,
                              WrBoxShadowClipMode::Outset);
     }
@@ -5017,17 +5017,17 @@ nsDisplayBoxShadowInner::CreateInsetBoxS
 
       float blurRadius = float(shadowItem->mRadius) / float(appUnitsPerDevPixel);
       // TODO: WR doesn't support non-uniform border radii
       float borderRadius = innerRadii.TopLeft().width;
       // NOTE: Any spread radius > 0 will render nothing. WR Bug.
       float spreadRadius = float(shadowItem->mSpread) / float(appUnitsPerDevPixel);
 
       aBuilder.PushBoxShadow(wr::ToWrRect(deviceBoxRect),
-                             wr::ToWrRect(deviceClipRect),
+                             aBuilder.BuildClipRegion(wr::ToWrRect(deviceClipRect)),
                              wr::ToWrRect(deviceBoxRect),
                              wr::ToWrPoint(shadowOffset),
                              wr::ToWrColor(shadowColor),
                              blurRadius,
                              spreadRadius,
                              borderRadius,
                              WrBoxShadowClipMode::Inset
                              );