Bug 1543482 - Extract a helper to identify clip paths WR can handle without masks. r=mattwoodrow
authorKartikaya Gupta <kgupta@mozilla.com>
Mon, 15 Apr 2019 11:24:53 +0000
changeset 528336 7d9507696389b81ea47798b0528769422bd3ec96
parent 528335 f17ab3584d22dad10e2e7b62e0692ac8703d49ac
child 528337 7d6cd4e207055a667e1136ba200603f2420c671c
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs1543482
milestone68.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 1543482 - Extract a helper to identify clip paths WR can handle without masks. r=mattwoodrow Differential Revision: https://phabricator.services.mozilla.com/D27454
layout/painting/nsDisplayList.cpp
layout/svg/nsSVGIntegrationUtils.cpp
layout/svg/nsSVGIntegrationUtils.h
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -9527,29 +9527,22 @@ void nsDisplayMasksAndClipPaths::PaintWi
 }
 
 static Maybe<wr::WrClipId> CreateSimpleClipRegion(
     const nsDisplayMasksAndClipPaths& aDisplayItem,
     wr::DisplayListBuilder& aBuilder) {
   nsIFrame* frame = aDisplayItem.Frame();
   auto* style = frame->StyleSVGReset();
   MOZ_ASSERT(style->HasClipPath() || style->HasMask());
-  if (style->HasMask()) {
+  if (!nsSVGIntegrationUtils::UsingSimpleClipPathForFrame(frame)) {
     return Nothing();
   }
 
   const auto& clipPath = style->mClipPath;
-  if (clipPath.GetType() != StyleShapeSourceType::Shape) {
-    return Nothing();
-  }
-
   const auto& shape = clipPath.BasicShape();
-  if (shape.GetShapeType() == StyleBasicShapeType::Polygon) {
-    return Nothing();
-  }
 
   auto appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel();
   const nsRect refBox =
       nsLayoutUtils::ComputeGeometryBox(frame, clipPath.GetReferenceBox());
 
   AutoTArray<wr::ComplexClipRegion, 1> clipRegions;
 
   wr::LayoutRect rect;
@@ -9597,18 +9590,18 @@ static Maybe<wr::WrClipId> CreateSimpleC
       rect = wr::ToRoundedLayoutRect(
           LayoutDeviceRect::FromAppUnits(ellipseRect, appUnitsPerDevPixel));
       break;
     }
     default:
       // Please don't add more exceptions, try to find a way to define the clip
       // without using a mask image.
       //
-      // And if you _really really_ need to add an exception, add it to where
-      // the polygon check is.
+      // And if you _really really_ need to add an exception, add it to
+      // nsSVGIntegrationUtils::UsingSimpleClipPathForFrame
       MOZ_ASSERT_UNREACHABLE("Unhandled shape id?");
       return Nothing();
   }
   wr::WrClipId clipId =
       aBuilder.DefineClip(Nothing(), rect, &clipRegions, nullptr);
   return Some(clipId);
 }
 
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -164,16 +164,32 @@ bool nsSVGIntegrationUtils::UsingEffects
 }
 
 bool nsSVGIntegrationUtils::UsingMaskOrClipPathForFrame(
     const nsIFrame* aFrame) {
   const nsStyleSVGReset* style = aFrame->StyleSVGReset();
   return style->HasClipPath() || style->HasMask();
 }
 
+bool nsSVGIntegrationUtils::UsingSimpleClipPathForFrame(
+    const nsIFrame* aFrame) {
+  const nsStyleSVGReset* style = aFrame->StyleSVGReset();
+  if (!style->HasClipPath() || style->HasMask()) {
+    return false;
+  }
+
+  const auto& clipPath = style->mClipPath;
+  if (clipPath.GetType() != StyleShapeSourceType::Shape) {
+    return false;
+  }
+
+  const auto& shape = clipPath.BasicShape();
+  return (shape.GetShapeType() != StyleBasicShapeType::Polygon);
+}
+
 nsPoint nsSVGIntegrationUtils::GetOffsetToBoundingBox(nsIFrame* aFrame) {
   if ((aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT)) {
     // Do NOT call GetAllInFlowRectsUnion for SVG - it will get the
     // covered region relative to the nsSVGOuterSVGFrame, which is absolutely
     // not what we want. SVG frames are always in user space, so they have
     // no offset adjustment to make.
     return nsPoint();
   }
--- a/layout/svg/nsSVGIntegrationUtils.h
+++ b/layout/svg/nsSVGIntegrationUtils.h
@@ -64,16 +64,22 @@ class nsSVGIntegrationUtils final {
   static bool UsingEffectsForFrame(const nsIFrame* aFrame);
 
   /**
    * Returns true if mask or clippath are currently applied to this frame.
    */
   static bool UsingMaskOrClipPathForFrame(const nsIFrame* aFrame);
 
   /**
+   * Returns true if the element has a clippath that is simple enough to
+   * be represented without a mask in WebRender.
+   */
+  static bool UsingSimpleClipPathForFrame(const nsIFrame* aFrame);
+
+  /**
    * Returns the size of the union of the border-box rects of all of
    * aNonSVGFrame's continuations.
    */
   static nsSize GetContinuationUnionSize(nsIFrame* aNonSVGFrame);
 
   /**
    * When SVG effects need to resolve percentage, userSpaceOnUse lengths, they
    * need a coordinate context to resolve them against. This method provides