Bug 613659 - Implement box-decoration-break layout for backgrounds. r=cam,jmuizelaar
authorMats Palmgren <matspal@gmail.com>
Mon, 05 May 2014 17:55:54 +0000
changeset 181568 1035f42d8280
parent 181567 fdbe3aa72cdb
child 181569 54ea939d2a1f
push id43092
push usermpalmgren@mozilla.com
push dateMon, 05 May 2014 17:56:10 +0000
treeherdermozilla-inbound@75cafc47ff36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscam, jmuizelaar
bugs613659
milestone32.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 613659 - Implement box-decoration-break layout for backgrounds. r=cam,jmuizelaar
gfx/thebes/gfxContext.h
layout/base/nsCSSRendering.cpp
layout/base/nsCSSRendering.h
layout/base/nsDisplayList.cpp
layout/generic/crashtests/383089-1.html
layout/reftests/backgrounds/background-size-bounding-box.html
layout/reftests/backgrounds/background-size-clone.html
layout/reftests/backgrounds/background-size-continuous.html
layout/reftests/backgrounds/background-size-cover-bounding-box.html
layout/reftests/backgrounds/background-size-cover-clone.html
layout/reftests/backgrounds/background-size-cover-continuous.html
layout/reftests/backgrounds/background-size-cover-each-box.html
layout/reftests/backgrounds/background-size-cover-slice.html
layout/reftests/backgrounds/background-size-each-box.html
layout/reftests/backgrounds/background-size-slice.html
layout/reftests/backgrounds/reftest.list
layout/reftests/bugs/368020-3-ref.html
layout/reftests/bugs/368020-3.html
layout/reftests/bugs/368020-4-ref.html
layout/reftests/bugs/368020-4.html
layout/reftests/bugs/368020-5-ref.html
layout/reftests/bugs/368020-5.html
layout/reftests/bugs/reftest.list
--- a/gfx/thebes/gfxContext.h
+++ b/gfx/thebes/gfxContext.h
@@ -826,24 +826,22 @@ public:
   }
 
   void SetContext(gfxContext *aContext) {
     NS_ASSERTION(!mContext, "Not going to call Restore() on some context!!!");
     mContext = aContext;
     mContext->Save();    
   }
 
