Bug 841192. Part 3: Make DisplayItemClip members private and encapsulate them in a real API. r=mattwoodrow
authorRobert O'Callahan <robert@ocallahan.org>
Mon, 04 Mar 2013 22:56:00 +1300
changeset 127798 fb7633e8733e0094329fa668b21738f6464e52cf
parent 127797 698d23ec564bb1cbb8f4b97c2aa09779bd186ad0
child 127799 ec3f4cfe3866b48f0f7714a50ae5e621f588bfcd
push idunknown
push userunknown
push dateunknown
reviewersmattwoodrow
bugs841192
milestone23.0a1
Bug 841192. Part 3: Make DisplayItemClip members private and encapsulate them in a real API. r=mattwoodrow
layout/base/DisplayItemClip.cpp
layout/base/DisplayItemClip.h
layout/base/FrameLayerBuilder.cpp
--- a/layout/base/DisplayItemClip.cpp
+++ b/layout/base/DisplayItemClip.cpp
@@ -202,16 +202,33 @@ DisplayItemClip::NonRoundedIntersection(
   nsRect result = mClipRect;
   for (uint32_t i = 0, iEnd = mRoundedClipRects.Length();
        i < iEnd; ++i) {
     result.IntersectRect(result, mRoundedClipRects[i].mRect);
   }
   return result;
 }
 
