Bug 1373750 - Part 1. Except the bottom layer, recompute clip state of each mask layer by a clear clipState object. draft
authorcku <cku@mozilla.com>
Mon, 25 Sep 2017 15:07:45 +0800
changeset 672046 8d590a34984636c2dd77c6f86def43902756175f
parent 670875 70158e4e215d784d1391db5e517b18727f4b3683
child 672047 a77de114e04a5fd60d851b08f633980675196bb9
push id82133
push userbmo:cku@mozilla.com
push dateThu, 28 Sep 2017 16:48:41 +0000
bugs1373750
milestone58.0a1
Bug 1373750 - Part 1. Except the bottom layer, recompute clip state of each mask layer by a clear clipState object. In nsCSSRendering::PaintStyleImageLayerWithSC, we reuse the same clip-state object, clipState, for all bg/mask layers. We hit this assertion if the border-radius of previous one is not 0, but the the border-radius of the next one is 0. In this condition, clipState.mHasRoundedCorners is false, but clipState.mClippedRadii still stores border-radius information of the previous layer. MozReview-Commit-ID: KyxD0vPnMb9
layout/painting/nsCSSRendering.cpp
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -2148,21 +2148,16 @@ nsCSSRendering::ImageLayerClipState::IsV
 
 /* static */ void
 nsCSSRendering::GetImageLayerClip(const nsStyleImageLayers::Layer& aLayer,
                                   nsIFrame* aForFrame, const nsStyleBorder& aBorder,
                                   const nsRect& aBorderArea, const nsRect& aCallerDirtyRect,
                                   bool aWillPaintBorder, nscoord aAppUnitsPerPixel,
                                   /* out */ ImageLayerClipState* aClipState)
 {
-  aClipState->mHasRoundedCorners = false;
-  aClipState->mHasAdditionalBGClipArea = false;
-  aClipState->mAdditionalBGClipArea.SetEmpty();
-  aClipState->mCustomClip = false;
-
   StyleGeometryBox layerClip = ComputeBoxValue(aForFrame, aLayer.mClip);
   if (IsSVGStyleGeometryBox(layerClip)) {
     MOZ_ASSERT(aForFrame->IsFrameOfType(nsIFrame::eSVG) &&
                !aForFrame->IsSVGOuterSVGFrame());
 
     // The coordinate space of clipArea is svg user space.
     nsRect clipArea =
       nsLayoutUtils::ComputeGeometryBox(aForFrame, layerClip);
@@ -2673,25 +2668,28 @@ nsCSSRendering::PaintStyleImageLayerWith
     // in the cases we need it.
     gfxContextAutoSaveRestore autoSR;
     const nsStyleImageLayers::Layer& layer = layers.mLayers[i];
 
     if (!aParams.bgClipRect) {
       bool isBottomLayer = (i == layers.mImageCount - 1);
       if (currentBackgroundClip != layer.mClip || isBottomLayer) {
         currentBackgroundClip = layer.mClip;
-        // For  the bottom layer, we already called GetImageLayerClip above
-        // and it stored its results in clipState.
-        if (!isBottomLayer) {
+        ImageLayerClipState currentLayerClipState;
+        if (isBottomLayer) {
+          currentLayerClipState = clipState;
+        } else {
+          // For the bottom layer, we already called GetImageLayerClip above
+          // and it stored its results in clipState.
           GetImageLayerClip(layer, aParams.frame,
                             aBorder, aParams.borderArea, aParams.dirtyRect,
                             (aParams.paintFlags & PAINTBG_WILL_PAINT_BORDER),
-                            appUnitsPerPixel, &clipState);
+                            appUnitsPerPixel, &currentLayerClipState);
         }
-        SetupImageLayerClip(clipState, &aRenderingCtx,
+        SetupImageLayerClip(currentLayerClipState, &aRenderingCtx,
                             appUnitsPerPixel, &autoSR);
         if (!clipBorderArea.IsEqualEdges(aParams.borderArea)) {
           // We're drawing the background for the joined continuation boxes
           // so we need to clip that to the slice that we want for this
           // frame.
           gfxRect clip =
             nsLayoutUtils::RectToGfxRect(aParams.borderArea, appUnitsPerPixel);
           autoSR.EnsureSaved(&aRenderingCtx);