-  void Reset(gfxContext *aContext) {
-    // Do the equivalent of destroying and re-creating this object.
-    NS_PRECONDITION(aContext, "must provide a context");
-    if (mContext) {
-      mContext->Restore();
+  void EnsureSaved(gfxContext *aContext) {
+    MOZ_ASSERT(!mContext || mContext == aContext, "wrong context");
+    if (!mContext) {
+        mContext = aContext;
+        mContext->Save();
     }
-    mContext = aContext;
-    mContext->Save();
   }
 
 private:
   gfxContext *mContext;
 };
 
 /**
  * Sentry helper class for functions with multiple return points that need to
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -522,16 +522,28 @@ BoxDecorationRectForBorder(nsIFrame* aFr
   if (!aStyleBorder) {
     aStyleBorder = aFrame->StyleBorder();
   }
   return ::IsBoxDecorationSlice(*aStyleBorder)
            ? ::JoinBoxesForSlice(aFrame, aBorderArea, eForBorder)
            : aBorderArea;
 }
 
+static nsRect
+BoxDecorationRectForBackground(nsIFrame* aFrame, const nsRect& aBorderArea,
+                               const nsStyleBorder* aStyleBorder = nullptr)
+{
+  if (!aStyleBorder) {
+    aStyleBorder = aFrame->StyleBorder();
+  }
+  return ::IsBoxDecorationSlice(*aStyleBorder)
+           ? ::JoinBoxesForSlice(aFrame, aBorderArea, eForBackground)
+           : aBorderArea;
+}
+
 //----------------------------------------------------------------------
 // Thebes Border Rendering Code Start
 
 /*
  * Compute the float-pixel radii that should be used for drawing
  * this border/outline, given the various input bits.
  */
 /* static */ void
@@ -1692,16 +1704,17 @@ GetBackgroundClip(gfxContext *aCtx, uint
                   const gfxCornerSizes& aBGRadii, nscoord aAppUnitsPerPixel,
                   /* out */ BackgroundClipState* aClipState)
 {
   aClipState->mBGClipArea = aBorderArea;
   aClipState->mHasAdditionalBGClipArea = false;
   aClipState->mCustomClip = false;
   aClipState->mRadiiAreOuter = true;
   aClipState->mClippedRadii = aBGRadii;
+
   if (aForFrame->GetType() == nsGkAtoms::scrollFrame &&
         NS_STYLE_BG_ATTACHMENT_LOCAL == aBackgroundAttachment) {
     // As of this writing, this is still in discussion in the CSS Working Group
     // http://lists.w3.org/Archives/Public/www-style/2013Jul/0250.html
 
     // The rectangle for 'background-clip' scrolls with the content,
     // but the background is also clipped at a non-scrolling 'padding-box'
     // like the content. (See below.)
@@ -1790,25 +1803,23 @@ SetupBackgroundClip(BackgroundClipState&
 
   // If we have rounded corners, clip all subsequent drawing to the
   // rounded rectangle defined by bgArea and bgRadii (we don't know
   // whether the rounded corners intrude on the dirtyRect or not).
   // Do not do this if we have a caller-provided clip rect --
   // as above with bgArea, arguably a bug, but table painting seems
   // to depend on it.
 
-  if (aHaveRoundedCorners || aClipState.mHasAdditionalBGClipArea) {
-    aAutoSR->Reset(aCtx);
-  }
-
   if (aClipState.mHasAdditionalBGClipArea) {
     gfxRect bgAreaGfx = nsLayoutUtils::RectToGfxRect(
       aClipState.mAdditionalBGClipArea, aAppUnitsPerPixel);
     bgAreaGfx.Round();
     bgAreaGfx.Condition();
+
+    aAutoSR->EnsureSaved(aCtx);
     aCtx->NewPath();
     aCtx->Rectangle(bgAreaGfx, true);
     aCtx->Clip();
   }
 
   if (aHaveRoundedCorners) {
     gfxRect bgAreaGfx =
       nsLayoutUtils::RectToGfxRect(aClipState.mBGClipArea, aAppUnitsPerPixel);
@@ -1819,16 +1830,17 @@ SetupBackgroundClip(BackgroundClipState&
       // I think it's become possible to hit this since
       // http://hg.mozilla.org/mozilla-central/rev/50e934e4979b landed.
       NS_WARNING("converted background area should not be empty");
       // Make our caller not do anything.
       aClipState.mDirtyRectGfx.SizeTo(gfxSize(0.0, 0.0));
       return;
     }
 
+    aAutoSR->EnsureSaved(aCtx);
     aCtx->NewPath();
     aCtx->RoundedRectangle(bgAreaGfx, aClipState.mClippedRadii, aClipState.mRadiiAreOuter);
     aCtx->Clip();
   }
 }
 
 static void
 DrawBackgroundColor(BackgroundClipState& aClipState, gfxContext *aCtx,
@@ -2593,43 +2605,33 @@ nsCSSRendering::PaintBackgroundWithSC(ns
 
   // At this point, drawBackgroundImage and drawBackgroundColor are
   // true if and only if we are actually supposed to paint an image or
   // color into aDirtyRect, respectively.
   if (!drawBackgroundImage && !drawBackgroundColor)
     return;
 
   // Compute the outermost boundary of the area that might be painted.
-  gfxContext *ctx = aRenderingContext.ThebesContext();
-  nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
-
-  // Same coordinate space as aBorderArea & aBGClipRect
+  // Same coordinate space as aBorderArea & aBGClipRect.
+  nsRect paintBorderArea =
+    ::BoxDecorationRectForBackground(aForFrame, aBorderArea, &aBorder);
+  nsRect clipBorderArea =
+    ::BoxDecorationRectForBorder(aForFrame, aBorderArea, &aBorder);
   gfxCornerSizes bgRadii;
-  bool haveRoundedCorners;
-  {
-    nscoord radii[8];
-    nsSize frameSize = aForFrame->GetSize();
-    if (&aBorder == aForFrame->StyleBorder() &&
-        frameSize == aBorderArea.Size()) {
-      haveRoundedCorners = aForFrame->GetBorderRadii(radii);
-    } else {
-      haveRoundedCorners = nsIFrame::ComputeBorderRadii(aBorder.mBorderRadius,
-                                   frameSize, aBorderArea.Size(),
-                                   aForFrame->GetSkipSides(), radii);
-    }
-    if (haveRoundedCorners)
-      ComputePixelRadii(radii, appUnitsPerPixel, &bgRadii);
-  }
+  bool haveRoundedCorners =
+    ::GetRadii(aForFrame, aBorder, aBorderArea, clipBorderArea, &bgRadii);
 
   // The 'bgClipArea' (used only by the image tiling logic, far below)
   // is the caller-provided aBGClipRect if any, or else the area
   // determined by the value of 'background-clip' in
   // SetupCurrentBackgroundClip.  (Arguably it should be the
   // intersection, but that breaks the table painter -- in particular,
   // taking the intersection breaks reftests/bugs/403249-1[ab].)
+  gfxContext* ctx = aRenderingContext.ThebesContext();
+  nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
   BackgroundClipState clipState;
   uint8_t currentBackgroundClip;
   bool isSolidBorder;
   if (aBGClipRect) {
     clipState.mBGClipArea = *aBGClipRect;
     clipState.mCustomClip = true;
     SetupDirtyRects(clipState.mBGClipArea, aDirtyRect, appUnitsPerPixel,
                     &clipState.mDirtyRect, &clipState.mDirtyRectGfx);
@@ -2649,25 +2651,27 @@ nsCSSRendering::PaintBackgroundWithSC(ns
       // If we have rounded corners, we need to inflate the background
       // drawing area a bit to avoid seams between the border and
       // background.
       currentBackgroundClip = haveRoundedCorners ?
         NS_STYLE_BG_CLIP_MOZ_ALMOST_PADDING : NS_STYLE_BG_CLIP_PADDING;
     }
 
     GetBackgroundClip(ctx, currentBackgroundClip, bg->BottomLayer().mAttachment,
-                      aForFrame, aBorderArea,
+                      aForFrame, clipBorderArea,
                       aDirtyRect, haveRoundedCorners, bgRadii, appUnitsPerPixel,
                       &clipState);
   }
 
   // If we might be using a background color, go ahead and set it now.
   if (drawBackgroundColor && !isCanvasFrame)
     ctx->SetColor(gfxRGBA(bgColor));
 
+  // NOTE: no Save() yet, we do that later by calling autoSR.EnsureSaved(ctx)
+  // in the cases we need it.
   gfxContextAutoSaveRestore autoSR;
 
   // If there is no background image, draw a color.  (If there is
   // neither a background image nor a color, we wouldn't have gotten
   // this far.)
   if (!drawBackgroundImage) {
     if (!isCanvasFrame) {
       DrawBackgroundColor(clipState, ctx, haveRoundedCorners, appUnitsPerPixel);
@@ -2717,38 +2721,49 @@ nsCSSRendering::PaintBackgroundWithSC(ns
             NS_STYLE_BG_CLIP_MOZ_ALMOST_PADDING : NS_STYLE_BG_CLIP_PADDING;
         }
         if (currentBackgroundClip != newBackgroundClip || !clipSet) {
           currentBackgroundClip = newBackgroundClip;
           // If clipSet is false that means this is the bottom layer and we
           // already called GetBackgroundClip above and it stored its results
           // in clipState.
           if (clipSet) {
+            autoSR = gfxContextAutoSaveRestore(); // reset the previous one
             GetBackgroundClip(ctx, currentBackgroundClip, layer.mAttachment, aForFrame,
-                              aBorderArea, aDirtyRect, haveRoundedCorners,
+                              clipBorderArea, aDirtyRect, haveRoundedCorners,
                               bgRadii, appUnitsPerPixel, &clipState);
           }
           SetupBackgroundClip(clipState, ctx, haveRoundedCorners,
                               appUnitsPerPixel, &autoSR);
           clipSet = true;
+          if (!clipBorderArea.IsEqualEdges(aBorderArea)) {
+            // 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(aBorderArea, appUnitsPerPixel);
+            autoSR.EnsureSaved(ctx);
+            ctx->NewPath();
+            ctx->SnappedRectangle(clip);
+            ctx->Clip();
+          }
         }
       }
       if ((aLayer < 0 || i == (uint32_t)startLayer) &&
           !clipState.mDirtyRectGfx.IsEmpty()) {
         nsBackgroundLayerState state = PrepareBackgroundLayer(aPresContext, aForFrame,
-            aFlags, aBorderArea, clipState.mBGClipArea, *bg, layer);
+            aFlags, paintBorderArea, clipState.mBGClipArea, layer);
         if (!state.mFillArea.IsEmpty()) {
           if (state.mCompositingOp != gfxContext::OPERATOR_OVER) {
             NS_ASSERTION(ctx->CurrentOperator() == gfxContext::OPERATOR_OVER,
                          "It is assumed the initial operator is OPERATOR_OVER, when it is restored later");
             ctx->SetOperator(state.mCompositingOp);
           }
           state.mImageRenderer.DrawBackground(aPresContext, aRenderingContext,
                                               state.mDestArea, state.mFillArea,
-                                              state.mAnchor + aBorderArea.TopLeft(),
+                                              state.mAnchor + paintBorderArea.TopLeft(),
                                               clipState.mDirtyRect);
           if (state.mCompositingOp != gfxContext::OPERATOR_OVER) {
             ctx->SetOperator(gfxContext::OPERATOR_OVER);
           }
         }
       }
     }
   }
@@ -2793,60 +2808,48 @@ nsCSSRendering::PaintBackgroundColorWith
 
   NS_ASSERTION(drawBackgroundImage || drawBackgroundColor,
                "Should not be trying to paint a background if we don't have one");
   if (!drawBackgroundColor) {
     return;
   }
 
   // Compute the outermost boundary of the area that might be painted.
-  gfxContext *ctx = aRenderingContext.ThebesContext();
-  nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
-
-  // Same coordinate space as aBorderArea
+  // Same coordinate space as aBorderArea.
+  nsRect clipBorderArea =
+    ::BoxDecorationRectForBorder(aForFrame, aBorderArea, &aBorder);
   gfxCornerSizes bgRadii;
-  bool haveRoundedCorners;
-  {
-    nscoord radii[8];
-    nsSize frameSize = aForFrame->GetSize();
-    if (&aBorder == aForFrame->StyleBorder() &&
-        frameSize == aBorderArea.Size()) {
-      haveRoundedCorners = aForFrame->GetBorderRadii(radii);
-    } else {
-      haveRoundedCorners = nsIFrame::ComputeBorderRadii(aBorder.mBorderRadius,
-                                   frameSize, aBorderArea.Size(),
-                                   aForFrame->GetSkipSides(), radii);
-    }
-    if (haveRoundedCorners)
-      ComputePixelRadii(radii, appUnitsPerPixel, &bgRadii);
-  }
+  bool haveRoundedCorners =
+    ::GetRadii(aForFrame, aBorder, aBorderArea, clipBorderArea, &bgRadii);
 
   // The background is rendered over the 'background-clip' area,
   // which is normally equal to the border area but may be reduced
   // to the padding area by CSS.  Also, if the border is solid, we
   // don't need to draw outside the padding area.  In either case,
   // if the borders are rounded, make sure we use the same inner
   // radii as the border code will.
   // The background-color is drawn based on the bottom
   // background-clip.
+  gfxContext* ctx = aRenderingContext.ThebesContext();
+  nscoord appUnitsPerPixel = aPresContext->AppUnitsPerDevPixel();
   const nsStyleBackground *bg = aBackgroundSC->StyleBackground();
   uint8_t currentBackgroundClip = bg->BottomLayer().mClip;
   bool isSolidBorder =
     (aFlags & PAINTBG_WILL_PAINT_BORDER) && IsOpaqueBorder(aBorder);
   if (isSolidBorder && currentBackgroundClip == NS_STYLE_BG_CLIP_BORDER) {
     // If we have rounded corners, we need to inflate the background
     // drawing area a bit to avoid seams between the border and
     // background.
     currentBackgroundClip = haveRoundedCorners ?
       NS_STYLE_BG_CLIP_MOZ_ALMOST_PADDING : NS_STYLE_BG_CLIP_PADDING;
   }
 
   BackgroundClipState clipState;
   GetBackgroundClip(ctx, currentBackgroundClip, bg->BottomLayer().mAttachment,
-                    aForFrame, aBorderArea,
+                    aForFrame, clipBorderArea,
                     aDirtyRect, haveRoundedCorners, bgRadii, appUnitsPerPixel,
                     &clipState);
 
   ctx->SetColor(gfxRGBA(bgColor));
 
   gfxContextAutoSaveRestore autoSR;
   DrawBackgroundColor(clipState, ctx, haveRoundedCorners, appUnitsPerPixel);
 }
@@ -2861,57 +2864,27 @@ IsTransformed(nsIFrame* aForFrame, nsIFr
   }
   return false;
 }
 
 nsRect
 nsCSSRendering::ComputeBackgroundPositioningArea(nsPresContext* aPresContext,
                                                  nsIFrame* aForFrame,
                                                  const nsRect& aBorderArea,
-                                                 const nsStyleBackground& aBackground,
                                                  const nsStyleBackground::Layer& aLayer,
                                                  nsIFrame** aAttachedToFrame)
 {
   // Compute background origin area relative to aBorderArea now as we may need
   // it to compute the effective image size for a CSS gradient.
-  nsRect bgPositioningArea(0, 0, 0, 0);
+  nsRect bgPositioningArea;
 
   nsIAtom* frameType = aForFrame->GetType();
   nsIFrame* geometryFrame = aForFrame;
-  if (frameType == nsGkAtoms::inlineFrame) {
-    // XXXjwalden Strictly speaking this is not quite faithful to how
-    // background-break is supposed to interact with background-origin values,
-    // but it's a non-trivial amount of work to make it fully conformant, and
-    // until the specification is more finalized (and assuming background-break
-    // even makes the cut) it doesn't make sense to hammer out exact behavior.
-    switch (aBackground.mBackgroundInlinePolicy) {
-    case NS_STYLE_BG_INLINE_POLICY_EACH_BOX:
-      bgPositioningArea = nsRect(nsPoint(0,0), aBorderArea.Size());
-      break;
-    case NS_STYLE_BG_INLINE_POLICY_BOUNDING_BOX:
-      bgPositioningArea = gInlineBGData->GetBoundingRect(aForFrame);
-      break;
-    default:
-      NS_ERROR("Unknown background-inline-policy value!  "
-               "Please, teach me what to do.");
-    case NS_STYLE_BG_INLINE_POLICY_CONTINUOUS:
-      bgPositioningArea = gInlineBGData->GetContinuousRect(aForFrame);
-      break;
-    }
-  } else if (frameType == nsGkAtoms::canvasFrame) {
-    geometryFrame = aForFrame->GetFirstPrincipalChild();
-    // geometryFrame might be null if this canvas is a page created
-    // as an overflow container (e.g. the in-flow content has already
-    // finished and this page only displays the continuations of
-    // absolutely positioned content).
-    if (geometryFrame) {
-      bgPositioningArea = geometryFrame->GetRect();
-    }
-  } else if (frameType == nsGkAtoms::scrollFrame &&
-             NS_STYLE_BG_ATTACHMENT_LOCAL == aLayer.mAttachment) {
+  if (MOZ_UNLIKELY(frameType == nsGkAtoms::scrollFrame &&
+                   NS_STYLE_BG_ATTACHMENT_LOCAL == aLayer.mAttachment)) {
     nsIScrollableFrame* scrollableFrame = do_QueryFrame(aForFrame);
     bgPositioningArea = nsRect(
       scrollableFrame->GetScrolledFrame()->GetPosition()
         // For the dir=rtl case:
         + scrollableFrame->GetScrollRange().TopLeft(),
       scrollableFrame->GetScrolledRect().Size());
     // The ScrolledRect’s size does not include the borders or scrollbars,
     // reverse the handling of background-origin
@@ -2925,30 +2898,40 @@ nsCSSRendering::ComputeBackgroundPositio
       nsMargin padding = geometryFrame->GetUsedPadding();
       geometryFrame->ApplySkipSides(padding);
       bgPositioningArea.Deflate(padding);
       NS_ASSERTION(aLayer.mOrigin == NS_STYLE_BG_ORIGIN_CONTENT,
                    "unknown background-origin value");
     }
     *aAttachedToFrame = aForFrame;
     return bgPositioningArea;
+  }
+
+  if (MOZ_UNLIKELY(frameType == nsGkAtoms::canvasFrame)) {
+    geometryFrame = aForFrame->GetFirstPrincipalChild();
+    // geometryFrame might be null if this canvas is a page created
+    // as an overflow container (e.g. the in-flow content has already
+    // finished and this page only displays the continuations of
+    // absolutely positioned content).
+    if (geometryFrame) {
+      bgPositioningArea = geometryFrame->GetRect();
+    }
   } else {
     bgPositioningArea = nsRect(nsPoint(0,0), aBorderArea.Size());
   }
 
   // Background images are tiled over the 'background-clip' area
   // but the origin of the tiling is based on the 'background-origin' area
   if (aLayer.mOrigin != NS_STYLE_BG_ORIGIN_BORDER && geometryFrame) {
     nsMargin border = geometryFrame->GetUsedBorder();
     if (aLayer.mOrigin != NS_STYLE_BG_ORIGIN_PADDING) {
       border += geometryFrame->GetUsedPadding();
       NS_ASSERTION(aLayer.mOrigin == NS_STYLE_BG_ORIGIN_CONTENT,
                    "unknown background-origin value");
     }
-    geometryFrame->ApplySkipSides(border);
     bgPositioningArea.Deflate(border);
   }
 
   nsIFrame* attachedToFrame = aForFrame;
   if (NS_STYLE_BG_ATTACHMENT_FIXED == aLayer.mAttachment) {
     // If it's a fixed background attachment, then the image is placed
     // relative to the viewport, which is the area of the root frame
     // in a screen context or the page content frame in a print context.
@@ -3022,32 +3005,31 @@ ComputeDrawnSizeForBackground(const CSSS
 }
 
 nsBackgroundLayerState
 nsCSSRendering::PrepareBackgroundLayer(nsPresContext* aPresContext,
                                        nsIFrame* aForFrame,
                                        uint32_t aFlags,
                                        const nsRect& aBorderArea,
                                        const nsRect& aBGClipRect,
-                                       const nsStyleBackground& aBackground,
                                        const nsStyleBackground::Layer& aLayer)
 {
   /*
-   * The background properties we need to keep in mind when drawing background
+   * The properties we need to keep in mind when drawing background
    * layers are:
    *
    *   background-image
    *   background-repeat
    *   background-attachment
    *   background-position
    *   background-clip
    *   background-origin
    *   background-size
-   *   background-break (-moz-background-inline-policy)
    *   background-blend-mode
+   *   box-decoration-break
    *
    * (background-color applies to the entire element and not to individual
    * layers, so it is irrelevant to this method.)
    *
    * These properties have the following dependencies upon each other when
    * determining rendering:
    *
    *   background-image
@@ -3060,32 +3042,31 @@ nsCSSRendering::PrepareBackgroundLayer(n
    *     depends upon background-size (for the image's scaled size) and
    *     background-break (for the background positioning area)
    *   background-clip
    *     no dependencies
    *   background-origin
    *     depends upon background-attachment (only in the case where that value
    *     is 'fixed')
    *   background-size
-   *     depends upon background-break (for the background positioning area for
-   *     resolving percentages), background-image (for the image's intrinsic
+   *     depends upon box-decoration-break (for the background positioning area
+   *     for resolving percentages), background-image (for the image's intrinsic
    *     size), background-repeat (if that value is 'round'), and
    *     background-origin (for the background painting area, when
    *     background-repeat is 'round')
-   *   background-break
-   *     depends upon background-origin (specifying how the boxes making up the
-   *     background positioning area are determined)
+   *   box-decoration-break
+   *     no dependencies
    *
    * As a result of only-if dependencies we don't strictly do a topological
    * sort of the above properties when processing, but it's pretty close to one:
    *
    *   background-clip (by caller)
    *   background-image
-   *   background-break, background-origin
-   *   background-attachment (postfix for background-{origin,break} if 'fixed')
+   *   box-decoration-break, background-origin
+   *   background-attachment (postfix for background-origin if 'fixed')
    *   background-size
    *   background-position
    *   background-repeat
    */
 
   uint32_t irFlags = 0;
   if (aFlags & nsCSSRendering::PAINTBG_SYNC_DECODE_IMAGES) {
     irFlags |= nsImageRenderer::FLAG_SYNC_DECODE_IMAGES;
@@ -3101,17 +3082,17 @@ nsCSSRendering::PrepareBackgroundLayer(n
   }
 
   // The frame to which the background is attached
   nsIFrame* attachedToFrame = aForFrame;
   // Compute background origin area relative to aBorderArea now as we may need
   // it to compute the effective image size for a CSS gradient.
   nsRect bgPositioningArea =
     ComputeBackgroundPositioningArea(aPresContext, aForFrame, aBorderArea,
-                                     aBackground, aLayer, &attachedToFrame);
+                                     aLayer, &attachedToFrame);
 
   // For background-attachment:fixed backgrounds, we'll limit the area
   // where the background can be drawn to the viewport.
   nsRect bgClipRect = aBGClipRect;
 
   // Compute the anchor point.
   //
   // relative to aBorderArea.TopLeft() (which is where the top-left
@@ -3171,23 +3152,23 @@ nsCSSRendering::PrepareBackgroundLayer(n
   return state;
 }
 
 nsRect
 nsCSSRendering::GetBackgroundLayerRect(nsPresContext* aPresContext,
                                        nsIFrame* aForFrame,
                                        const nsRect& aBorderArea,
                                        const nsRect& aClipRect,
-                                       const nsStyleBackground& aBackground,
                                        const nsStyleBackground::Layer& aLayer,
                                        uint32_t aFlags)
 {
+  nsRect borderArea = ::BoxDecorationRectForBackground(aForFrame, aBorderArea);
   nsBackgroundLayerState state =
-      PrepareBackgroundLayer(aPresContext, aForFrame, aFlags, aBorderArea,
-                             aClipRect, aBackground, aLayer);
+      PrepareBackgroundLayer(aPresContext, aForFrame, aFlags, borderArea,
+                             aClipRect, aLayer);
   return state.mFillArea;
 }
 
 /* static */ bool
 nsCSSRendering::IsBackgroundImageDecodedForStyleContextAndLayer(
   const nsStyleBackground *aBackground, uint32_t aLayer)
 {
   const nsStyleImage* image = &aBackground->mLayers[aLayer].mImage;
--- a/layout/base/nsCSSRendering.h
+++ b/layout/base/nsCSSRendering.h
@@ -451,27 +451,25 @@ struct nsCSSRendering {
                            nsIFrame* aFrame,
                            bool& aDrawBackgroundImage,
                            bool& aDrawBackgroundColor);
 
   static nsRect
   ComputeBackgroundPositioningArea(nsPresContext* aPresContext,
                                    nsIFrame* aForFrame,
                                    const nsRect& aBorderArea,
-                                   const nsStyleBackground& aBackground,
                                    const nsStyleBackground::Layer& aLayer,
                                    nsIFrame** aAttachedToFrame);
 
   static nsBackgroundLayerState
   PrepareBackgroundLayer(nsPresContext* aPresContext,
                          nsIFrame* aForFrame,
                          uint32_t aFlags,
                          const nsRect& aBorderArea,
                          const nsRect& aBGClipRect,
-                         const nsStyleBackground& aBackground,
                          const nsStyleBackground::Layer& aLayer);
 
   /**
    * Render the background for an element using css rendering rules
    * for backgrounds.
    */
   enum {
     /**
@@ -537,17 +535,16 @@ struct nsCSSRendering {
    * Returns the rectangle covered by the given background layer image, taking
    * into account background positioning, sizing, and repetition, but not
    * clipping.
    */
   static nsRect GetBackgroundLayerRect(nsPresContext* aPresContext,
                                        nsIFrame* aForFrame,
                                        const nsRect& aBorderArea,
                                        const nsRect& aClipRect,
-                                       const nsStyleBackground& aBackground,
                                        const nsStyleBackground::Layer& aLayer,
                                        uint32_t aFlags);
 
   /**
    * Checks if image in layer aLayer of aBackground is currently decoded.
    */
   static bool IsBackgroundImageDecodedForStyleContextAndLayer(
     const nsStyleBackground *aBackground, uint32_t aLayer);
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1937,24 +1937,18 @@ nsDisplayBackgroundImage::IsSingleFixedP
   uint32_t flags = aBuilder->GetBackgroundPaintFlags();
   nsRect borderArea = nsRect(ToReferenceFrame(), mFrame->GetSize());
   const nsStyleBackground::Layer &layer = mBackgroundStyle->mLayers[mLayer];
 
   if (layer.mAttachment != NS_STYLE_BG_ATTACHMENT_FIXED)
     return false;
 
   nsBackgroundLayerState state =
-    nsCSSRendering::PrepareBackgroundLayer(presContext,
-                                           mFrame,
-                                           flags,
-                                           borderArea,
-                                           aClipRect,
-                                           *mBackgroundStyle,
-                                           layer);
-
+    nsCSSRendering::PrepareBackgroundLayer(presContext, mFrame, flags,
+                                           borderArea, aClipRect, layer);
   nsImageRenderer* imageRenderer = &state.mImageRenderer;
   // We only care about images here, not gradients.
   if (!imageRenderer->IsRasterImage())
     return false;
 
   int32_t appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
   *aDestRect = nsLayoutUtils::RectToGfxRect(state.mFillArea, appUnitsPerDevPixel);
 
@@ -1977,24 +1971,18 @@ nsDisplayBackgroundImage::TryOptimizeToI
     return false;
   }
   nscoord radii[8];
   if (mFrame->GetBorderRadii(radii)) {
     return false;
   }
 
   nsBackgroundLayerState state =
-    nsCSSRendering::PrepareBackgroundLayer(presContext,
-                                           mFrame,
-                                           flags,
-                                           borderArea,
-                                           borderArea,
-                                           *mBackgroundStyle,
-                                           layer);
-
+    nsCSSRendering::PrepareBackgroundLayer(presContext, mFrame, flags,
+                                           borderArea, borderArea, layer);
   nsImageRenderer* imageRenderer = &state.mImageRenderer;
   // We only care about images here, not gradients.
   if (!imageRenderer->IsRasterImage())
     return false;
 
   nsRefPtr<ImageContainer> imageContainer = imageRenderer->GetContainer(aManager);
   // Image is not ready to be made into a layer yet
   if (!imageContainer)
@@ -2256,17 +2244,17 @@ nsDisplayBackgroundImage::GetPositioning
 {
   if (!mBackgroundStyle) {
     return nsRect();
   }
   nsIFrame* attachedToFrame;
   return nsCSSRendering::ComputeBackgroundPositioningArea(
       mFrame->PresContext(), mFrame,
       nsRect(ToReferenceFrame(), mFrame->GetSize()),
-      *mBackgroundStyle, mBackgroundStyle->mLayers[mLayer],
+      mBackgroundStyle->mLayers[mLayer],
       &attachedToFrame) + ToReferenceFrame();
 }
 
 bool
 nsDisplayBackgroundImage::RenderingMightDependOnPositioningAreaSizeChange()
 {
   if (!mBackgroundStyle)
     return false;
@@ -2378,18 +2366,17 @@ nsDisplayBackgroundImage::GetBoundsInter
   nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize());
   nsRect clipRect = borderBox;
   if (mFrame->GetType() == nsGkAtoms::canvasFrame) {
     nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
     clipRect = frame->CanvasArea() + ToReferenceFrame();
   }
   const nsStyleBackground::Layer& layer = mBackgroundStyle->mLayers[mLayer];
   return nsCSSRendering::GetBackgroundLayerRect(presContext, mFrame,
-                                                borderBox, clipRect,
-                                                *mBackgroundStyle, layer,
+                                                borderBox, clipRect, layer,
                                                 aBuilder->GetBackgroundPaintFlags());
 }
 
 uint32_t
 nsDisplayBackgroundImage::GetPerFrameKey()
 {
   return (mLayer << nsDisplayItem::TYPE_BITS) |
     nsDisplayItem::GetPerFrameKey();
--- a/layout/generic/crashtests/383089-1.html
+++ b/layout/generic/crashtests/383089-1.html
@@ -73,14 +73,14 @@ function foo()
 </style>
 
 </head><body onload="setTimeout(olo, 30);">
 
 <br style="overflow: visible;" id="br1">
 <br style="clear: none;" id="br2">
 <br style="height: auto; clear: both; width: auto;" id="br3">
 <br style="position: static;" id="br4">
-<br style="background: yellow none repeat scroll 0% 0%; background-clip: initial; background-origin: initial; -moz-background-inline-policy: initial; display: inline;" id="br5">
+<br style="background: yellow none repeat scroll 0% 0%; background-clip: initial; background-origin: initial; display: inline;" id="br5">
 <br style="width: 1px; visibility: visible;" id="br6">
 <br style="color: black; width: 2px; display: table-cell;" id="br7">
 <table border="1"><tbody><tr style="display: list-item;" id="tableRow"><td>x</td></tr></tbody></table>
 
 </body></html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/background-size-bounding-box.html
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <title>background-break: bounding-box</title>
-  <style type="text/css">
-@font-face
-{
-  font-family: Ahem;
-  src: url(../fonts/Ahem.ttf);
-}
-
-#outer
-{
-  border: 1px solid black;
-  width: 10em;
-}
-#ahem-lines
-{
-  font-family: Ahem;
-  font-size: 32px;
-  white-space: pre;
-  background-image: url(blue-8x20-green-8x20.png);
-  background-repeat: no-repeat;
-  -moz-background-inline-policy: bounding-box;
-}
-</style>
-</head>
-<body>
-<div id="outer">
-<span id="ahem-lines">      <!-- EOL -->
-        <!-- mix it up for each-box and bounding-box --><!-- EOL -->
-      <!-- EOL -->
-      <!-- EOL -->
-      </span></div>
-</body>
-</html>
rename from layout/reftests/backgrounds/background-size-each-box.html
rename to layout/reftests/backgrounds/background-size-clone.html
--- a/layout/reftests/backgrounds/background-size-each-box.html
+++ b/layout/reftests/backgrounds/background-size-clone.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <html>
 <head>
-  <title>background-break: each-box</title>
+  <title>box-decoration-break: clone</title>
   <style type="text/css">
 @font-face
 {
   font-family: Ahem;
   src: url(../fonts/Ahem.ttf);
 }
 
 #outer
@@ -16,21 +16,21 @@
 }
 #ahem-lines
 {
   font-family: Ahem;
   font-size: 32px;
   white-space: pre;
   background-image: url(blue-8x20-green-8x20.png);
   background-repeat: no-repeat;
-  -moz-background-inline-policy: each-box;
+  box-decoration-break: clone;
 }
 </style>
 </head>
 <body>
 <div id="outer">
 <span id="ahem-lines">      <!-- EOL -->
-        <!-- mix it up for each-box and bounding-box --><!-- EOL -->
+        <!-- mix it up for clone --><!-- EOL -->
       <!-- EOL -->
       <!-- EOL -->
       </span></div>
 </body>
 </html>
deleted file mode 100644
--- a/layout/reftests/backgrounds/background-size-cover-bounding-box.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-  <title>background-size: cover; background-break: bounding-box</title>
-  <style type="text/css">
-@font-face
-{
-  font-family: Ahem;
-  src: url(../fonts/Ahem.ttf);
-}
-
-#outer
-{
-  border: 1px solid black;
-  width: 10em;
-}
-#ahem-lines
-{
-  font-family: Ahem;
-  font-size: 32px;
-  white-space: pre;
-  background-image: url(blue-8x20-green-8x20.png);
-  background-repeat: no-repeat;
-  background-size: cover;
-  -moz-background-inline-policy: bounding-box;
-}
-</style>
-</head>
-<body>
-<div id="outer">
-<span id="ahem-lines">      <!-- EOL -->
-        <!-- mix it up for each-box and bounding-box --><!-- EOL -->
-      <!-- EOL -->
-      <!-- EOL -->
-      </span></div>
-</body>
-</html>
rename from layout/reftests/backgrounds/background-size-cover-each-box.html
rename to layout/reftests/backgrounds/background-size-cover-clone.html
--- a/layout/reftests/backgrounds/background-size-cover-each-box.html
+++ b/layout/reftests/backgrounds/background-size-cover-clone.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <html>
 <head>
-  <title>background-size: cover; background-break: each-box</title>
+  <title>background-size: cover; box-decoration-break: clone</title>
   <style type="text/css">
 @font-face
 {
   font-family: Ahem;
   src: url(../fonts/Ahem.ttf);
 }
 
 #outer
@@ -17,21 +17,21 @@
 #ahem-lines
 {
   font-family: Ahem;
   font-size: 32px;
   white-space: pre;
   background-image: url(blue-8x20-green-8x20.png);
   background-repeat: no-repeat;
   background-size: cover;
-  -moz-background-inline-policy: each-box;
+  box-decoration-break: clone;
 }
 </style>
 </head>
 <body>
 <div id="outer">
 <span id="ahem-lines">      <!-- EOL -->
-        <!-- mix it up for each-box and bounding-box --><!-- EOL -->
+        <!-- mix it up for clone --><!-- EOL -->
       <!-- EOL -->
       <!-- EOL -->
       </span></div>
 </body>
 </html>
rename from layout/reftests/backgrounds/background-size-cover-continuous.html
rename to layout/reftests/backgrounds/background-size-cover-slice.html
--- a/layout/reftests/backgrounds/background-size-cover-continuous.html
+++ b/layout/reftests/backgrounds/background-size-cover-slice.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <html>
 <head>
-  <title>background-size: cover; background-break: continuous</title>
+  <title>background-size: cover; box-decoration-break: slice</title>
   <style type="text/css">
 @font-face
 {
   font-family: Ahem;
   src: url(../fonts/Ahem.ttf);
 }
 
 #outer
@@ -17,21 +17,21 @@
 #ahem-lines
 {
   font-family: Ahem;
   font-size: 32px;
   white-space: pre;
   background-image: url(blue-8x20-green-8x20.png);
   background-repeat: no-repeat;
   background-size: cover;
-  -moz-background-inline-policy: continuous;
+  box-decoration-break: slice;
 }
 </style>
 </head>
 <body>
 <div id="outer">
 <span id="ahem-lines">      <!-- EOL -->
-        <!-- mix it up for each-box and bounding-box --><!-- EOL -->
+        <!-- mix it up for slice --><!-- EOL -->
       <!-- EOL -->
       <!-- EOL -->
       </span></div>
 </body>
 </html>
rename from layout/reftests/backgrounds/background-size-continuous.html
rename to layout/reftests/backgrounds/background-size-slice.html
--- a/layout/reftests/backgrounds/background-size-continuous.html
+++ b/layout/reftests/backgrounds/background-size-slice.html
@@ -1,12 +1,12 @@
 <!DOCTYPE html>
 <html>
 <head>
-  <title>background-break: continuous</title>
+  <title>box-decoration-break: slice</title>
   <style type="text/css">
 @font-face
 {
   font-family: Ahem;
   src: url(../fonts/Ahem.ttf);
 }
 
 #outer
@@ -16,21 +16,21 @@
 }
 #ahem-lines
 {
   font-family: Ahem;
   font-size: 32px;
   white-space: pre;
   background-image: url(blue-8x20-green-8x20.png);
   background-repeat: no-repeat;
-  -moz-background-inline-policy: continuous;
+  box-decoration-break: slice;
 }
 </style>
 </head>
 <body>
 <div id="outer">
 <span id="ahem-lines">      <!-- EOL -->
-        <!-- mix it up for each-box and bounding-box --><!-- EOL -->
+        <!-- mix it up for slice --><!-- EOL -->
       <!-- EOL -->
       <!-- EOL -->
       </span></div>
 </body>
 </html>
--- a/layout/reftests/backgrounds/reftest.list
+++ b/layout/reftests/backgrounds/reftest.list
@@ -85,29 +85,25 @@ fails-if(smallScreen&&Android) != backgr
 == background-size-contain-clip-border.html background-size-contain-clip-border-ref.html
 == background-size-contain-position-fifty-fifty.html background-size-contain-position-fifty-fifty-ref.html
 == background-size-contain-clip-padding-origin-border.html background-size-contain-clip-padding-origin-border-ref.html
 == background-size-contain-clip-padding-origin-border-padding.html background-size-contain-clip-padding-origin-border-padding-ref.html
 
 skip-if(B2G) == background-layers-1a.html background-layers-1-ref.html # bug 773482
 == background-layers-1b.html background-layers-1-ref.html
 
-# -moz-background-inline-policy is touchy and hard to test due to stretching
-# artifacts and the difficulty of covering exact lines, and its CSS3 analog is
-# on the chopping block at the moment, so just make sure background-size results
-# in a different rendering when present.
-!= background-size-cover-continuous.html background-size-continuous.html
-!= background-size-cover-each-box.html background-size-each-box.html
-!= background-size-cover-bounding-box.html background-size-bounding-box.html
+# box-decoration-break's effect on backgrounds is touchy and hard to test due to stretching
+# artifacts and the difficulty of covering exact lines, so just make sure
+# background-size results in a different rendering when present.
+pref(layout.css.box-decoration-break.enabled,true) != background-size-cover-slice.html background-size-slice.html
+pref(layout.css.box-decoration-break.enabled,true) != background-size-cover-clone.html background-size-clone.html
 
 # ...and make sure each rendering with background-size is different from the
-# others
-!= background-size-cover-continuous.html background-size-cover-each-box.html
-!= background-size-cover-continuous.html background-size-cover-bounding-box.html
-!= background-size-cover-each-box.html background-size-cover-bounding-box.html
+# other
+pref(layout.css.box-decoration-break.enabled,true) != background-size-cover-slice.html background-size-cover-clone.html
 
 == background-size-monster-ch.html background-size-monster-ref.html
 == background-size-monster-cm.html background-size-monster-ref.html
 == background-size-monster-em.html background-size-monster-ref.html
 == background-size-monster-ex.html background-size-monster-ref.html
 == background-size-monster-inches.html background-size-monster-ref.html
 == background-size-monster-mm.html background-size-monster-ref.html
 == background-size-monster-pc.html background-size-monster-ref.html
--- a/layout/reftests/bugs/368020-3-ref.html
+++ b/layout/reftests/bugs/368020-3-ref.html
@@ -1,15 +1,15 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <title>Testcase, bug 368020</title>
 </head>
 <body style="line-height: 3; width: 500px; height: 250px;">
 
-    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: border-box; background-clip: border; background-origin: padding-box; background-origin: padding; margin: 7px 4px 2px 18px; border: 6px transparent solid; border-width: 2px 10px 15px 2px; -moz-background-inline-policy: continuous; background-inline-policy: continuous;">
+    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: border-box; background-clip: border; background-origin: padding-box; background-origin: padding; margin: 7px 4px 2px 18px; border: 6px transparent solid; border-width: 2px 10px 15px 2px;">
         blah<br>
         blah<br>
         blah
     </span>
 
 </body>
 </html>
--- a/layout/reftests/bugs/368020-3.html
+++ b/layout/reftests/bugs/368020-3.html
@@ -1,15 +1,15 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <title>Testcase, bug 368020</title>
 </head>
 <body style="line-height: 3; width: 500px; height: 250px;">
 
-    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: content-box; background-origin: content; border: medium transparent solid; border-width: 7px 4px 2px 18px; padding: 2px 2% 3% 2px; -moz-background-inline-policy: continuous; background-inline-policy: continuous;">
+    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: content-box; background-origin: content; border: medium transparent solid; border-width: 7px 4px 2px 18px; padding: 2px 2% 3% 2px;">
         blah<br>
         blah<br>
         blah
     </span>
 
 </body>
 </html>
deleted file mode 100644
--- a/layout/reftests/bugs/368020-4-ref.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<title>Testcase, bug 368020</title>
-</head>
-<body style="line-height: 3; width: 500px; height: 250px;">
-
-    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: border-box; background-clip: border; background-origin: padding-box; background-origin: padding; margin: 7px 4px 2px 18px; border: 6px transparent solid; border-width: 2px 10px 15px 2px; -moz-background-inline-policy: bounding-box; background-inline-policy: bounding-box;">
-        blah<br>
-        blah<br>
-        blah
-    </span>
-
-</body>
-</html>
deleted file mode 100644
--- a/layout/reftests/bugs/368020-4.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<title>Testcase, bug 368020</title>
-</head>
-<body style="line-height: 3; width: 500px; height: 250px;">
-
-    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: content-box; background-origin: content; border: medium transparent solid; border-width: 7px 4px 2px 18px; padding: 2px 2% 3% 2px; -moz-background-inline-policy: bounding-box; background-inline-policy: bounding-box;">
-        blah<br>
-        blah<br>
-        blah
-    </span>
-
-</body>
-</html>
--- a/layout/reftests/bugs/368020-5-ref.html
+++ b/layout/reftests/bugs/368020-5-ref.html
@@ -1,15 +1,15 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <title>Testcase, bug 368020</title>
 </head>
 <body style="line-height: 3; width: 500px; height: 250px;">
 
-    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: border-box; background-clip: border; background-origin: padding-box; background-origin: padding; margin: 7px 4px 2px 18px; border: 6px transparent solid; border-width: 2px 10px 15px 2px; -moz-background-inline-policy: each-box; background-inline-policy: each-box;">
+    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: border-box; background-clip: border; background-origin: padding-box; background-origin: padding; margin: 7px 4px 2px 18px; border: 6px transparent solid; border-width: 2px 10px 15px 2px; box-decoration-break: clone;">
         blah<br>
         blah<br>
         blah
     </span>
 
 </body>
 </html>
--- a/layout/reftests/bugs/368020-5.html
+++ b/layout/reftests/bugs/368020-5.html
@@ -1,15 +1,15 @@
 <!DOCTYPE HTML>
 <html>
 <head>
 <title>Testcase, bug 368020</title>
 </head>
 <body style="line-height: 3; width: 500px; height: 250px;">
 
-    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: content-box; background-origin: content; border: medium transparent solid; border-width: 7px 4px 2px 18px; padding: 2px 10px 15px 2px; -moz-background-inline-policy: each-box; background-inline-policy: each-box;">
+    <span style="background: url(repeatable-diagonal-gradient.png); background-clip: padding-box; background-clip: padding; background-origin: content-box; background-origin: content; border: medium transparent solid; border-width: 7px 4px 2px 18px; padding: 2px 10px 15px 2px; box-decoration-break: clone;">
         blah<br>
         blah<br>
         blah
     </span>
 
 </body>
 </html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -591,18 +591,17 @@ skip-if(B2G) == 367247-l-scroll.html 367
 == 367612-1c.html 367612-1-ref.html
 == 367612-1d.html 367612-1-ref.html
 == 367612-1e.html 367612-1-ref.html
 == 367612-1f.html 367612-1-ref.html
 != 367612-1g.html 367612-1-ref.html
 skip-if(B2G) random-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == 368020-1.html 368020-1-ref.html
 == 368020-2.html 368020-2-ref.html
 fails == 368020-3.html 368020-3-ref.html # bug 368085
-fails == 368020-4.html 368020-4-ref.html # bug 368085
-== 368020-5.html 368020-5-ref.html
+pref(layout.css.box-decoration-break.enabled,true) == 368020-5.html 368020-5-ref.html
 == 368155-1.xhtml 368155-1-ref.xhtml
 asserts(4) == 368155-negative-margins-1.html 368155-negative-margins-1-ref.html # bug 387205 / bug 457397
 # we can't test this because there's antialiasing involved, and our comparison
 # is too exact
 # == 368247-1.html 368247-1-ref.html
 == 368247-2.html 368247-2-ref.html
 == 368504-1.html 368504-1-ref.html
 == 368504-2.html 368504-2-ref.html