Bug 1438990 - Remove common clip count code from FrameLayerBuilder, as it's no longer necessary now that we have ASRs. r=mstange
☠☠ backed out by b6252f86f57b ☠ ☠
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 07 Mar 2018 15:40:42 +1300
changeset 462178 2c63728fdf4b4c5d522a382a47df2aed6bff03c4
parent 462177 cc36ff7b9f58d3f816f44339eca78b8c9c9120f8
child 462179 fe859b4ec63cc8737ad26a1ca2bc2e7bfaa6dcdc
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1438990
milestone60.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 1438990 - Remove common clip count code from FrameLayerBuilder, as it's no longer necessary now that we have ASRs. r=mstange * * * [mq]: fix MozReview-Commit-ID: F3tlwtmGlvL
layout/painting/DisplayItemClip.cpp
layout/painting/DisplayItemClip.h
layout/painting/FrameLayerBuilder.cpp
layout/painting/FrameLayerBuilder.h
layout/reftests/border-radius/reftest.list
--- a/layout/painting/DisplayItemClip.cpp
+++ b/layout/painting/DisplayItemClip.cpp
@@ -86,21 +86,20 @@ DisplayItemClip::IntersectWith(const Dis
     mRoundedClipRects.Clear();
     return;
   }
   mRoundedClipRects.AppendElements(aOther.mRoundedClipRects);
 }
 
 void
 DisplayItemClip::ApplyTo(gfxContext* aContext,
-                         int32_t A2D,
-                         uint32_t aBegin, uint32_t aEnd)
+                         int32_t A2D)
 {
   ApplyRectTo(aContext, A2D);
-  ApplyRoundedRectClipsTo(aContext, A2D, aBegin, aEnd);
+  ApplyRoundedRectClipsTo(aContext, A2D, 0, mRoundedClipRects.Length());
 }
 
 void
 DisplayItemClip::ApplyRectTo(gfxContext* aContext, int32_t A2D) const
 {
   aContext->NewPath();
   gfxRect clip = nsLayoutUtils::RectToGfxRect(mClipRect, A2D);
   aContext->Rectangle(clip, true);
@@ -121,40 +120,37 @@ DisplayItemClip::ApplyRoundedRectClipsTo
       MakeRoundedRectPath(aDrawTarget, A2D, mRoundedClipRects[i]);
     aContext->Clip(roundedRect);
   }
 }
 
 void
 DisplayItemClip::FillIntersectionOfRoundedRectClips(gfxContext* aContext,
                                                     const Color& aColor,
-                                                    int32_t aAppUnitsPerDevPixel,
-                                                    uint32_t aBegin,
-                                                    uint32_t aEnd) const
+                                                    int32_t aAppUnitsPerDevPixel) const
 {
   DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
 
-  aEnd = std::min<uint32_t>(aEnd, mRoundedClipRects.Length());
-
-  if (aBegin >= aEnd) {
+  uint32_t end = mRoundedClipRects.Length();
+  if (!end) {
     return;
   }
 
   // Push clips for any rects that come BEFORE the rect at |aEnd - 1|, if any:
-  ApplyRoundedRectClipsTo(aContext, aAppUnitsPerDevPixel, aBegin, aEnd - 1);
+  ApplyRoundedRectClipsTo(aContext, aAppUnitsPerDevPixel, 0, end - 1);
 
   // Now fill the rect at |aEnd - 1|:
   RefPtr<Path> roundedRect = MakeRoundedRectPath(aDrawTarget,
                                                  aAppUnitsPerDevPixel,
-                                                 mRoundedClipRects[aEnd - 1]);
+                                                 mRoundedClipRects[end - 1]);
   ColorPattern color(ToDeviceColor(aColor));
   aDrawTarget.Fill(roundedRect, color);
 
   // Finally, pop any clips that we may have pushed:
-  for (uint32_t i = aBegin; i < aEnd - 1; ++i) {
+  for (uint32_t i = 0; i < end - 1; ++i) {
     aContext->PopClip();
   }
 }
 
 already_AddRefed<Path>
 DisplayItemClip::MakeRoundedRectPath(DrawTarget& aDrawTarget,
                                      int32_t A2D,
                                      const RoundedRect &aRoundRect) const
@@ -353,66 +349,46 @@ AccumulateRectDifference(const nsRect& a
     return;
   nsRegion r;
   r.Xor(aR1, aR2);
   r.And(r, aBounds);
   aOut->Or(*aOut, r);
 }
 
 void
-DisplayItemClip::AddOffsetAndComputeDifference(uint32_t aStart,
-                                               const nsPoint& aOffset,
+DisplayItemClip::AddOffsetAndComputeDifference(const nsPoint& aOffset,
                                                const nsRect& aBounds,
                                                const DisplayItemClip& aOther,
-                                               uint32_t aOtherStart,
                                                const nsRect& aOtherBounds,
                                                nsRegion* aDifference)
 {
   if (mHaveClipRect != aOther.mHaveClipRect ||
-      aStart != aOtherStart ||
       mRoundedClipRects.Length() != aOther.mRoundedClipRects.Length()) {
     aDifference->Or(*aDifference, aBounds);
     aDifference->Or(*aDifference, aOtherBounds);
     return;
   }
   if (mHaveClipRect) {
     AccumulateRectDifference(mClipRect + aOffset, aOther.mClipRect,
                              aBounds.Union(aOtherBounds),
                              aDifference);
   }
-  for (uint32_t i = aStart; i < mRoundedClipRects.Length(); ++i) {
+  for (uint32_t i = 0; i < mRoundedClipRects.Length(); ++i) {
     if (mRoundedClipRects[i] + aOffset != aOther.mRoundedClipRects[i]) {
       // The corners make it tricky so we'll just add both rects here.
       aDifference->Or(*aDifference, mRoundedClipRects[i].mRect.Intersect(aBounds));
       aDifference->Or(*aDifference, aOther.mRoundedClipRects[i].mRect.Intersect(aOtherBounds));
     }
   }
 }
 
-uint32_t
-DisplayItemClip::GetCommonRoundedRectCount(const DisplayItemClip& aOther,
-                                           uint32_t aMax) const
+void
+DisplayItemClip::AppendRoundedRects(nsTArray<RoundedRect>* aArray) const
 {
-  uint32_t end = std::min(std::min(mRoundedClipRects.Length(), size_t(aMax)),
-                          aOther.mRoundedClipRects.Length());
-  uint32_t clipCount = 0;
-  for (; clipCount < end; ++clipCount) {
-    if (mRoundedClipRects[clipCount] !=
-        aOther.mRoundedClipRects[clipCount]) {
-      return clipCount;
-    }
-  }
-  return clipCount;
-}
-
-void
-DisplayItemClip::AppendRoundedRects(nsTArray<RoundedRect>* aArray, uint32_t aCount) const
-{
-  size_t count = std::min(mRoundedClipRects.Length(), size_t(aCount));
-  aArray->AppendElements(mRoundedClipRects.Elements(), count);
+  aArray->AppendElements(mRoundedClipRects.Elements(), mRoundedClipRects.Length());
 }
 
 bool
 DisplayItemClip::ComputeRegionInClips(const DisplayItemClip* aOldClip,
                                       const nsPoint& aShift,
                                       nsRegion* aCombined) const
 {
   if (!mHaveClipRect || (aOldClip && !aOldClip->mHaveClipRect)) {
--- a/layout/painting/DisplayItemClip.h
+++ b/layout/painting/DisplayItemClip.h
@@ -76,32 +76,29 @@ public:
   void SetTo(const nsRect& aRect);
   void SetTo(const nsRect& aRect, const nscoord* aRadii);
   void SetTo(const nsRect& aRect, const nsRect& aRoundedRect, const nscoord* aRadii);
   void IntersectWith(const DisplayItemClip& aOther);
 
   // Apply this |DisplayItemClip| to the given gfxContext.  Any saving of state
   // or clearing of other clips must be done by the caller.
   // See aBegin/aEnd note on ApplyRoundedRectsTo.
-  void ApplyTo(gfxContext* aContext, int32_t A2D,
-               uint32_t aBegin = 0, uint32_t aEnd = UINT32_MAX);
+  void ApplyTo(gfxContext* aContext, int32_t A2D);
 
   void ApplyRectTo(gfxContext* aContext, int32_t A2D) const;
   // Applies the rounded rects in this Clip to aContext
   // Will only apply rounded rects from aBegin (inclusive) to aEnd
   // (exclusive) or the number of rounded rects, whichever is smaller.
   void ApplyRoundedRectClipsTo(gfxContext* aContext, int32_t A2DPRInt32,
                                uint32_t aBegin, uint32_t aEnd) const;
 
   // Draw (fill) the rounded rects in this clip to aContext
   void FillIntersectionOfRoundedRectClips(gfxContext* aContext,
                                           const Color& aColor,
-                                          int32_t aAppUnitsPerDevPixel,
-                                          uint32_t aBegin,
-                                          uint32_t aEnd) const;
+                                          int32_t aAppUnitsPerDevPixel) const;
   // 'Draw' (create as a path, does not stroke or fill) aRoundRect to aContext
   already_AddRefed<Path> MakeRoundedRectPath(DrawTarget& aDrawTarget,
                                                   int32_t A2D,
                                                   const RoundedRect &aRoundRect) const;
 
   // Returns true if the intersection of aRect and this clip region is
   // non-empty. This is precise for DisplayItemClips with at most one
   // rounded rectangle. When multiple rounded rectangles are present, we just
@@ -143,18 +140,18 @@ public:
   // rounded corners.
   nsRect ApplyNonRoundedIntersection(const nsRect& aRect) const;
 
   // Gets rid of any rounded corners in this clip.
   void RemoveRoundedCorners();
 
   // Adds the difference between Intersect(*this + aPoint, aBounds) and
   // Intersect(aOther, aOtherBounds) to aDifference (or a bounding-box thereof).
-  void AddOffsetAndComputeDifference(uint32_t aStart, const nsPoint& aPoint, const nsRect& aBounds,
-                                     const DisplayItemClip& aOther, uint32_t aOtherStart, const nsRect& aOtherBounds,
+  void AddOffsetAndComputeDifference(const nsPoint& aPoint, const nsRect& aBounds,
+                                     const DisplayItemClip& aOther, const nsRect& aOtherBounds,
                                      nsRegion* aDifference);
 
   bool operator==(const DisplayItemClip& aOther) const {
     return mHaveClipRect == aOther.mHaveClipRect &&
            (!mHaveClipRect || mClipRect.IsEqualInterior(aOther.mClipRect)) &&
            mRoundedClipRects == aOther.mRoundedClipRects;
   }
   bool operator!=(const DisplayItemClip& aOther) const {
@@ -167,24 +164,18 @@ public:
     NS_ASSERTION(HasClip(), "No clip rect!");
     return mClipRect;
   }
 
   void MoveBy(const nsPoint& aPoint);
 
   nsCString ToString() const;
 
-  /**
-   * Find the largest N such that the first N rounded rects in 'this' are
-   * equal to the first N rounded rects in aOther, and N <= aMax.
-   */
-  uint32_t GetCommonRoundedRectCount(const DisplayItemClip& aOther,
-                                     uint32_t aMax) const;
   uint32_t GetRoundedRectCount() const { return mRoundedClipRects.Length(); }
-  void AppendRoundedRects(nsTArray<RoundedRect>* aArray, uint32_t aCount) const;
+  void AppendRoundedRects(nsTArray<RoundedRect>* aArray) const;
 
   void ToComplexClipRegions(int32_t aAppUnitsPerDevPixel,
                               const layers::StackingContextHelper& aSc,
                               nsTArray<wr::ComplexClipRegion>& aOutArray) const;
 
   static const DisplayItemClip& NoClip();
 
   static void Shutdown();
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -444,17 +444,16 @@ public:
     mForceTransparentSurface(false),
     mHideAllLayersBelow(false),
     mOpaqueForAnimatedGeometryRootParent(false),
     mDisableFlattening(false),
     mBackfaceHidden(false),
     mShouldPaintOnContentSide(false),
     mDTCRequiresTargetConfirmation(false),
     mImage(nullptr),
-    mCommonClipCount(-1),
     mNewChildLayersIndex(-1)
   {}
 
 #ifdef MOZ_DUMP_PAINTING
   /**
    * Keep track of important decisions for debugging.
    */
   nsCString mLog;
@@ -657,33 +656,19 @@ public:
    * image, a clip for SOME item in the layer. There is no guarantee which
    * item's clip will be stored here and mItemClip should not be used to clip
    * the whole layer - only some part of the clip should be used, as determined
    * by PaintedDisplayItemLayerUserData::GetCommonClipCount() - which may even be
    * no part at all.
    */
   DisplayItemClip mItemClip;
   /**
-   * The first mCommonClipCount rounded rectangle clips are identical for
-   * all items in the layer.
-   * -1 if there are no items in the layer; must be >=0 by the time that this
-   * data is popped from the stack.
-   */
-  int32_t mCommonClipCount;
-  /**
    * Index of this layer in mNewChildLayers.
    */
   int32_t mNewChildLayersIndex;
-  /*
-   * Updates mCommonClipCount by checking for rounded rect clips in common
-   * between the clip on a new item (aCurrentClip) and the common clips
-   * on items already in the layer (the first mCommonClipCount rounded rects
-   * in mItemClip).
-   */
-  void UpdateCommonClipCount(const DisplayItemClip& aCurrentClip);
   /**
    * The region of visible content above the layer and below the
    * next PaintedLayerData currently in the stack, if any.
    * This is a conservative approximation: it contains the true region.
    */
   nsIntRegion mVisibleAboveRegion;
   /**
    * All the display items that have been assigned to this painted layer.
@@ -1380,22 +1365,18 @@ protected:
 
   /* Build a mask layer to represent the clipping region. Will return null if
    * there is no clipping specified or a mask layer cannot be built.
    * Builds an ImageLayer for the appropriate backend; the mask is relative to
    * aLayer's visible region.
    * aLayer is the layer to be clipped.
    * relative to the container reference frame
    * aRoundedRectClipCount is used when building mask layers for PaintedLayers,
-   * SetupMaskLayer will build a mask layer for only the first
-   * aRoundedRectClipCount rounded rects in aClip
-   * Returns the number of rounded rects included in the mask layer.
    */
-  uint32_t SetupMaskLayer(Layer *aLayer, const DisplayItemClip& aClip,
-                          uint32_t aRoundedRectClipCount = UINT32_MAX);
+  void SetupMaskLayer(Layer *aLayer, const DisplayItemClip& aClip);
 
   /**
    * If |aClip| has rounded corners, create a mask layer for them, and
    * add it to |aLayer|'s ancestor mask layers, returning an index into
    * the array of ancestor mask layers. Returns an empty Maybe if
    * |aClip| does not have rounded corners, or if no mask layer could
    * be created.
    */
@@ -1405,18 +1386,17 @@ protected:
   /*
    * Create/find a mask layer with suitable size for aMaskItem to paint
    * css-positioned-masking onto.
    */
   void SetupMaskLayerForCSSMask(Layer* aLayer, nsDisplayMask* aMaskItem);
 
   already_AddRefed<Layer> CreateMaskLayer(
     Layer *aLayer, const DisplayItemClip& aClip,
-    const Maybe<size_t>& aForAncestorMaskLayer,
-    uint32_t aRoundedRectClipCount = UINT32_MAX);
+    const Maybe<size_t>& aForAncestorMaskLayer);
 
   /**
    * Get the display port for an AGR.
    * The result would be cached for later reusing.
    */
   nsRect GetDisplayPortForAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot);
 
   nsDisplayListBuilder*            mBuilder;
@@ -1493,43 +1473,28 @@ protected:
   AnimatedGeometryRoot* mLastDisplayPortAGR;
   nsRect mLastDisplayPortRect;
 };
 
 class PaintedDisplayItemLayerUserData : public LayerUserData
 {
 public:
   PaintedDisplayItemLayerUserData() :
-    mMaskClipCount(0),
-    mLastCommonClipCount(0),
     mForcedBackgroundColor(NS_RGBA(0,0,0,0)),
     mXScale(1.f), mYScale(1.f),
     mAppUnitsPerDevPixel(0),
     mTranslation(0, 0),
     mAnimatedGeometryRootPosition(0, 0),
     mLastItemCount(0),
     mContainerLayerFrame(nullptr),
     mHasExplicitLastPaintOffset(false) {}
 
   NS_INLINE_DECL_REFCOUNTING(PaintedDisplayItemLayerUserData);
 
   /**
-   * Record the number of clips in the PaintedLayer's mask layer.
-   * Should not be reset when the layer is recycled since it is used to track
-   * changes in the use of mask layers.
-   */
-  uint32_t mMaskClipCount;
-
-  /**
-   * Records the number of clips in the PaintedLayer's mask layer during
-   * the previous paint. Used for invalidation.
-   */
-  uint32_t mLastCommonClipCount;
-
-  /**
    * A color that should be painted over the bounds of the layer's visible
    * region before any other content is painted.
    */
   nscolor mForcedBackgroundColor;
 
   /**
    * The resolution scale used.
    */
@@ -1635,25 +1600,24 @@ FrameLayerBuilder::AddPaintedLayerItemsE
 struct MaskLayerUserData : public LayerUserData
 {
   MaskLayerUserData()
     : mScaleX(-1.0f)
     , mScaleY(-1.0f)
     , mAppUnitsPerDevPixel(-1)
   { }
   MaskLayerUserData(const DisplayItemClip& aClip,
-                    uint32_t aRoundedRectClipCount,
                     int32_t aAppUnitsPerDevPixel,
                     const ContainerLayerParameters& aParams)
     : mScaleX(aParams.mXScale)
     , mScaleY(aParams.mYScale)
     , mOffset(aParams.mOffset)
     , mAppUnitsPerDevPixel(aAppUnitsPerDevPixel)
   {
-    aClip.AppendRoundedRects(&mRoundedClipRects, aRoundedRectClipCount);
+    aClip.AppendRoundedRects(&mRoundedClipRects);
   }
 
   void operator=(MaskLayerUserData&& aOther)
   {
     mScaleX = aOther.mScaleX;
     mScaleY = aOther.mScaleY;
     mOffset = aOther.mOffset;
     mAppUnitsPerDevPixel = aOther.mAppUnitsPerDevPixel;
@@ -2495,17 +2459,16 @@ ContainerState::PreparePaintedLayerForUs
   aData->mYScale = mParameters.mYScale;
   aData->mLastAnimatedGeometryRootOrigin = aData->mAnimatedGeometryRootOrigin;
   aData->mAnimatedGeometryRootOrigin = aTopLeft;
   aData->mAppUnitsPerDevPixel = mAppUnitsPerDevPixel;
   aLayer->SetAllowResidualTranslation(mParameters.AllowResidualTranslation());
 
   aData->mLastPaintOffset = GetTranslationForPaintedLayer(aLayer);
   aData->mHasExplicitLastPaintOffset = true;
-  aData->mLastCommonClipCount = aData->mMaskClipCount;
 
   // Set up transform so that 0,0 in the PaintedLayer corresponds to the
   // (pixel-snapped) top-left of the aAnimatedGeometryRoot.
   nsPoint offset = (*aAnimatedGeometryRoot)->GetOffsetToCrossDoc(aReferenceFrame);
   nscoord appUnitsPerDevPixel = (*aAnimatedGeometryRoot)->PresContext()->AppUnitsPerDevPixel();
   gfxPoint scaledOffset(
       NSAppUnitsToDoublePixels(offset.x, appUnitsPerDevPixel)*mParameters.mXScale,
       NSAppUnitsToDoublePixels(offset.y, appUnitsPerDevPixel)*mParameters.mYScale);
@@ -2758,28 +2721,16 @@ PaintedLayerDataNode::FindOpaqueBackgrou
       return mParent->FindOpaqueBackgroundColor(mClipRect);
     }
     return mParent->FindOpaqueBackgroundColorCoveringEverything();
   }
   // We are the root.
   return mTree.UniformBackgroundColor();
 }
 
-void
-PaintedLayerData::UpdateCommonClipCount(
-    const DisplayItemClip& aCurrentClip)
-{
-  if (mCommonClipCount >= 0) {
-    mCommonClipCount = mItemClip.GetCommonRoundedRectCount(aCurrentClip, mCommonClipCount);
-  } else {
-    // first item in the layer
-    mCommonClipCount = aCurrentClip.GetRoundedRectCount();
-  }
-}
-
 bool
 PaintedLayerData::CanOptimizeToImageLayer(nsDisplayListBuilder* aBuilder)
 {
   if (!mImage) {
     return false;
   }
 
   return mImage->CanOptimizeToImageLayer(mLayer->Manager(), aBuilder);
@@ -3356,32 +3307,16 @@ void ContainerState::FinishPaintedLayerD
         nsAutoCString str;
         AppendToString(str, data->mLayer->GetValidRegion());
         printf_stderr("Invalidating layer %p: %s\n", data->mLayer, str.get());
       }
 #endif
       data->mLayer->InvalidateWholeLayer();
     }
     userData->mForcedBackgroundColor = backgroundColor;
-
-    // use a mask layer for rounded rect clipping.
-    // data->mCommonClipCount may be -1 if we haven't put any actual
-    // drawable items in this layer (i.e. it's only catching events).
-    uint32_t commonClipCount;
-    commonClipCount = std::max(0, data->mCommonClipCount);
-
-    // if the number of clips we are going to mask has decreased, then aLayer might have
-    // cached graphics which assume the existence of a soon-to-be non-existent mask layer
-    // in that case, invalidate the whole layer.
-    if (commonClipCount < userData->mMaskClipCount) {
-      PaintedLayer* painted = layer->AsPaintedLayer();
-      painted->InvalidateWholeLayer();
-    }
-
-    userData->mMaskClipCount = SetupMaskLayer(layer, data->mItemClip, commonClipCount);
   } else {
     // mask layer for image and color layers
     SetupMaskLayer(layer, data->mItemClip);
   }
 
   uint32_t flags = 0;
   nsIWidget* widget = mContainerReferenceFrame->PresContext()->GetRootWidget();
   // See bug 941095. Not quite ready to disable this.
