Backout bug 1188075 for graphical artifacts. r=me a=backout
authorMason Chang <mchang@mozilla.com>
Mon, 21 Sep 2015 08:14:05 -0700
changeset 296116 9087b63b0cd27b6cd2dd80daaa6a5040ed5971ea
parent 296115 577c248da8de42756be578bc4f09301dbc5998b2
child 296117 18d549918ec0939d11906bb6c4371c414373e504
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme, backout
bugs1188075
milestone43.0a2
Backout bug 1188075 for graphical artifacts. r=me a=backout
gfx/thebes/gfx2DGlue.h
gfx/thebes/gfxBlur.cpp
gfx/thebes/gfxBlur.h
layout/base/nsCSSRendering.cpp
layout/base/nsCSSRendering.h
layout/reftests/box-shadow/boxshadow-color-rounding-middle-ref.html
layout/reftests/box-shadow/boxshadow-color-rounding-middle.html
layout/reftests/box-shadow/reftest.list
--- a/gfx/thebes/gfx2DGlue.h
+++ b/gfx/thebes/gfx2DGlue.h
@@ -35,17 +35,17 @@ inline Rect ToRect(const IntRect &aRect)
 }
 
 inline Color ToColor(const gfxRGBA &aRGBA)
 {
   return Color(Float(aRGBA.r), Float(aRGBA.g),
                Float(aRGBA.b), Float(aRGBA.a));
 }
 
-inline gfxRGBA ThebesColor(const Color &aColor)
+inline gfxRGBA ThebesColor(Color &aColor)
 {
   return gfxRGBA(aColor.r, aColor.g, aColor.b, aColor.a);
 }
 
 inline Matrix ToMatrix(const gfxMatrix &aMatrix)
 {
   return Matrix(Float(aMatrix._11), Float(aMatrix._12), Float(aMatrix._21),
                 Float(aMatrix._22), Float(aMatrix._31), Float(aMatrix._32));
--- a/gfx/thebes/gfxBlur.cpp
+++ b/gfx/thebes/gfxBlur.cpp
@@ -165,109 +165,68 @@ struct BlurCacheKey : public PLDHashEntr
   typedef const BlurCacheKey* KeyTypePointer;
   enum { ALLOW_MEMMOVE = true };
 
   IntSize mMinSize;
   IntSize mBlurRadius;
   gfxRGBA mShadowColor;
   BackendType mBackend;
   RectCornerRadii mCornerRadii;
-  bool mIsInset;
 
-  // Only used for inset blurs
-  bool mHasBorderRadius;
-  gfxIntSize mSpreadRadius;
-  IntSize mInnerMinSize;
-
-  BlurCacheKey(IntSize aMinSize, gfxIntSize aBlurRadius,
+  BlurCacheKey(IntSize aMinimumSize, gfxIntSize aBlurRadius,
                RectCornerRadii* aCornerRadii, gfxRGBA aShadowColor,
-               BackendType aBackendType)
-    : BlurCacheKey(aMinSize, IntSize(0, 0),
-                   aBlurRadius, IntSize(0, 0),
-                   aCornerRadii, aShadowColor,
-                   false, false, aBackendType)
-  {}
+               BackendType aBackend)
+    : mMinSize(aMinimumSize)
+    , mBlurRadius(aBlurRadius)
+    , mShadowColor(aShadowColor)
+    , mBackend(aBackend)
+    , mCornerRadii(aCornerRadii ? *aCornerRadii : RectCornerRadii())
+  { }
 
   explicit BlurCacheKey(const BlurCacheKey* aOther)
     : mMinSize(aOther->mMinSize)
     , mBlurRadius(aOther->mBlurRadius)
     , mShadowColor(aOther->mShadowColor)
     , mBackend(aOther->mBackend)
     , mCornerRadii(aOther->mCornerRadii)
-    , mIsInset(aOther->mIsInset)
-    , mHasBorderRadius(aOther->mHasBorderRadius)
-    , mSpreadRadius(aOther->mSpreadRadius)
-    , mInnerMinSize(aOther->mInnerMinSize)
-  { }
-
-  explicit BlurCacheKey(IntSize aOuterMinSize, IntSize aInnerMinSize,
-                        gfxIntSize aBlurRadius, gfxIntSize aSpreadRadius,
-                        const RectCornerRadii* aCornerRadii, gfxRGBA aShadowColor,
-                        bool aIsInset,
-                        bool aHasBorderRadius, BackendType aBackendType)
-    : mMinSize(aOuterMinSize)
-    , mBlurRadius(aBlurRadius)
-    , mShadowColor(aShadowColor)
-    , mBackend(aBackendType)
-    , mCornerRadii(aCornerRadii ? *aCornerRadii : RectCornerRadii())
-    , mIsInset(aIsInset)
-    , mHasBorderRadius(aHasBorderRadius)
-    , mSpreadRadius(aSpreadRadius)
-    , mInnerMinSize(aInnerMinSize)
   { }
 
   static PLDHashNumber
   HashKey(const KeyTypePointer aKey)
   {
     PLDHashNumber hash = 0;
     hash = AddToHash(hash, aKey->mMinSize.width, aKey->mMinSize.height);
     hash = AddToHash(hash, aKey->mBlurRadius.width, aKey->mBlurRadius.height);
 
     hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.r, sizeof(gfxFloat)));
     hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.g, sizeof(gfxFloat)));
     hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.b, sizeof(gfxFloat)));
     hash = AddToHash(hash, HashBytes(&aKey->mShadowColor.a, sizeof(gfxFloat)));
 
     for (int i = 0; i < 4; i++) {
-      hash = AddToHash(hash, aKey->mCornerRadii[i].width, aKey->mCornerRadii[i].height);
+    hash = AddToHash(hash, aKey->mCornerRadii[i].width, aKey->mCornerRadii[i].height);
     }
 
     hash = AddToHash(hash, (uint32_t)aKey->mBackend);
-
-    if (aKey->mIsInset) {
-      hash = AddToHash(hash, aKey->mSpreadRadius.width, aKey->mSpreadRadius.height);
-      hash = AddToHash(hash, aKey->mInnerMinSize.width, aKey->mInnerMinSize.height);
-      hash = AddToHash(hash, HashBytes(&aKey->mHasBorderRadius, sizeof(bool)));
-    }
     return hash;
   }
 
