Bug 1259621 - use AlphaBoxBlur in DrawTargetSkia::DrawSurfaceWithShadow. r=mchang
authorLee Salzman <lsalzman@mozilla.com>
Fri, 25 Mar 2016 22:14:50 -0400
changeset 290551 604371ad19b0b60ca45f801b846e67f9f71f4264
parent 290550 f3d7946a5cb969f875790b8685092b841985d320
child 290552 170088059bf79fd3f43eb3ec77b062f6e6ba9e99
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmchang
bugs1259621
milestone48.0a1
Bug 1259621 - use AlphaBoxBlur in DrawTargetSkia::DrawSurfaceWithShadow. r=mchang
gfx/2d/DrawTargetSkia.cpp
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -12,16 +12,17 @@
 #include "HelpersSkia.h"
 
 #include "skia/include/core/SkSurface.h"
 #include "skia/include/core/SkTypeface.h"
 #include "skia/include/effects/SkGradientShader.h"
 #include "skia/include/core/SkColorFilter.h"
 #include "skia/include/effects/SkBlurImageFilter.h"
 #include "skia/include/effects/SkLayerRasterizer.h"
+#include "Blur.h"
 #include "Logging.h"
 #include "Tools.h"
 #include "DataSurfaceHelpers.h"
 #include <algorithm>
 
 #ifdef USE_SKIA_GPU
 #include "GLDefs.h"
 #include "skia/include/gpu/SkGr.h"
@@ -427,26 +428,47 @@ DrawTargetSkia::DrawSurfaceWithShadow(So
   // We can't use the SkDropShadowImageFilter here because it applies the xfer
   // mode first to render the bitmap to a temporary layer, and then implicitly
   // uses src-over to composite the resulting shadow.
   // The canvas spec, however, states that the composite op must be used to
   // composite the resulting shadow, so we must instead use a SkBlurImageFilter
   // to blur the image ourselves.
 
   SkPaint shadowPaint;
-  SkAutoTUnref<SkImageFilter> blurFilter(SkBlurImageFilter::Create(aSigma, aSigma));
-  SkAutoTUnref<SkColorFilter> colorFilter(
-    SkColorFilter::CreateModeFilter(ColorToSkColor(aColor, 1.0), SkXfermode::kSrcIn_Mode));
-
   shadowPaint.setXfermode(paint.getXfermode());
-  shadowPaint.setImageFilter(blurFilter.get());
-  shadowPaint.setColorFilter(colorFilter.get());
 
   IntPoint shadowDest = RoundedToInt(aDest + aOffset);
-  mCanvas->drawBitmap(bitmap, shadowDest.x, shadowDest.y, &shadowPaint);
+
+  SkBitmap blurMask;
+  if (!UsingSkiaGPU() &&
+      bitmap.extractAlpha(&blurMask)) {
+    // Prefer using our own box blur instead of Skia's when we're
+    // not using the GPU. It currently performs much better than
+    // SkBlurImageFilter or SkBlurMaskFilter on the CPU.
+    AlphaBoxBlur blur(Rect(0, 0, blurMask.width(), blurMask.height()),
+                      int32_t(blurMask.rowBytes()),
+                      aSigma, aSigma);
+    blurMask.lockPixels();
+    blur.Blur(reinterpret_cast<uint8_t*>(blurMask.getPixels()));
+    blurMask.unlockPixels();
+    blurMask.notifyPixelsChanged();
+
+    shadowPaint.setColor(ColorToSkColor(aColor, 1.0f));
+
+    mCanvas->drawBitmap(blurMask, shadowDest.x, shadowDest.y, &shadowPaint);
+  } else {
+    SkAutoTUnref<SkImageFilter> blurFilter(SkBlurImageFilter::Create(aSigma, aSigma));
+    SkAutoTUnref<SkColorFilter> colorFilter(
+      SkColorFilter::CreateModeFilter(ColorToSkColor(aColor, 1.0f), SkXfermode::kSrcIn_Mode));
+
+    shadowPaint.setImageFilter(blurFilter.get());
+    shadowPaint.setColorFilter(colorFilter.get());
+
+    mCanvas->drawBitmap(bitmap, shadowDest.x, shadowDest.y, &shadowPaint);
+  }
 
   // Composite the original image after the shadow
   IntPoint dest = RoundedToInt(aDest);
   mCanvas->drawBitmap(bitmap, dest.x, dest.y, &paint);
 
   mCanvas->restore();
 }