@@ -4014,18 +3949,17 @@ ContainerState::ComputeOpaqueRect(nsDisp
 }
 
 Maybe<size_t>
 ContainerState::SetupMaskLayerForScrolledClip(Layer* aLayer,
                                               const DisplayItemClip& aClip)
 {
   if (aClip.GetRoundedRectCount() > 0) {
     Maybe<size_t> maskLayerIndex = Some(aLayer->GetAncestorMaskLayerCount());
-    if (RefPtr<Layer> maskLayer = CreateMaskLayer(aLayer, aClip, maskLayerIndex,
-                                                  aClip.GetRoundedRectCount())) {
+    if (RefPtr<Layer> maskLayer = CreateMaskLayer(aLayer, aClip, maskLayerIndex)) {
       aLayer->AddAncestorMaskLayer(maskLayer);
       return maskLayerIndex;
     }
     // Fall through to |return Nothing()|.
   }
   return Nothing();
 }
 
@@ -4682,21 +4616,16 @@ ContainerState::ProcessDisplayItems(nsDi
         nsDisplayLayerEventRegions* eventRegions =
           static_cast<nsDisplayLayerEventRegions*>(item);
         paintedLayerData->AccumulateEventRegions(this, eventRegions);
       } else if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
         nsDisplayCompositorHitTestInfo* hitTestInfo =
           static_cast<nsDisplayCompositorHitTestInfo*>(item);
         paintedLayerData->AccumulateHitTestInfo(this, hitTestInfo);
       } else {
-        // check to see if the new item has rounded rect clips in common with
-        // other items in the layer
-        if (mManager->IsWidgetLayerManager()) {
-          paintedLayerData->UpdateCommonClipCount(itemClip);
-        }
         paintedLayerData->Accumulate(this, item, itemVisibleRect, itemClip, layerState, aList);
 
         if (!paintedLayerData->mLayer) {
           // Try to recycle the old layer of this display item.
           RefPtr<PaintedLayer> layer =
             AttemptToRecyclePaintedLayer(animatedGeometryRoot, item,
                                          topLeft, referenceFrame);
           if (layer) {
@@ -4815,21 +4744,19 @@ FrameLayerBuilder::ComputeGeometryChange
 
     // Only allocate a new geometry object if something actually changed, otherwise the existing
     // one should be fine. We always reallocate for inactive layers, since these types don't
     // implement ComputeInvalidateRegion (and rely on the ComputeDifferences call in
     // AddPaintedDisplayItem instead).
     if (!combined.IsEmpty() || aData->mLayerState == LAYER_INACTIVE) {
       geometry = item->AllocateGeometry(mDisplayListBuilder);
     }
-    aData->mClip.AddOffsetAndComputeDifference(layerData->mMaskClipCount,
-                                               shift, aData->mGeometry->ComputeInvalidationRegion(),
-                                               clip, layerData->mLastCommonClipCount,
-                                               geometry ? geometry->ComputeInvalidationRegion() :
-                                                          aData->mGeometry->ComputeInvalidationRegion(),
+    aData->mClip.AddOffsetAndComputeDifference(shift, aData->mGeometry->ComputeInvalidationRegion(),
+                                               clip, geometry ? geometry->ComputeInvalidationRegion() :
+                                                                aData->mGeometry->ComputeInvalidationRegion(),
                                                &combined);
 
     // Add in any rect that the frame specified
     combined.Or(combined, invalid);
     combined.Or(combined, changedFrameInvalidations);
 
     // Restrict invalidation to the clipped region
     nsRegion clipRegion;
@@ -5303,17 +5230,17 @@ ContainerState::SetupScrollingMetadata(N
         clip->GetRoundedRectCount() > 0)
     {
       // The clip in between this scrollframe and its ancestor scrollframe
       // requires a mask layer. Since this mask layer should not move with
       // the APZC associated with this FrameMetrics, we attach the mask
       // layer as an additional, separate clip.
       Maybe<size_t> nextIndex = Some(maskLayers.Length());
       RefPtr<Layer> maskLayer =
-        CreateMaskLayer(aEntry->mLayer, *clip, nextIndex, clip->GetRoundedRectCount());
+        CreateMaskLayer(aEntry->mLayer, *clip, nextIndex);
       if (maskLayer) {
         MOZ_ASSERT(metadata->HasScrollClip());
         metadata->ScrollClip().SetMaskLayerIndex(nextIndex);
         maskLayers.AppendElement(maskLayer);
       }
     }
 
     metricsArray.AppendElement(*metadata);
@@ -6029,18 +5956,17 @@ FrameLayerBuilder::RecomputeVisibilityFo
 
 void
 FrameLayerBuilder::PaintItems(nsTArray<AssignedDisplayItem>& aItems,
                               const nsIntRect& aRect,
                               gfxContext *aContext,
                               nsDisplayListBuilder* aBuilder,
                               nsPresContext* aPresContext,
                               const nsIntPoint& aOffset,
-                              float aXScale, float aYScale,
-                              int32_t aCommonClipCount)
+                              float aXScale, float aYScale)
 {
   DrawTarget& aDrawTarget = *aContext->GetDrawTarget();
 
   int32_t appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel();
   nsRect boundRect = ToAppUnits(aRect, appUnitsPerDevPixel);
   boundRect.MoveBy(NSIntPixelsToAppUnits(aOffset.x, appUnitsPerDevPixel),
                  NSIntPixelsToAppUnits(aOffset.y, appUnitsPerDevPixel));
   boundRect.ScaleInverseRoundOut(aXScale, aYScale);
@@ -6079,19 +6005,17 @@ FrameLayerBuilder::PaintItems(nsTArray<A
         (clip->HasClip() && *clip != currentClip)) {
       if (currentClipIsSetInContext) {
         aContext->Restore();
       }
       currentClipIsSetInContext = clip->HasClip();
       if (currentClipIsSetInContext) {
         currentClip = *clip;
         aContext->Save();
-        NS_ASSERTION(aCommonClipCount < 100,
-          "Maybe you really do have more than a hundred clipping rounded rects, or maybe something has gone wrong.");
-        currentClip.ApplyTo(aContext, aPresContext->AppUnitsPerDevPixel(), aCommonClipCount);
+        currentClip.ApplyTo(aContext, aPresContext->AppUnitsPerDevPixel());
         aContext->NewPath();
       }
     }
 
     if (cdi->mInactiveLayerManager) {
       bool saved = aDrawTarget.GetPermitSubpixelAA();
       PaintInactiveLayer(aBuilder, cdi->mInactiveLayerManager, cdi->mItem, aContext, aContext);
       aDrawTarget.SetPermitSubpixelAA(saved);
@@ -6244,34 +6168,32 @@ FrameLayerBuilder::DrawPaintedLayer(Pain
       // snapping when we draw into aContext exactly matches the ideal transform.
       // See above for why this is OK.
       aContext->SetMatrixDouble(
         aContext->CurrentMatrixDouble().PreTranslate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y)).
                                         PreScale(userData->mXScale, userData->mYScale));
 
       layerBuilder->PaintItems(userData->mItems, iterRect, aContext,
                                builder, presContext,
-                               offset, userData->mXScale, userData->mYScale,
-                               userData->mMaskClipCount);
+                               offset, userData->mXScale, userData->mYScale);
       if (gfxPrefs::GfxLoggingPaintedPixelCountEnabled()) {
         aLayer->Manager()->AddPaintedPixelCount(iterRect.Area());
       }
     }
   } else {
     // Apply the residual transform if it has been enabled, to ensure that
     // snapping when we draw into aContext exactly matches the ideal transform.
     // See above for why this is OK.
     aContext->SetMatrixDouble(
       aContext->CurrentMatrixDouble().PreTranslate(aLayer->GetResidualTranslation() - gfxPoint(offset.x, offset.y)).
                                       PreScale(userData->mXScale,userData->mYScale));
 
     layerBuilder->PaintItems(userData->mItems, aRegionToDraw.GetBounds(), aContext,
                              builder, presContext,
-                             offset, userData->mXScale, userData->mYScale,
-                             userData->mMaskClipCount);
+                             offset, userData->mXScale, userData->mYScale);
     if (gfxPrefs::GfxLoggingPaintedPixelCountEnabled()) {
       aLayer->Manager()->AddPaintedPixelCount(
         aRegionToDraw.GetBounds().Area());
     }
   }
 
   bool isActiveLayerManager = !aLayer->Manager()->IsInactiveLayerManager();
 