+bool
+DisplayItemClip::IsRectAffectedByClip(const nsRect& aRect) const
+{
+  if (mHaveClipRect && !mClipRect.Contains(aRect)) {
+    return true;
+  }
+  for (uint32_t i = 0, iEnd = mRoundedClipRects.Length();
+       i < iEnd; ++i) {
+    const RoundedRect &rr = mRoundedClipRects[i];
+    nsRegion rgn = nsLayoutUtils::RoundedRectIntersectRect(rr.mRect, rr.mRadii, aRect);
+    if (!rgn.Contains(aRect)) {
+      return true;
+    }
+  }
+  return false;
+}
+
 nsRect
 DisplayItemClip::ApplyNonRoundedIntersection(const nsRect& aRect) const
 {
   if (!mHaveClipRect) {
     return aRect;
   }
 
   nsRect result = aRect.Intersect(mClipRect);
@@ -264,9 +281,53 @@ DisplayItemClip::AddOffsetAndComputeDiff
     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
+{
+  uint32_t end = std::min(std::min(mRoundedClipRects.Length(), 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
+{
+  uint32_t count = std::min(mRoundedClipRects.Length(), aCount);
+  for (uint32_t i = 0; i < count; ++i) {
+    *aArray->AppendElement() = mRoundedClipRects[i];
+  }
+}
+
+bool
+DisplayItemClip::ComputeRegionInClips(DisplayItemClip* aOldClip,
+                                      const nsPoint& aShift,
+                                      nsRegion* aCombined) const
+{
+  if (!mHaveClipRect || (aOldClip && !aOldClip->mHaveClipRect)) {
+    return false;
+  }
+
+  if (aOldClip) {
+    *aCombined = aOldClip->NonRoundedIntersection();
+    aCombined->MoveBy(aShift);
+    aCombined->Or(*aCombined, NonRoundedIntersection());
+  } else {
+    *aCombined = NonRoundedIntersection();
+  }
+  return true;
+}
+
+}
--- a/layout/base/DisplayItemClip.h
+++ b/layout/base/DisplayItemClip.h
@@ -18,17 +18,18 @@ class nsRegion;
 namespace mozilla {
 
 /**
  * An DisplayItemClip represents the intersection of an optional rectangle
  * with a list of rounded rectangles (which is often empty), all in appunits.
  * It can represent everything CSS clipping can do to an element (except for
  * SVG clip-path), including no clipping at all.
  */
-struct DisplayItemClip {
+class DisplayItemClip {
+public:
   struct RoundedRect {
     nsRect mRect;
     // Indices into mRadii are the NS_CORNER_* constants in nsStyleConsts.h
     nscoord mRadii[8];
 
     RoundedRect operator+(const nsPoint& aOffset) const {
       RoundedRect r = *this;
       r.mRect += aOffset;
@@ -45,19 +46,16 @@ struct DisplayItemClip {
         }
       }
       return true;
     }
     bool operator!=(const RoundedRect& aOther) const {
       return !(*this == aOther);
     }
   };
-  nsRect mClipRect;
-  nsTArray<RoundedRect> mRoundedClipRects;
-  bool mHaveClipRect;
 
   // Constructs a DisplayItemClip that does no clipping at all.
   DisplayItemClip() : mHaveClipRect(false) {}
 
   // Construct as the intersection of aOther and aClipItem.
   DisplayItemClip(const DisplayItemClip& aOther, nsDisplayItem* aClipItem);
 
   // Apply this |DisplayItemClip| to the given gfxContext.  Any saving of state
@@ -80,22 +78,37 @@ struct DisplayItemClip {
   void AddRoundedRectPathTo(gfxContext* aContext, int32_t A2D,
                             const RoundedRect &aRoundRect) const;
 
   // Return a rectangle contained in the intersection of aRect with this
   // clip region. Tries to return the largest possible rectangle, but may
   // not succeed.
   nsRect ApproximateIntersect(const nsRect& aRect) const;
 
+  /*
+   * Computes a region which contains the clipped area of this DisplayItemClip,
+   * or if aOldClip is non-null, the union of the clipped area of this
+   * DisplayItemClip with the clipped area of aOldClip translated by aShift.
+   * The result is stored in aCombined. If the result would be infinite
+   * (because one or both of the clips does no clipping), returns false.
+   */
+  bool ComputeRegionInClips(DisplayItemClip* aOldClip,
+                            const nsPoint& aShift,
+                            nsRegion* aCombined) const;
+
   // Returns false if aRect is definitely not clipped by a rounded corner in
   // this clip. Returns true if aRect is clipped by a rounded corner in this
   // clip or it can not be quickly determined that it is not clipped by a
   // rounded corner in this clip.
   bool IsRectClippedByRoundedCorner(const nsRect& aRect) const;
 
+  // Returns false if aRect is definitely not clipped by anything in this clip.
+  // Fast but not necessarily accurate.
+  bool IsRectAffectedByClip(const nsRect& aRect) const;
+
   // Intersection of all rects in this clip ignoring any rounded corners.
   nsRect NonRoundedIntersection() const;
 
   // Intersect the given rects with all rects in this clip, ignoring any
   // rounded corners.
   nsRect ApplyNonRoundedIntersection(const nsRect& aRect) const;
 
   // Gets rid of any rounded corners in this clip.
@@ -110,13 +123,36 @@ struct DisplayItemClip {
   bool operator==(const DisplayItemClip& aOther) const {
     return mHaveClipRect == aOther.mHaveClipRect &&
            (!mHaveClipRect || mClipRect.IsEqualInterior(aOther.mClipRect)) &&
            mRoundedClipRects == aOther.mRoundedClipRects;
   }
   bool operator!=(const DisplayItemClip& aOther) const {
     return !(*this == aOther);
   }
+
+  bool HasClip() { return mHaveClipRect; }
+  const nsRect& GetClipRect()
+  {
+    NS_ASSERTION(HasClip(), "No clip rect!");
+    return mClipRect;
+  }
+
+  /**
+   * 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;
+
+private:
+  nsRect mClipRect;
+  nsTArray<RoundedRect> mRoundedClipRects;
+  // If mHaveClipRect is false then this object represents no clipping at all
+  // and mRoundedClipRects must be empty.
+  bool mHaveClipRect;
 };
 
 }
 
 #endif /* DISPLAYITEMCLIP_H_ */
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -103,18 +103,17 @@ FrameLayerBuilder::DisplayItemData::Upda
                                                    nsDisplayItem* aItem /* = nullptr */)
 {
   mLayer = aLayer;
   mOptLayer = nullptr;
   mInactiveManager = nullptr;
   mLayerState = aState;
   mContainerLayerGeneration = aContainerLayerGeneration;
   mGeometry = nullptr;
-  mClip.mHaveClipRect = false;
-  mClip.mRoundedClipRects.Clear();
+  mClip = DisplayItemClip();
   mUsed = true;
 
   if (!aItem) {
     return;
   }
 
   nsAutoTArray<nsIFrame*, 4> copy(mFrameList);
   if (!copy.RemoveElement(aItem->GetUnderlyingFrame())) {
@@ -1518,31 +1517,20 @@ ContainerState::FindOpaqueBackgroundColo
   return NS_RGBA(0,0,0,0);
 }
 
 void
 ContainerState::ThebesLayerData::UpdateCommonClipCount(
     const DisplayItemClip& aCurrentClip)
 {
   if (mCommonClipCount >= 0) {
-    int32_t end = std::min<int32_t>(aCurrentClip.mRoundedClipRects.Length(),
-                                  mCommonClipCount);
-    int32_t clipCount = 0;
-    for (; clipCount < end; ++clipCount) {
-      if (mItemClip.mRoundedClipRects[clipCount] !=
-          aCurrentClip.mRoundedClipRects[clipCount]) {
-        break;
-      }
-    }
-    mCommonClipCount = clipCount;
-    NS_ASSERTION(mItemClip.mRoundedClipRects.Length() >= uint32_t(mCommonClipCount),
-                 "Inconsistent common clip count.");
+    mCommonClipCount = mItemClip.GetCommonRoundedRectCount(aCurrentClip, mCommonClipCount);
   } else {
     // first item in the layer
-    mCommonClipCount = aCurrentClip.mRoundedClipRects.Length();
+    mCommonClipCount = aCurrentClip.GetRoundedRectCount();
   }
 }
 
 already_AddRefed<ImageContainer>
 ContainerState::ThebesLayerData::CanOptimizeImageLayer(nsDisplayListBuilder* aBuilder)
 {
   if (!mImage) {
     return nullptr;
@@ -1567,18 +1555,18 @@ ContainerState::PopThebesLayerData()
     NS_ASSERTION(!(data->mIsSolidColorInVisibleRegion && imageContainer),
                  "Can't be a solid color as well as an image!");
     if (imageContainer) {
       nsRefPtr<ImageLayer> imageLayer = CreateOrRecycleImageLayer(data->mLayer);
       imageLayer->SetContainer(imageContainer);
       data->mImage->ConfigureLayer(imageLayer, mParameters.mOffset);
       imageLayer->SetPostScale(mParameters.mXScale,
                                mParameters.mYScale);
-      if (data->mItemClip.mHaveClipRect) {
-        nsIntRect clip = ScaleToNearestPixels(data->mItemClip.mClipRect);
+      if (data->mItemClip.HasClip()) {
+        nsIntRect clip = ScaleToNearestPixels(data->mItemClip.GetClipRect());
         clip.MoveBy(mParameters.mOffset);
         imageLayer->SetClipRect(&clip);
       } else {
         imageLayer->SetClipRect(nullptr);
       }
       layer = imageLayer;
       mLayerBuilder->StoreOptimizedLayerForFrame(data->mImage,
                                                  imageLayer);
@@ -1789,17 +1777,17 @@ ContainerState::ThebesLayerData::Accumul
     // pixel-aligned (thus the item will not be truly uniform).
     if (isUniform) {
       bool snap;
       nsRect bounds = aItem->GetBounds(aState->mBuilder, &snap);
       if (!aState->ScaleToInsidePixels(bounds, snap).Contains(aVisibleRect)) {
         isUniform = false;
       }
     }
-    if (isUniform && aClip.mRoundedClipRects.IsEmpty()) {
+    if (isUniform && aClip.GetRoundedRectCount() == 0) {
       if (mVisibleRegion.IsEmpty()) {
         // This color is all we have
         mSolidColor = uniformColor;
         mIsSolidColorInVisibleRegion = true;
       } else if (mIsSolidColorInVisibleRegion &&
                  mVisibleRegion.IsEqual(nsIntRegion(aVisibleRect))) {
         // we can just blend the colors together
         mSolidColor = NS_ComposeColors(mSolidColor, uniformColor);
@@ -2086,18 +2074,18 @@ ContainerState::ProcessDisplayItems(cons
       "items in a container layer should all have the same app units per dev pixel");
 
     nsIntRect itemVisibleRect =
       ScaleToOutsidePixels(item->GetVisibleRect(), false);
     bool snap;
     nsRect itemContent = item->GetBounds(mBuilder, &snap);
     nsIntRect itemDrawRect = ScaleToOutsidePixels(itemContent, snap);
     nsIntRect clipRect;
-    if (aClip.mHaveClipRect) {
-      itemContent.IntersectRect(itemContent, aClip.mClipRect);
+    if (aClip.HasClip()) {
+      itemContent.IntersectRect(itemContent, aClip.GetClipRect());
       clipRect = ScaleToNearestPixels(aClip.NonRoundedIntersection());
       itemDrawRect.IntersectRect(itemDrawRect, clipRect);
       clipRect.MoveBy(mParameters.mOffset);
     }
     mBounds.UnionRect(mBounds, itemContent);
     itemVisibleRect.IntersectRect(itemVisibleRect, itemDrawRect);
 
     LayerState layerState = item->GetLayerState(mBuilder, mManager, mParameters);
@@ -2183,21 +2171,21 @@ ContainerState::ProcessDisplayItems(cons
       // fixed layers. This means we need to make sure transform layers are not
       // marked as fixed.
       ownLayer->SetIsFixedPosition(isFixed && type != nsDisplayItem::TYPE_TRANSFORM);
 
       // Update that layer's clip and visible rects.
       NS_ASSERTION(ownLayer->Manager() == mManager, "Wrong manager");
       NS_ASSERTION(!ownLayer->HasUserData(&gLayerManagerUserData),
                    "We shouldn't have a FrameLayerBuilder-managed layer here!");
-      NS_ASSERTION(aClip.mHaveClipRect ||
-                     aClip.mRoundedClipRects.IsEmpty(),
+      NS_ASSERTION(aClip.HasClip() ||
+                   aClip.GetRoundedRectCount() == 0,
                    "If we have rounded rects, we must have a clip rect");
       // It has its own layer. Update that layer's clip and visible rects.
-      if (aClip.mHaveClipRect) {
+      if (aClip.HasClip()) {
         ownLayer->SetClipRect(&clipRect);
       } else {
         ownLayer->SetClipRect(nullptr);
       }
       ThebesLayerData* data = GetTopThebesLayerData();
       if (data) {
         data->mVisibleAboveRegion.Or(data->mVisibleAboveRegion, itemVisibleRect);
         data->mVisibleAboveRegion.SimplifyOutward(4);
@@ -2255,47 +2243,16 @@ ContainerState::ProcessDisplayItems(cons
 
       // check to see if the new item has rounded rect clips in common with
       // other items in the layer
       data->UpdateCommonClipCount(aClip);
     }
   }
 }
 
-/**
- * Combine two clips and returns true if clipping
- * needs to be applied.
- *
- * @param aClip Current clip
- * @param aOldClip Optional clip from previous paint.
- * @param aShift Offet to apply to aOldClip
- * @param aCombined Outparam - Computed clip region
- * @return True if the clip should be applied, false
- *         otherwise.
- */
-static bool ComputeCombinedClip(const DisplayItemClip& aClip,
-                                DisplayItemClip* aOldClip,
-                                const nsPoint& aShift,
-                                nsRegion& aCombined)
-{
-  if (!aClip.mHaveClipRect ||
-      (aOldClip && !aOldClip->mHaveClipRect)) {
-    return false;
-  }
-
-  if (aOldClip) {
-    aCombined = aOldClip->NonRoundedIntersection();
-    aCombined.MoveBy(aShift);
-    aCombined.Or(aCombined, aClip.NonRoundedIntersection());
-  } else {
-    aCombined = aClip.NonRoundedIntersection();
-  }
-  return true;
-}
-
 void
 ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, 
                                          Layer* aNewLayer,
                                          const DisplayItemClip& aClip,
                                          const nsPoint& aTopLeft,
                                          nsDisplayItemGeometry *aGeometry)
 {
   NS_ASSERTION(aItem->GetUnderlyingFrame(),
@@ -2380,17 +2337,17 @@ ContainerState::InvalidateForLayerChange
     combined.Or(combined, invalid);
  
     for (uint32_t i = 0; i < changedFrames.Length(); i++) {
       combined.Or(combined, changedFrames[i]->GetVisualOverflowRect());
     } 
 
     // Restrict invalidation to the clipped region
     nsRegion clip;
-    if (ComputeCombinedClip(aClip, oldClip, shift, clip)) {
+    if (aClip.ComputeRegionInClips(oldClip, shift, &clip)) {
       combined.And(combined, clip);
     }
 #ifdef DEBUG_INVALIDATIONS
     if (!combined.IsEmpty()) {
       printf("Display item type %s(%p) (in layer %p) changed geometry!\n", aItem->Name(), aItem->GetUnderlyingFrame(), aNewLayer);
     }
 #endif
   }
@@ -2424,19 +2381,19 @@ FrameLayerBuilder::AddThebesDisplayItem(
     if (!tempManager) {
       tempManager = new BasicLayerManager();
     }
 
     // We need to grab these before calling AddLayerDisplayItem because it will overwrite them.
     nsRegion clip;
     DisplayItemClip* oldClip = nullptr;
     GetOldLayerFor(aItem, nullptr, &oldClip);
-    hasClip = ComputeCombinedClip(aClip, oldClip, 
-                                  aTopLeft - thebesData->mLastActiveScrolledRootOrigin,
-                                  clip);
+    hasClip = aClip.ComputeRegionInClips(oldClip,
+                                         aTopLeft - thebesData->mLastActiveScrolledRootOrigin,
+                                         &clip);
 
     if (hasClip) {
       intClip = clip.GetBounds().ScaleToOutsidePixels(thebesData->mXScale, 
                                                       thebesData->mYScale, 
                                                       thebesData->mAppUnitsPerDevPixel);
     }
   }
 
@@ -3278,36 +3235,34 @@ FrameLayerBuilder::DrawThebesLayer(Thebe
   visible.ScaleInverseRoundOut(userData->mXScale, userData->mYScale);
 
   for (i = items.Length(); i > 0; --i) {
     ClippedDisplayItem* cdi = &items[i - 1];
 
     NS_ASSERTION(AppUnitsPerDevPixel(cdi->mItem) == appUnitsPerDevPixel,
                  "a thebes layer should contain items only at the same zoom");
 
-    NS_ABORT_IF_FALSE(cdi->mClip.mHaveClipRect ||
-                      cdi->mClip.mRoundedClipRects.IsEmpty(),
+    NS_ABORT_IF_FALSE(cdi->mClip.HasClip() ||
+                      cdi->mClip.GetRoundedRectCount() == 0,
                       "If we have rounded rects, we must have a clip rect");
 
-    if (!cdi->mClip.mHaveClipRect ||
-        (cdi->mClip.mRoundedClipRects.IsEmpty() &&
-         cdi->mClip.mClipRect.Contains(visible.GetBounds()))) {
+    if (!cdi->mClip.IsRectAffectedByClip(visible.GetBounds())) {
       cdi->mItem->RecomputeVisibility(builder, &visible);
       continue;
     }
 
     // Do a little dance to account for the fact that we're clipping
     // to cdi->mClipRect
     nsRegion clipped;
-    clipped.And(visible, cdi->mClip.mClipRect);
+    clipped.And(visible, cdi->mClip.NonRoundedIntersection());
     nsRegion finalClipped = clipped;
     cdi->mItem->RecomputeVisibility(builder, &finalClipped);
     // If we have rounded clip rects, don't subtract from the visible
     // region since we aren't displaying everything inside the rect.
-    if (cdi->mClip.mRoundedClipRects.IsEmpty()) {
+    if (cdi->mClip.GetRoundedRectCount() == 0) {
       nsRegion removed;
       removed.Sub(clipped, finalClipped);
       nsRegion newVisible;
       newVisible.Sub(visible, removed);
       // Don't let the visible region get too complex.
       if (newVisible.GetNumRects() <= 15) {
         visible = newVisible;
       }
@@ -3316,33 +3271,33 @@ FrameLayerBuilder::DrawThebesLayer(Thebe
       cdi->mClip.RemoveRoundedCorners();
     }
   }
 
   nsRefPtr<nsRenderingContext> rc = new nsRenderingContext();
   rc->Init(presContext->DeviceContext(), aContext);
 
   DisplayItemClip currentClip;
-  bool setClipRect = false;
+  bool currentClipIsSetInContext = false;
 
   for (i = 0; i < items.Length(); ++i) {
     ClippedDisplayItem* cdi = &items[i];
 
     if (cdi->mItem->GetVisibleRect().IsEmpty())
       continue;
 
     // If the new desired clip state is different from the current state,
     // update the clip.
-    if (setClipRect != cdi->mClip.mHaveClipRect ||
-        (cdi->mClip.mHaveClipRect && cdi->mClip != currentClip)) {
-      if (setClipRect) {
+    if (currentClipIsSetInContext != cdi->mClip.HasClip() ||
+        (cdi->mClip.HasClip() && cdi->mClip != currentClip)) {
+      if (currentClipIsSetInContext) {
         aContext->Restore();
       }
-      setClipRect = cdi->mClip.mHaveClipRect;
-      if (setClipRect) {
+      currentClipIsSetInContext = cdi->mClip.HasClip();
+      if (currentClipIsSetInContext) {
         currentClip = cdi->mClip;
         aContext->Save();
         NS_ASSERTION(commonClipCount < 100,
           "Maybe you really do have more than a hundred clipping rounded rects, or maybe something has gone wrong.");
         currentClip.ApplyTo(aContext, presContext, commonClipCount);
       }
     }
 
@@ -3370,17 +3325,17 @@ FrameLayerBuilder::DrawThebesLayer(Thebe
   }
 
   {
     ThebesLayerItemsEntry* entry =
       layerBuilder->mThebesLayerItems.GetEntry(aLayer);
     items.SwapElements(entry->mItems);
   }
 
-  if (setClipRect) {
+  if (currentClipIsSetInContext) {
     aContext->Restore();
   }
 
   if (presContext->RefreshDriver()->GetPaintFlashing()) {
     FlashPaint(aContext);
   }
 
   if (!aRegionToInvalidate.IsEmpty()) {
@@ -3445,32 +3400,29 @@ ContainerState::SetupMaskLayer(Layer *aL
   if (thebesData &&
       aRoundedRectClipCount < thebesData->mMaskClipCount) {
     ThebesLayer* thebes = aLayer->AsThebesLayer();
     thebes->InvalidateRegion(thebes->GetValidRegion().GetBounds());
   }
 
   // don't build an unnecessary mask
   nsIntRect layerBounds = aLayer->GetVisibleRegion().GetBounds();
-  if (aClip.mRoundedClipRects.IsEmpty() ||
+  if (aClip.GetRoundedRectCount() == 0 ||
       aRoundedRectClipCount == 0 ||
       layerBounds.IsEmpty()) {
     SetClipCount(thebesData, 0);
     return;
   }
 
   // check if we can re-use the mask layer
   nsRefPtr<ImageLayer> maskLayer =  CreateOrRecycleMaskImageLayerFor(aLayer);
   MaskLayerUserData* userData = GetMaskLayerUserData(maskLayer);
 
   MaskLayerUserData newData;
-  newData.mRoundedClipRects.AppendElements(aClip.mRoundedClipRects);
-  if (aRoundedRectClipCount < newData.mRoundedClipRects.Length()) {
-    newData.mRoundedClipRects.TruncateLength(aRoundedRectClipCount);
-  }
+  aClip.AppendRoundedRects(&newData.mRoundedClipRects, aRoundedRectClipCount);
   newData.mScaleX = mParameters.mXScale;
   newData.mScaleY = mParameters.mYScale;
   newData.mOffset = mParameters.mOffset;
 
   if (*userData == newData) {
     aLayer->SetMaskLayer(maskLayer);
     SetClipCount(thebesData, aRoundedRectClipCount);
     return;