-  bool
-  KeyEquals(KeyTypePointer aKey) const
+  bool KeyEquals(KeyTypePointer aKey) const
   {
     if (aKey->mMinSize == mMinSize &&
         aKey->mBlurRadius == mBlurRadius &&
         aKey->mCornerRadii == mCornerRadii &&
         aKey->mShadowColor == mShadowColor &&
         aKey->mBackend == mBackend) {
-
-      if (mIsInset) {
-        return (mHasBorderRadius == aKey->mHasBorderRadius) &&
-                (mInnerMinSize == aKey->mInnerMinSize) &&
-                (mSpreadRadius == aKey->mSpreadRadius);
-      }
-
       return true;
      }
 
      return false;
   }
-
-  static KeyTypePointer
-  KeyToPointer(KeyType aKey)
+  static KeyTypePointer KeyToPointer(KeyType aKey)
   {
     return &aKey;
   }
 };
 
 /**
  * This class is what is cached. It need to be allocated in an object separated
  * to the cache entry to be able to be tracked by the nsExpirationTracker.
@@ -327,37 +286,16 @@ class BlurCache final : public nsExpirat
                                       aBackendType));
       if (blur) {
         MarkUsed(blur);
       }
 
       return blur;
     }
 
-    BlurCacheData* LookupInsetBoxShadow(const IntSize aOuterMinSize,
-                                        const IntSize aInnerMinSize,
-                                        const gfxIntSize& aBlurRadius,
-                                        const gfxIntSize& aSpreadRadius,
-                                        const RectCornerRadii* aCornerRadii,
-                                        const gfxRGBA& aShadowColor,
-                                        const bool& aHasBorderRadius,
-                                        BackendType aBackendType)
-    {
-      BlurCacheKey key(aOuterMinSize, aInnerMinSize,
-                       aBlurRadius, aSpreadRadius,
-                       aCornerRadii, aShadowColor,
-                       true, aHasBorderRadius, aBackendType);
-      BlurCacheData* blur = mHashEntries.Get(key);
-      if (blur) {
-        MarkUsed(blur);
-      }
-
-      return blur;
-    }
-
     // Returns true if we successfully register the blur in the cache, false
     // otherwise.
     bool RegisterEntry(BlurCacheData* aValue)
     {
       nsresult rv = AddObject(aValue);
       if (NS_FAILED(rv)) {
         // We are OOM, and we cannot track this object. We don't want stall
         // entries in the hash table (since the expiration tracker is responsible
@@ -488,33 +426,33 @@ CreateBlurMask(const IntSize& aRectSize,
 
   MOZ_ASSERT(aSliceBorder.LeftRight() <= expandedMinRect.width);
   MOZ_ASSERT(aSliceBorder.TopBottom() <= expandedMinRect.height);
 
   return result.forget();
 }
 
 static already_AddRefed<SourceSurface>
-CreateBoxShadow(SourceSurface* aBlurMask, const gfxRGBA& aShadowColor)
+CreateBoxShadow(DrawTarget& aDT, SourceSurface* aBlurMask, const gfxRGBA& aShadowColor)
 {
   IntSize blurredSize = aBlurMask->GetSize();
   gfxPlatform* platform = gfxPlatform::GetPlatform();
   RefPtr<DrawTarget> boxShadowDT =
     platform->CreateOffscreenContentDrawTarget(blurredSize, SurfaceFormat::B8G8R8A8);
 
   if (!boxShadowDT) {
     return nullptr;
   }
 
   ColorPattern shadowColor(ToDeviceColor(aShadowColor));
   boxShadowDT->MaskSurface(shadowColor, aBlurMask, Point(0, 0));
   return boxShadowDT->Snapshot();
 }
 
-static SourceSurface*
+SourceSurface*
 GetBlur(DrawTarget& aDT,
         const IntSize& aRectSize,
         const gfxIntSize& aBlurRadius,
         RectCornerRadii* aCornerRadii,
         const gfxRGBA& aShadowColor,
         IntMargin& aExtendDestBy,
         IntMargin& aSlice)
 {
@@ -537,17 +475,17 @@ GetBlur(DrawTarget& aDT,
 
   RefPtr<SourceSurface> blurMask =
     CreateBlurMask(aRectSize, aCornerRadii, aBlurRadius, aExtendDestBy, aSlice, aDT);
 
   if (!blurMask) {
     return nullptr;
   }
 
-  RefPtr<SourceSurface> boxShadow = CreateBoxShadow(blurMask, aShadowColor);
+  RefPtr<SourceSurface> boxShadow = CreateBoxShadow(aDT, blurMask, aShadowColor);
   if (!boxShadow) {
     return nullptr;
   }
 
   CacheBlur(aDT, minSize, aBlurRadius, aCornerRadii, aShadowColor, aExtendDestBy, boxShadow);
   return boxShadow;
 }
 
@@ -598,78 +536,16 @@ DrawCorner(DrawTarget& aDT, SourceSurfac
 {
   if (aSkipRect.Contains(aDest)) {
     return;
   }
 
   aDT.DrawSurface(aSurface, aDest, aSrc);
 }
 
-static void
-DrawBoxShadows(DrawTarget& aDestDrawTarget, SourceSurface* aSourceBlur,
-               Rect aDstOuter, Rect aDstInner, Rect aSrcOuter, Rect aSrcInner,
-               Rect aSkipRect)
-{
-  // Corners: top left, top right, bottom left, bottom right
-  DrawCorner(aDestDrawTarget, aSourceBlur,
-             RectWithEdgesTRBL(aDstOuter.Y(), aDstInner.X(),
-                               aDstInner.Y(), aDstOuter.X()),
-             RectWithEdgesTRBL(aSrcOuter.Y(), aSrcInner.X(),
-                               aSrcInner.Y(), aSrcOuter.X()),
-             aSkipRect);
-
-  DrawCorner(aDestDrawTarget, aSourceBlur,
-             RectWithEdgesTRBL(aDstOuter.Y(), aDstOuter.XMost(),
-                               aDstInner.Y(), aDstInner.XMost()),
-             RectWithEdgesTRBL(aSrcOuter.Y(), aSrcOuter.XMost(),
-                               aSrcInner.Y(), aSrcInner.XMost()),
-             aSkipRect);
-
-  DrawCorner(aDestDrawTarget, aSourceBlur,
-             RectWithEdgesTRBL(aDstInner.YMost(), aDstInner.X(),
-                               aDstOuter.YMost(), aDstOuter.X()),
-             RectWithEdgesTRBL(aSrcInner.YMost(), aSrcInner.X(),
-                               aSrcOuter.YMost(), aSrcOuter.X()),
-             aSkipRect);
-
-  DrawCorner(aDestDrawTarget, aSourceBlur,
-             RectWithEdgesTRBL(aDstInner.YMost(), aDstOuter.XMost(),
-                               aDstOuter.YMost(), aDstInner.XMost()),
-             RectWithEdgesTRBL(aSrcInner.YMost(), aSrcOuter.XMost(),
-                               aSrcOuter.YMost(), aSrcInner.XMost()),
-             aSkipRect);
-
-  // Edges: top, left, right, bottom
-  RepeatOrStretchSurface(aDestDrawTarget, aSourceBlur,
-                         RectWithEdgesTRBL(aDstOuter.Y(), aDstInner.XMost(),
-                                           aDstInner.Y(), aDstInner.X()),
-                         RectWithEdgesTRBL(aSrcOuter.Y(), aSrcInner.XMost(),
-                                           aSrcInner.Y(), aSrcInner.X()),
-                         aSkipRect);
-  RepeatOrStretchSurface(aDestDrawTarget, aSourceBlur,
-                         RectWithEdgesTRBL(aDstInner.Y(), aDstInner.X(),
-                                           aDstInner.YMost(), aDstOuter.X()),
-                         RectWithEdgesTRBL(aSrcInner.Y(), aSrcInner.X(),
-                                           aSrcInner.YMost(), aSrcOuter.X()),
-                         aSkipRect);
-  RepeatOrStretchSurface(aDestDrawTarget, aSourceBlur,
-                         RectWithEdgesTRBL(aDstInner.Y(), aDstOuter.XMost(),
-                                           aDstInner.YMost(), aDstInner.XMost()),
-                         RectWithEdgesTRBL(aSrcInner.Y(), aSrcOuter.XMost(),
-                                           aSrcInner.YMost(), aSrcInner.XMost()),
-                         aSkipRect);
-  RepeatOrStretchSurface(aDestDrawTarget, aSourceBlur,
-                         RectWithEdgesTRBL(aDstInner.YMost(), aDstInner.XMost(),
-                                           aDstOuter.YMost(), aDstInner.X()),
-                         RectWithEdgesTRBL(aSrcInner.YMost(), aSrcInner.XMost(),
-                                           aSrcOuter.YMost(), aSrcInner.X()),
-                         aSkipRect);
-}
-
-
 /***
  * We draw a blurred a rectangle by only blurring a smaller rectangle and
  * splitting the rectangle into 9 parts.
  * First, a small minimum source rect is calculated and used to create a blur
  * mask since the actual blurring itself is expensive. Next, we use the mask
  * with the given shadow color to create a minimally-sized box shadow of the
  * right color. Finally, we cut out the 9 parts from the box-shadow source and
  * paint each part in the right place, stretching the non-corner parts to fill
@@ -717,18 +593,70 @@ gfxAlphaBoxBlur::BlurRectangle(gfxContex
 
   Rect skipRect = ToRect(aSkipRect);
 
   if (srcInner.IsEqualInterior(srcOuter)) {
     MOZ_ASSERT(dstInner.IsEqualInterior(dstOuter));
     // The target rect is smaller than the minimal size so just draw the surface
     destDrawTarget.DrawSurface(boxShadow, dstInner, srcInner);
   } else {
-    DrawBoxShadows(destDrawTarget, boxShadow, dstOuter, dstInner,
-                   srcOuter, srcInner, skipRect);
+    // Corners: top left, top right, bottom left, bottom right
+    DrawCorner(destDrawTarget, boxShadow,
+               RectWithEdgesTRBL(dstOuter.Y(), dstInner.X(),
+                                 dstInner.Y(), dstOuter.X()),
+               RectWithEdgesTRBL(srcOuter.Y(), srcInner.X(),
+                                 srcInner.Y(), srcOuter.X()),
+               skipRect);
+
+    DrawCorner(destDrawTarget, boxShadow,
+               RectWithEdgesTRBL(dstOuter.Y(), dstOuter.XMost(),
+                                 dstInner.Y(), dstInner.XMost()),
+               RectWithEdgesTRBL(srcOuter.Y(), srcOuter.XMost(),
+                                 srcInner.Y(), srcInner.XMost()),
+               skipRect);
+
+    DrawCorner(destDrawTarget, boxShadow,
+               RectWithEdgesTRBL(dstInner.YMost(), dstInner.X(),
+                                 dstOuter.YMost(), dstOuter.X()),
+               RectWithEdgesTRBL(srcInner.YMost(), srcInner.X(),
+                                 srcOuter.YMost(), srcOuter.X()),
+               skipRect);
+
+    DrawCorner(destDrawTarget, boxShadow,
+               RectWithEdgesTRBL(dstInner.YMost(), dstOuter.XMost(),
+                                 dstOuter.YMost(), dstInner.XMost()),
+               RectWithEdgesTRBL(srcInner.YMost(), srcOuter.XMost(),
+                                 srcOuter.YMost(), srcInner.XMost()),
+               skipRect);
+
+    // Edges: top, left, right, bottom
+    RepeatOrStretchSurface(destDrawTarget, boxShadow,
+                           RectWithEdgesTRBL(dstOuter.Y(), dstInner.XMost(),
+                                             dstInner.Y(), dstInner.X()),
+                           RectWithEdgesTRBL(srcOuter.Y(), srcInner.XMost(),
+                                             srcInner.Y(), srcInner.X()),
+                           skipRect);
+    RepeatOrStretchSurface(destDrawTarget, boxShadow,
+                           RectWithEdgesTRBL(dstInner.Y(), dstInner.X(),
+                                             dstInner.YMost(), dstOuter.X()),
+                           RectWithEdgesTRBL(srcInner.Y(), srcInner.X(),
+                                             srcInner.YMost(), srcOuter.X()),
+                           skipRect);
+    RepeatOrStretchSurface(destDrawTarget, boxShadow,
+                           RectWithEdgesTRBL(dstInner.Y(), dstOuter.XMost(),
+                                             dstInner.YMost(), dstInner.XMost()),
+                           RectWithEdgesTRBL(srcInner.Y(), srcOuter.XMost(),
+                                             srcInner.YMost(), srcInner.XMost()),
+                           skipRect);
+    RepeatOrStretchSurface(destDrawTarget, boxShadow,
+                           RectWithEdgesTRBL(dstInner.YMost(), dstInner.XMost(),
+                                             dstOuter.YMost(), dstInner.X()),
+                           RectWithEdgesTRBL(srcInner.YMost(), srcInner.XMost(),
+                                             srcOuter.YMost(), srcInner.X()),
+                           skipRect);
 
     // Middle part
     RepeatOrStretchSurface(destDrawTarget, boxShadow,
                            RectWithEdgesTRBL(dstInner.Y(), dstInner.XMost(),
                                              dstInner.YMost(), dstInner.X()),
                            RectWithEdgesTRBL(srcInner.Y(), srcInner.XMost(),
                                              srcInner.YMost(), srcInner.X()),
                            skipRect);
@@ -749,263 +677,8 @@ gfxAlphaBoxBlur::BlurRectangle(gfxContex
   // will not just fill the pixels that have their pixel center inside the
   // filled shape. Instead, it will fill all the pixels which are partially
   // covered by the shape. So for pixels on the edge between two adjacent parts,
   // all those pixels will be painted to by both parts, which looks very bad.
 
   destDrawTarget.PopClip();
 }
 
-static already_AddRefed<Path>
-GetBoxShadowInsetPath(DrawTarget* aDrawTarget,
-                      const Rect aOuterRect, const Rect aInnerRect,
-                      const bool aHasBorderRadius, const RectCornerRadii& aInnerClipRadii)
-{
-  /***
-   * We create an inset path by having two rects.
-   *
-   *  -----------------------
-   *  |  ________________   |
-   *  | |                |  |
-   *  | |                |  |
-   *  | ------------------  |
-   *  |_____________________|
-   *
-   * The outer rect and the inside rect. The path
-   * creates a frame around the content where we draw the inset shadow.
-   */
-  RefPtr<PathBuilder> builder =
-    aDrawTarget->CreatePathBuilder(FillRule::FILL_EVEN_ODD);
-  AppendRectToPath(builder, aOuterRect, true);
-
-  if (aHasBorderRadius) {
-    AppendRoundedRectToPath(builder, aInnerRect, aInnerClipRadii, false);
-  } else {
-    AppendRectToPath(builder, aInnerRect, false);
-  }
-  return builder->Finish();
-}
-
-static void
-ComputeRectsForInsetBoxShadow(gfxIntSize aBlurRadius,
-                              gfxIntSize aSpreadRadius,
-                              const Rect& aDestRect,
-                              const Rect& aShadowClipRect,
-                              Rect& aOutOuterRect,
-                              Rect& aOutInnerRect,
-                              Margin& aOutPathMargins)
-{
-  gfxIntSize marginSize = aBlurRadius + aSpreadRadius;
-  // The sizes we're given for aBlurRadius/aSpreadRadius are radius'.
-  // We actually want to paint the whole blur, so we need the diameter.
-  // We render both the outer / inner blur portions of a blur,
-  // Then we clip out the outer portion later.
-  aOutPathMargins.SizeTo(marginSize.height, marginSize.width, marginSize.height, marginSize.width);
-  aOutPathMargins += aOutPathMargins;
-
-  aOutOuterRect.x = 0;
-  aOutInnerRect.x = marginSize.width;
-
-  aOutOuterRect.y = 0;
-  aOutInnerRect.y = marginSize.height;
-
-  // + 1 for the middle edges so we can sample them
-  aOutInnerRect.width = aOutPathMargins.LeftRight() + 1;
-  aOutInnerRect.height = aOutPathMargins.TopBottom() + 1;
-
-  // The outer path rect needs to be 1 blur radius past the inner edges
-  aOutOuterRect.width = aOutInnerRect.XMost() + marginSize.width;
-  aOutOuterRect.height = aOutInnerRect.YMost() + marginSize.height;
-
-  if ((aOutOuterRect.width >= aDestRect.width) ||
-      (aOutOuterRect.height >= aDestRect.height) ||
-      (aOutInnerRect.width >= aShadowClipRect.width) ||
-      (aOutInnerRect.height >= aShadowClipRect.height))
-  {
-    aOutOuterRect.width = aDestRect.width;
-    aOutOuterRect.height = aDestRect.height;
-    aOutInnerRect.width = aShadowClipRect.width;
-    aOutInnerRect.height = aShadowClipRect.height;
-    aOutPathMargins.SizeTo(0, 0, 0, 0);
-  }
-}
-
-static void
-FillDestinationPath(gfxContext* aDestinationCtx,
-                    const Rect aDestinationRect,
-                    const Rect aShadowClipRect,
-                    const Color& aShadowColor,
-                    const bool aHasBorderRadius,
-                    const RectCornerRadii& aInnerClipRadii)
-{
-  // When there is no blur radius, fill the path onto the destination
-  // surface.
-  aDestinationCtx->SetColor(ThebesColor(aShadowColor));
-  DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget();
-  RefPtr<Path> shadowPath = GetBoxShadowInsetPath(destDrawTarget, aDestinationRect,
-                                                  aShadowClipRect, aHasBorderRadius,
-                                                  aInnerClipRadii);
-
-  aDestinationCtx->SetPath(shadowPath);
-  aDestinationCtx->Fill();
-}
-
-void
-CacheInsetBlur(const IntSize aMinOuterSize,
-               const IntSize aMinInnerSize,
-               const gfxIntSize& aBlurRadius,
-               const gfxIntSize& aSpreadRadius,
-               const RectCornerRadii* aCornerRadii,
-               const gfxRGBA& aShadowColor,
-               const bool& aHasBorderRadius,
-               BackendType aBackendType,
-               IntMargin aExtendBy,
-               SourceSurface* aBoxShadow)
-{
-  BlurCacheKey key(aMinOuterSize, aMinInnerSize,
-                   aBlurRadius, aSpreadRadius,
-                   aCornerRadii, aShadowColor,
-                   true, aHasBorderRadius, aBackendType);
-  BlurCacheData* data = new BlurCacheData(aBoxShadow, aExtendBy, key);
-  if (!gBlurCache->RegisterEntry(data)) {
-    delete data;
-  }
-}
-
-already_AddRefed<mozilla::gfx::SourceSurface>
-gfxAlphaBoxBlur::GetInsetBlur(Rect& aOuterRect,
-                              Rect& aInnerRect,
-                              const gfxIntSize& aBlurRadius,
-                              const gfxIntSize& aSpreadRadius,
-                              const RectCornerRadii& aInnerClipRadii,
-                              const Color& aShadowColor,
-                              const bool& aHasBorderRadius,
-                              IntPoint& aOutTopLeft,
-                              gfxContext* aDestinationCtx)
-
-{
-  if (!gBlurCache) {
-    gBlurCache = new BlurCache();
-  }
-
-  gfxIntSize outerRectSize = RoundedToInt(aOuterRect).Size();
-  gfxIntSize innerRectSize = RoundedToInt(aInnerRect).Size();
-  DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget();
-
-  BlurCacheData* cached =
-      gBlurCache->LookupInsetBoxShadow(outerRectSize, innerRectSize, aBlurRadius, aSpreadRadius,
-                                       &aInnerClipRadii, ThebesColor(aShadowColor),
-                                       aHasBorderRadius, destDrawTarget->GetBackendType());
-
-  if (cached) {
-    IntMargin extends = cached->mExtendDest;
-    aOutTopLeft.x = extends.left;
-    aOutTopLeft.y = extends.top;
-    // So we don't forget the actual cached blur
-    RefPtr<SourceSurface> cachedBlur = cached->mBlur;
-    return cachedBlur.forget();
-  }
-
-  // Dirty rect and skip rect are null for the min inset shadow.
-  // When rendering inset box shadows, we respect the spread radius by changing
-  // the shape of the unblurred shadow, and can pass a spread radius of zero here.
-  gfxIntSize zeroSpread(0, 0);
-  gfxContext* minGfxContext = Init(ThebesRect(aOuterRect), zeroSpread, aBlurRadius, nullptr, nullptr);
-  if (!minGfxContext) {
-    return nullptr;
-  }
-
-  DrawTarget* minDrawTarget = minGfxContext->GetDrawTarget();
-  RefPtr<Path> maskPath = GetBoxShadowInsetPath(minDrawTarget, aOuterRect,
-                                                aInnerRect, aHasBorderRadius,
-                                                aInnerClipRadii);
-
-  minGfxContext->SetColor(ThebesColor(aShadowColor));
-  minGfxContext->SetPath(maskPath);
-  minGfxContext->Fill();
-
-  RefPtr<SourceSurface> minMask = DoBlur(minDrawTarget, &aOutTopLeft);
-  if (!minMask) {
-    return nullptr;
-  }
-
-  RefPtr<SourceSurface> minInsetBlur = CreateBoxShadow(minMask, ThebesColor(aShadowColor));
-  if (!minInsetBlur) {
-    return nullptr;
-  }
-
-  IntMargin extendBy(aOutTopLeft.y, 0, 0, aOutTopLeft.x);
-  CacheInsetBlur(outerRectSize, innerRectSize,
-                 aBlurRadius, aSpreadRadius,
-                 &aInnerClipRadii, ThebesColor(aShadowColor),
-                 aHasBorderRadius, destDrawTarget->GetBackendType(),
-                 extendBy, minInsetBlur);
-  return minInsetBlur.forget();
-}
-
-/***
- * Blur an inset box shadow by doing:
- * 1) Create a minimal box shadow path that creates a frame.
- * 2) Draw the box shadow portion over the destination surface.
- * 3) The "inset" part is created by a clip rect that properly clips
- *    the alpha mask so that it has clean edges. We still create the full
- *    proper alpha mask, but let the clip deal with the clean edges.
- *
- * All parameters should already be in device pixels.
- */
-void
-gfxAlphaBoxBlur::BlurInsetBox(gfxContext* aDestinationCtx,
-                              const Rect aDestinationRect,
-                              const Rect aShadowClipRect,
-                              const gfxIntSize aBlurRadius,
-                              const gfxIntSize aSpreadRadius,
-                              const Color& aShadowColor,
-                              bool aHasBorderRadius,
-                              const RectCornerRadii& aInnerClipRadii,
-                              const Rect aSkipRect)
-{
-  if ((aBlurRadius.width <= 0 && aBlurRadius.height <= 0)) {
-    // The outer path must be rounded out
-    // If not blurring, we're done now.
-    Rect pathRect(aDestinationRect);
-    pathRect.RoundOut();
-    FillDestinationPath(aDestinationCtx, pathRect, aShadowClipRect,
-        aShadowColor, aHasBorderRadius, aInnerClipRadii);
-    return;
-  }
-
-  DrawTarget* destDrawTarget = aDestinationCtx->GetDrawTarget();
-  Rect outerRect;
-  Rect innerRect;
-  Margin pathMargins;
-  ComputeRectsForInsetBoxShadow(aBlurRadius, aSpreadRadius,
-                                aDestinationRect, aShadowClipRect,
-                                outerRect, innerRect,
-                                pathMargins);
-  IntPoint topLeft;
-  RefPtr<SourceSurface> minInsetBlur = GetInsetBlur(outerRect, innerRect,
-                                                    aBlurRadius, aSpreadRadius,
-                                                    aInnerClipRadii, aShadowColor,
-                                                    aHasBorderRadius,
-                                                    topLeft, aDestinationCtx);
-  if (!minInsetBlur) {
-    return;
-  }
-
-  Rect destRectOuter(aDestinationRect);
-  destRectOuter.RoundIn();
-  Rect destRectInner(destRectOuter);
-  destRectInner.Deflate(pathMargins);
-
-  Rect srcRectOuter(outerRect);
-  srcRectOuter.MoveBy(abs(topLeft.x), abs(topLeft.y));
-  Rect srcRectInner(srcRectOuter);
-  srcRectInner.Deflate(pathMargins);
-
-  if (srcRectOuter.IsEqualInterior(srcRectInner)) {
-    destDrawTarget->DrawSurface(minInsetBlur, destRectOuter, srcRectOuter);
-  } else {
-    DrawBoxShadows(*destDrawTarget, minInsetBlur,
-                   destRectOuter, destRectInner,
-                   srcRectOuter, srcRectInner,
-                   aSkipRect);
- }
-}
--- a/gfx/thebes/gfxBlur.h
+++ b/gfx/thebes/gfxBlur.h
@@ -15,17 +15,16 @@
 
 class gfxContext;
 struct gfxRect;
 struct gfxRGBA;
 
 namespace mozilla {
   namespace gfx {
     class AlphaBoxBlur;
-    struct Color;
     struct RectCornerRadii;
     class SourceSurface;
     class DrawTarget;
   } // namespace gfx
 } // namespace mozilla
 
 /**
  * Implementation of a triple box blur approximation of a Gaussian blur.
@@ -131,54 +130,19 @@ public:
                               RectCornerRadii* aCornerRadii,
                               const gfxPoint& aBlurStdDev,
                               const gfxRGBA& aShadowColor,
                               const gfxRect& aDirtyRect,
                               const gfxRect& aSkipRect);
 
     static void ShutdownBlurCache();
 
-    /***
-     * Blurs an inset box shadow according to a given path.
-     * This is equivalent to calling Init(), drawing the inset path,
-     * and calling paint. Do not call Init() if using this method.
-     *
-     * @param aDestinationCtx     The destination to blur to.
-     * @param aDestinationRect    The destination rect in device pixels
-     * @param aShadowClipRect     The destiniation inner rect of the
-     *                            inset path in device pixels.
-     * @param aBlurRadius         The standard deviation of the blur.
-     * @param aSpreadRadius       The spread radius in device pixels.
-     * @param aShadowColor        The color of the blur.
-     * @param aHasBorderRadius    If this element also has a border radius
-     * @param aInnerClipRadii     Corner radii for the inside rect if it is a rounded rect.
-     * @param aSkipRect           An area in device pixels we don't have to paint in.
-     */
-    void BlurInsetBox(gfxContext* aDestinationCtx,
-                      const mozilla::gfx::Rect aDestinationRect,
-                      const mozilla::gfx::Rect aShadowClipRect,
-                      const gfxIntSize aBlurRadius,
-                      const gfxIntSize aSpreadRadius,
-                      const mozilla::gfx::Color& aShadowColor,
-                      const bool aHasBorderRadius,
-                      const RectCornerRadii& aInnerClipRadii,
-                      const mozilla::gfx::Rect aSkipRect);
+
 
 protected:
-    already_AddRefed<mozilla::gfx::SourceSurface>
-                   GetInsetBlur(mozilla::gfx::Rect& aOuterRect,
-                                mozilla::gfx::Rect& aInnerRect,
-                                const gfxIntSize& aBlurRadius,
-                                const gfxIntSize& aSpreadRadius,
-                                const RectCornerRadii& aInnerClipRadii,
-                                const mozilla::gfx::Color& aShadowColor,
-                                const bool& aHasBorderRadius,
-                                mozilla::gfx::IntPoint& aOutTopLeft,
-                                gfxContext* aDestinationCtx);
-
     /**
      * The context of the temporary alpha surface.
      */
     nsRefPtr<gfxContext> mContext;
 
     /**
      * The temporary alpha surface.
      */
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -1576,47 +1576,63 @@ nsCSSRendering::PaintBoxShadowInner(nsPr
 
     // When there's a blur radius, gfxAlphaBoxBlur leaves the skiprect area
     // unchanged. And by construction the gfxSkipRect is not touched by the
     // rendered shadow (even after blurring), so those pixels must be completely
     // transparent in the shadow, so drawing them changes nothing.
     gfxContext* renderContext = aRenderingContext.ThebesContext();
     DrawTarget* drawTarget = renderContext->GetDrawTarget();
     nsContextBoxBlur blurringArea;
+    gfxContext* shadowContext =
+      blurringArea.Init(shadowPaintRect, 0, blurRadius, twipsPerPixel,
+                        renderContext, aDirtyRect, &skipGfxRect);
+    if (!shadowContext)
+      continue;
+    DrawTarget* shadowDT = shadowContext->GetDrawTarget();
+
+    // shadowContext is owned by either blurringArea or aRenderingContext.
+    MOZ_ASSERT(shadowContext == renderContext ||
+               shadowContext == blurringArea.GetContext());
+
+    // Set the shadow color; if not specified, use the foreground color
+    Color shadowColor = Color::FromABGR(shadowItem->mHasColor ?
+                                          shadowItem->mColor :
+                                          aForFrame->StyleColor()->mColor);
+    renderContext->Save();
+    renderContext->SetColor(ThebesColor(shadowColor));
 
     // Clip the context to the area of the frame's padding rect, so no part of the
     // shadow is painted outside. Also cut out anything beyond where the inset shadow
     // will be.
     Rect shadowGfxRect = NSRectToRect(paddingRect, twipsPerPixel);
     shadowGfxRect.Round();
-
-    // Set the shadow color; if not specified, use the foreground color
-    Color shadowColor = Color::FromABGR(shadowItem->mHasColor ?
-                                          shadowItem->mColor :
-                                          aForFrame->StyleColor()->mColor);
-
-    renderContext->Save();
-
-    // This clips the outside border radius.
-    // clipRectRadii is the border radius inside the inset shadow.
     if (hasBorderRadius) {
       RefPtr<Path> roundedRect =
         MakePathForRoundedRect(*drawTarget, shadowGfxRect, innerRadii);
       renderContext->Clip(roundedRect);
     } else {
       renderContext->Clip(shadowGfxRect);
     }
 
-    nsContextBoxBlur insetBoxBlur;
-    gfxRect destRect = nsLayoutUtils::RectToGfxRect(shadowPaintRect, twipsPerPixel);
-    insetBoxBlur.InsetBoxBlur(renderContext, ToRect(destRect),
-                              shadowClipGfxRect, shadowColor,
-                              blurRadius, spreadDistanceAppUnits,
-                              twipsPerPixel, hasBorderRadius,
-                              clipRectRadii, ToRect(skipGfxRect));
+    // Fill the surface minus the area within the frame that we should
+    // not paint in, and blur and apply it.
+    RefPtr<PathBuilder> builder =
+      shadowDT->CreatePathBuilder(FillRule::FILL_EVEN_ODD);
+    AppendRectToPath(builder, shadowPaintGfxRect, true);
+    if (hasBorderRadius) {
+      AppendRoundedRectToPath(builder, shadowClipGfxRect, clipRectRadii, false);
+    } else {
+      AppendRectToPath(builder, shadowClipGfxRect, false);
+    }
+    RefPtr<Path> path = builder->Finish();
+    shadowContext->SetPath(path);
+    shadowContext->Fill();
+    shadowContext->NewPath();
+
+    blurringArea.DoPaint();
     renderContext->Restore();
   }
 }
 
 DrawResult
 nsCSSRendering::PaintBackground(nsPresContext* aPresContext,
                                 nsRenderingContext& aRenderingContext,
                                 nsIFrame* aForFrame,
@@ -5302,22 +5318,37 @@ nsContextBoxBlur::Init(const nsRect& aRe
                        const gfxRect* aSkipRect,
                        uint32_t aFlags)
 {
   if (aRect.IsEmpty()) {
     mContext = nullptr;
     return nullptr;
   }
 
-  gfxIntSize blurRadius;
-  gfxIntSize spreadRadius;
-  GetBlurAndSpreadRadius(aDestinationCtx, aAppUnitsPerDevPixel,
-                         aBlurRadius, aSpreadRadius,
-                         blurRadius, spreadRadius);
-
+  gfxFloat scaleX = 1;
+  gfxFloat scaleY = 1;
+
+  // Do blurs in device space when possible.
+  // Chrome/Skia always does the blurs in device space
+  // and will sometimes get incorrect results (e.g. rotated blurs)
+  gfxMatrix transform = aDestinationCtx->CurrentMatrix();
+  // XXX: we could probably handle negative scales but for now it's easier just to fallback
+  if (transform.HasNonAxisAlignedTransform() || transform._11 <= 0.0 || transform._22 <= 0.0) {
+    transform = gfxMatrix();
+  } else {
+    scaleX = transform._11;
+    scaleY = transform._22;
+  }
+
+  // compute a large or smaller blur radius
+  gfxIntSize blurRadius = ComputeBlurRadius(aBlurRadius, aAppUnitsPerDevPixel, scaleX, scaleY);
+  gfxIntSize spreadRadius = gfxIntSize(std::min(int32_t(aSpreadRadius * scaleX / aAppUnitsPerDevPixel),
+                                              int32_t(MAX_SPREAD_RADIUS)),
+                                       std::min(int32_t(aSpreadRadius * scaleY / aAppUnitsPerDevPixel),
+                                              int32_t(MAX_SPREAD_RADIUS)));
   mDestinationCtx = aDestinationCtx;
 
   // If not blurring, draw directly onto the destination device
   if (blurRadius.width <= 0 && blurRadius.height <= 0 &&
       spreadRadius.width <= 0 && spreadRadius.height <= 0 &&
       !(aFlags & FORCE_MASK)) {
     mContext = aDestinationCtx;
     return mContext;
@@ -5325,17 +5356,16 @@ nsContextBoxBlur::Init(const nsRect& aRe
 
   // Convert from app units to device pixels
   gfxRect rect = nsLayoutUtils::RectToGfxRect(aRect, aAppUnitsPerDevPixel);
 
   gfxRect dirtyRect =
     nsLayoutUtils::RectToGfxRect(aDirtyRect, aAppUnitsPerDevPixel);
   dirtyRect.RoundOut();
 
-  gfxMatrix transform = aDestinationCtx->CurrentMatrix();
   rect = transform.TransformBounds(rect);
 
   mPreTransformed = !transform.IsIdentity();
 
   // Create the temporary surface for blurring
   dirtyRect = transform.TransformBounds(dirtyRect);
   if (aSkipRect) {
     gfxRect skipRect = transform.TransformBounds(*aSkipRect);
@@ -5352,19 +5382,18 @@ nsContextBoxBlur::Init(const nsRect& aRe
     mContext->Multiply(transform);
   }
   return mContext;
 }
 
 void
 nsContextBoxBlur::DoPaint()
 {
-  if (mContext == mDestinationCtx) {
+  if (mContext == mDestinationCtx)
     return;
-  }
 
   gfxContextMatrixAutoSaveRestore saveMatrix(mDestinationCtx);
 
   if (mPreTransformed) {
     mDestinationCtx->SetMatrix(gfxMatrix());
   }
 
   mAlphaBoxBlur.Paint(mDestinationCtx);
@@ -5452,104 +5481,8 @@ nsContextBoxBlur::BlurRectangle(gfxConte
   gfxAlphaBoxBlur::BlurRectangle(aDestinationCtx,
                                  shadowThebesRect,
                                  aCornerRadii,
                                  blurStdDev,
                                  aShadowColor,
                                  dirtyRect,
                                  skipRect);
 }
-
-/* static */ void
-nsContextBoxBlur::GetBlurAndSpreadRadius(gfxContext* aDestinationCtx,
-                                         int32_t aAppUnitsPerDevPixel,
-                                         nscoord aBlurRadius,
-                                         nscoord aSpreadRadius,
-                                         gfxIntSize& aOutBlurRadius,
-                                         gfxIntSize& aOutSpreadRadius,
-                                         bool aConstrainSpreadRadius)
-{
-  gfxFloat scaleX = 1;
-  gfxFloat scaleY = 1;
-
-  // Do blurs in device space when possible.
-  // Chrome/Skia always does the blurs in device space
-  // and will sometimes get incorrect results (e.g. rotated blurs)
-  gfxMatrix transform = aDestinationCtx->CurrentMatrix();
-  // XXX: we could probably handle negative scales but for now it's easier just to fallback
-  if (transform.HasNonAxisAlignedTransform() || transform._11 <= 0.0 || transform._22 <= 0.0) {
-    transform = gfxMatrix();
-  } else {
-    scaleX = transform._11;
-    scaleY = transform._22;
-  }
-
-  // compute a large or smaller blur radius
-  aOutBlurRadius = ComputeBlurRadius(aBlurRadius, aAppUnitsPerDevPixel, scaleX, scaleY);
-  aOutSpreadRadius =
-      gfxIntSize(int32_t(aSpreadRadius * scaleX / aAppUnitsPerDevPixel),
-                 int32_t(aSpreadRadius * scaleY / aAppUnitsPerDevPixel));
-
-
-  if (aConstrainSpreadRadius) {
-    aOutSpreadRadius.width = std::min(aOutSpreadRadius.width, int32_t(MAX_SPREAD_RADIUS));
-    aOutSpreadRadius.height = std::min(aOutSpreadRadius.height, int32_t(MAX_SPREAD_RADIUS));
-  }
-}
-
-/* static */ bool
-nsContextBoxBlur::InsetBoxBlur(gfxContext* aDestinationCtx,
-                               Rect aDestinationRect,
-                               Rect aShadowClipRect,
-                               Color& aShadowColor,
-                               nscoord aBlurRadiusAppUnits,
-                               nscoord aSpreadDistanceAppUnits,
-                               int32_t aAppUnitsPerDevPixel,
-                               bool aHasBorderRadius,
-                               RectCornerRadii& aInnerClipRectRadii,
-                               Rect aSkipRect)
-{
-  if (aDestinationRect.IsEmpty()) {
-    mContext = nullptr;
-    return false;
-  }
-
-  gfxIntSize blurRadius;
-  gfxIntSize spreadRadius;
-  // Convert the blur and spread radius to device pixels
-  bool constrainSpreadRadius = false;
-  GetBlurAndSpreadRadius(aDestinationCtx, aAppUnitsPerDevPixel,
-                         aBlurRadiusAppUnits, aSpreadDistanceAppUnits,
-                         blurRadius, spreadRadius, constrainSpreadRadius);
-
-  // The blur and spread radius are scaled already, so scale all
-  // input data to the blur. This way, we don't have to scale the min
-  // inset blur to the invert of the dest context, then rescale it back
-  // when we draw to the destination surface.
-  gfxSize scale = aDestinationCtx->CurrentMatrix().ScaleFactors(true);
-  Matrix currentMatrix = ToMatrix(aDestinationCtx->CurrentMatrix());
-
-  Rect transformedDestRect = currentMatrix.TransformBounds(aDestinationRect);
-  Rect transformedShadowClipRect = currentMatrix.TransformBounds(aShadowClipRect);
-  Rect transformedSkipRect = currentMatrix.TransformBounds(aSkipRect);
-
-  transformedDestRect.RoundIn();
-  transformedShadowClipRect.Round();
-  transformedSkipRect.RoundIn();
-
-  for (size_t i = 0; i < 4; i++) {
-    aInnerClipRectRadii[i].width = std::floor(scale.width * aInnerClipRectRadii[i].width);
-    aInnerClipRectRadii[i].height = std::floor(scale.height * aInnerClipRectRadii[i].height);
-  }
-
-  {
-    gfxContextAutoSaveRestore autoRestore(aDestinationCtx);
-    aDestinationCtx->SetMatrix(gfxMatrix());
-
-    mAlphaBoxBlur.BlurInsetBox(aDestinationCtx, transformedDestRect,
-                               transformedShadowClipRect,
-                               blurRadius, spreadRadius,
-                               aShadowColor,
-                               aHasBorderRadius,
-                               aInnerClipRectRadii, transformedSkipRect);
-  }
-  return true;
-}
--- a/layout/base/nsCSSRendering.h
+++ b/layout/base/nsCSSRendering.h
@@ -20,17 +20,16 @@
 class gfxDrawable;
 class nsStyleContext;
 class nsPresContext;
 class nsRenderingContext;
 
 namespace mozilla {
 
 namespace gfx {
-struct Color;
 class DrawTarget;
 } // namespace gfx
 
 namespace layers {
 class ImageContainer;
 } // namespace layers
 
 // A CSSSizeOrRatio represents a (possibly partially specified) size for use
@@ -940,60 +939,20 @@ public:
                             const nsRect& aRect,
                             int32_t aAppUnitsPerDevPixel,
                             RectCornerRadii* aCornerRadii,
                             nscoord aBlurRadius,
                             const gfxRGBA& aShadowColor,
                             const nsRect& aDirtyRect,
                             const gfxRect& aSkipRect);
 
-  /**
-   * Draws a blurred inset box shadow shape onto the destination surface.
-   * Like BlurRectangle, this is equivalent to calling Init(),
-   * drawing a rectangle onto the returned surface
-   * and then calling DoPaint, but may let us optimize better in the
-   * backend.
-   *
-   * @param aDestinationCtx      The destination to blur to.
-   * @param aDestinationRect     The rectangle to blur in app units.
-   * @param aShadowClipRect      The inside clip rect that creates the path.
-   * @param aShadowColor         The color of the blur
-   * @param aBlurRadiusAppUnits  The blur radius in app units
-   * @param aSpreadRadiusAppUnits The spread radius in app units.
-   * @param aAppUnitsPerDevPixel The number of app units in a device pixel,
-   *                             for conversion.  Most of the time you'll
-   *                             pass this from the current PresContext if
-   *                             available.
-   * @param aHasBorderRadius     If this inset box blur has a border radius
-   * @param aInnerClipRectRadii  The clip rect radii used for the inside rect's path.
-   * @param aSkipRect            An area in device pixels (NOT app units!) to avoid
-   *                             blurring over, to prevent unnecessary work.
-   */
-  bool InsetBoxBlur(gfxContext* aDestinationCtx,
-                    mozilla::gfx::Rect aDestinationRect,
-                    mozilla::gfx::Rect aShadowClipRect,
-                    mozilla::gfx::Color& aShadowColor,
-                    nscoord aBlurRadiusAppUnits,
-                    nscoord aSpreadRadiusAppUnits,
-                    int32_t aAppUnitsPerDevPixel,
-                    bool aHasBorderRadius,
-                    RectCornerRadii& aInnerClipRectRadii,
-                    mozilla::gfx::Rect aSkipRect);
-
 protected:
-  static void GetBlurAndSpreadRadius(gfxContext* aContext,
-                                     int32_t aAppUnitsPerDevPixel,
-                                     nscoord aBlurRadius,
-                                     nscoord aSpreadRadius,
-                                     gfxIntSize& aOutBlurRadius,
-                                     gfxIntSize& aOutSpreadRadius,
-                                     bool aConstrainSpreadRadius = true);
-
   gfxAlphaBoxBlur mAlphaBoxBlur;
   nsRefPtr<gfxContext> mContext;
   gfxContext* mDestinationCtx;
 
   /* This is true if the blur already has it's content transformed
    * by mDestinationCtx's transform */
   bool mPreTransformed;
+
 };
 
 #endif /* nsCSSRendering_h___ */
deleted file mode 100644
--- a/layout/reftests/box-shadow/boxshadow-color-rounding-middle-ref.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE html>
-<style>
-#outerDiv {
-  width: 500px;
-  height: 500px;
-  background: lime;
-  position: absolute;
-}
-
-#middleBlur {
-  width: 300px;
-  height: 300px;
-  margin-left: 100px;
-  margin-top: 100px;
-  background: black;
-  box-shadow: inset 0 0 20px 100px lime;
-}
-</style>
-
-<div id="outerDiv">
-  <div id="middleBlur">
-  </div>
-</div>
deleted file mode 100644
--- a/layout/reftests/box-shadow/boxshadow-color-rounding-middle.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<style>
-#thediv {
-  width: 500px;
-  height: 500px;
-  background: black;
-  box-shadow: inset 0 0 20px 200px lime;
-}
-</style>
-
-<div id="thediv"></div>
--- a/layout/reftests/box-shadow/reftest.list
+++ b/layout/reftests/box-shadow/reftest.list
@@ -16,17 +16,16 @@ random-if(layersGPUAccelerated) == boxsh
 random-if(d2d) fuzzy-if(B2G,12,18) == boxshadow-rounded-spread.html boxshadow-rounded-spread-ref.html
 skip-if((B2G&&browserIsRemote)||Mulet) HTTP(..) == boxshadow-dynamic.xul boxshadow-dynamic-ref.xul # Initial mulet triage: parity with B2G/B2G Desktop
 random-if(d2d) == boxshadow-onecorner.html boxshadow-onecorner-ref.html
 random-if(d2d) == boxshadow-twocorners.html boxshadow-twocorners-ref.html
 random-if(d2d) == boxshadow-threecorners.html boxshadow-threecorners-ref.html
 == boxshadow-skiprect.html boxshadow-skiprect-ref.html
 == boxshadow-opacity.html boxshadow-opacity-ref.html
 == boxshadow-color-rounding.html boxshadow-color-rounding-ref.html
-== boxshadow-color-rounding-middle.html boxshadow-color-rounding-middle-ref.html
 
 == overflow-not-scrollable-1.html overflow-not-scrollable-1-ref.html
 == overflow-not-scrollable-1.html overflow-not-scrollable-1-ref2.html
 == overflow-not-scrollable-2.html overflow-not-scrollable-2-ref.html
 fails-if(B2G||Mulet) == 611574-1.html 611574-1-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 fails-if(B2G||Mulet) == 611574-2.html 611574-2-ref.html # Initial mulet triage: parity with B2G/B2G Desktop
 fuzzy-if(winWidget,5,30) == fieldset.html fieldset-ref.html # minor anti-aliasing problem on Windows
 fuzzy-if(winWidget,5,30) == fieldset-inset.html fieldset-inset-ref.html # minor anti-aliasing problem on Windows