@@ -6338,36 +6260,33 @@ CalculateBounds(const nsTArray<DisplayIt
   nsRect bounds = aRects[0].mRect;
   for (uint32_t i = 1; i < aRects.Length(); ++i) {
     bounds.UnionRect(bounds, aRects[i].mRect);
    }
 
   return gfx::Rect(bounds.ToNearestPixels(aAppUnitsPerDevPixel));
 }
 
-uint32_t
+void
 ContainerState::SetupMaskLayer(Layer *aLayer,
-                               const DisplayItemClip& aClip,
-                               uint32_t aRoundedRectClipCount)
+                               const DisplayItemClip& aClip)
 {
   // don't build an unnecessary mask
-  if (aClip.GetRoundedRectCount() == 0 ||
-      aRoundedRectClipCount == 0) {
-    return 0;
+  if (aClip.GetRoundedRectCount() == 0) {
+    return;
   }
 
   RefPtr<Layer> maskLayer =
-    CreateMaskLayer(aLayer, aClip, Nothing(), aRoundedRectClipCount);
+    CreateMaskLayer(aLayer, aClip, Nothing());
 
   if (!maskLayer) {
-    return 0;
+    return;
   }
 
   aLayer->SetMaskLayer(maskLayer);
-  return aRoundedRectClipCount;
 }
 
 static MaskLayerUserData*
 GetMaskLayerUserData(Layer* aMaskLayer)
 {
   if (!aMaskLayer) {
     return nullptr;
   }
@@ -6382,35 +6301,34 @@ SetMaskLayerUserData(Layer* aMaskLayer)
 
   aMaskLayer->SetUserData(&gMaskLayerUserData,
                           new MaskLayerUserData());
 }
 
 already_AddRefed<Layer>
 ContainerState::CreateMaskLayer(Layer *aLayer,
                                const DisplayItemClip& aClip,
-                               const Maybe<size_t>& aForAncestorMaskLayer,
-                               uint32_t aRoundedRectClipCount)
+                               const Maybe<size_t>& aForAncestorMaskLayer)
 {
   // aLayer will never be the container layer created by an nsDisplayMask
   // because nsDisplayMask propagates the DisplayItemClip to its contents
   // and is not clipped itself.
   // This assertion will fail if that ever stops being the case.
   MOZ_ASSERT(!aLayer->GetUserData(&gCSSMaskLayerUserData),
              "A layer contains round clips should not have css-mask on it.");
 
   // check if we can re-use the mask layer
   RefPtr<ImageLayer> maskLayer =
       CreateOrRecycleMaskImageLayerFor(MaskLayerKey(aLayer, aForAncestorMaskLayer),
                                        GetMaskLayerUserData,
                                        SetMaskLayerUserData);
   MaskLayerUserData* userData = GetMaskLayerUserData(maskLayer.get());
 
   int32_t A2D = mContainerFrame->PresContext()->AppUnitsPerDevPixel();
-  MaskLayerUserData newData(aClip, aRoundedRectClipCount, A2D, mParameters);
+  MaskLayerUserData newData(aClip, A2D, mParameters);
   if (*userData == newData) {
     return maskLayer.forget();
   }
 
   gfx::Rect boundingRect = CalculateBounds(newData.mRoundedClipRects,
                                            newData.mAppUnitsPerDevPixel);
   boundingRect.Scale(mParameters.mXScale, mParameters.mYScale);
   if (boundingRect.IsEmpty()) {
@@ -6480,19 +6398,17 @@ ContainerState::CreateMaskLayer(Layer *a
 
     RefPtr<gfxContext> context = gfxContext::CreateOrNull(dt);
     MOZ_ASSERT(context); // already checked the draw target above
     context->Multiply(ThebesMatrix(imageTransform));
 
     // paint the clipping rects with alpha to create the mask
     aClip.FillIntersectionOfRoundedRectClips(context,
                                              Color(1.f, 1.f, 1.f, 1.f),
-                                             newData.mAppUnitsPerDevPixel,
-                                             0,
-                                             aRoundedRectClipCount);
+                                             newData.mAppUnitsPerDevPixel);
 
     // build the image and container
     MOZ_ASSERT(aLayer->Manager() == mManager);
     container = imageData.CreateImageAndImageContainer();
     NS_ASSERTION(container, "Could not create image container for mask layer.");
 
     if (!container) {
       return nullptr;
--- a/layout/painting/FrameLayerBuilder.h
+++ b/layout/painting/FrameLayerBuilder.h
@@ -669,18 +669,17 @@ protected:
                                           float aYScale);
 
   void PaintItems(nsTArray<AssignedDisplayItem>& aItems,
                   const nsIntRect& aRect,
                   gfxContext* aContext,
                   nsDisplayListBuilder* aBuilder,
                   nsPresContext* aPresContext,
                   const nsIntPoint& aOffset,
-                  float aXScale, float aYScale,
-                  int32_t aCommonClipCount);
+                  float aXScale, float aYScale);
 
   /**
    * We accumulate ClippedDisplayItem elements in a hashtable during
    * the paint process. This is the hashentry for that hashtable.
    */
 public:
   /**
    * Add the PaintedDisplayItemLayerUserData object as being used in this
--- a/layout/reftests/border-radius/reftest.list
+++ b/layout/reftests/border-radius/reftest.list
@@ -46,17 +46,17 @@ fuzzy-if(/^Windows\x20NT\x2010\.0/.test(
 fuzzy-if(true,1,20) fuzzy-if(d2d,72,196) fuzzy-if(cocoaWidget,1,180) fuzzy-if(Android,140,237) == clipping-4-canvas.html clipping-4-ref.html # bug 732535
 fuzzy-if(Android,5,54) fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,10) fuzzy-if(skiaContent,1,172) == clipping-4-image.html clipping-4-ref.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,10) fuzzy-if(skiaContent,1,77) == clipping-4-overflow-hidden.html clipping-4-ref.html
 == clipping-5-canvas.html clipping-5-refc.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) == clipping-5-image.html clipping-5-refi.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(skiaContent,1,77) == clipping-5-overflow-hidden.html clipping-5-ref.html
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) fuzzy-if(Android,5,21) fuzzy-if(skiaContent,1,97) == clipping-5-refi.html clipping-5-ref.html
 fuzzy-if(true,1,7) fuzzy-if(d2d,55,95) fuzzy-if(cocoaWidget,1,99) fuzzy-if(Android,99,115) fuzzy-if(skiaContent,1,77) == clipping-5-refc.html clipping-5-ref.html # bug 732535
-fuzzy-if(winWidget,105,71) fuzzy-if(Android,8,469) fuzzy-if(skiaContent,7,58) fuzzy-if(d3d11&&advancedLayers,120,319) fuzzy-if(winWidget&&stylo,144,319) == clipping-6.html clipping-6-ref.html # PaintedLayer and MaskLayer with transforms that aren't identical
+fuzzy-if(winWidget,105,71) fuzzy-if(Android,8,469) fuzzy-if(skiaContent,16,74) fuzzy-if(d3d11&&advancedLayers,120,319) fuzzy-if(winWidget&&stylo,144,319) == clipping-6.html clipping-6-ref.html # PaintedLayer and MaskLayer with transforms that aren't identical
 fuzzy-if(true,2,29) fuzzy-if(d2d,46,71) fuzzy-if(Android,255,586) fuzzy-if(skiaContent,28,96) == clipping-7.html clipping-7-ref.html # ColorLayer and MaskLayer with transforms that aren't identical. Reference image rendered without using layers (which causes fuzzy failures).
 fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),1,5) == clipping-and-zindex-1.html clipping-and-zindex-1-ref.html
 fuzzy-if(cocoaWidget,1,4) fuzzy-if(d2d,59,342) fuzzy-if(d3d11&&advancedLayers&&!d2d,30,3) == intersecting-clipping-1-canvas.html intersecting-clipping-1-refc.html
 == intersecting-clipping-1-image.html intersecting-clipping-1-refi.html
 == intersecting-clipping-1-overflow-hidden.html intersecting-clipping-1-ref.html
 fuzzy-if(Android,5,105) fuzzy-if(d2d,1,20) fuzzy-if(skiaContent,1,300) == intersecting-clipping-1-refi.html intersecting-clipping-1-ref.html
 fuzzy-if(true,1,33) fuzzy-if(d2d,59,350) fuzzy-if(cocoaWidget,1,332) fuzzy-if(Android,124,440) fuzzy-if(skiaContent,1,135) fuzzy-if(d3d11&&advancedLayers,81,353) == intersecting-clipping-1-refc.html intersecting-clipping-1-ref.html # bug 732535