Complete the implementation of the faster blur; now supports all blur styles and matches the boxfilter approximation visually.  Also change the interpretation of the blur radius to be sigma/2; need to add SK_IGNORE_BLUR_RADIUS_CORRECTNESS to chromium GYP to avoid immediate layout test failures over there.

Review URL: https://codereview.appspot.com/7307076

git-svn-id: http://skia.googlecode.com/svn/trunk@7793 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/bench/BlurRectBench.cpp b/bench/BlurRectBench.cpp
index a3825be..cbb624c 100644
--- a/bench/BlurRectBench.cpp
+++ b/bench/BlurRectBench.cpp
@@ -74,13 +74,13 @@
 
 class BlurRectDirectBench: public BlurRectBench {
  public:
-    BlurRectDirectBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
+    BlurRectDirectBench(void *param, SkScalar rad) : INHERITED(param, rad) {
         SkString name;
 
         if (SkScalarFraction(rad) != 0) {
             name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad));
         } else {
-            name.printf("blurrect_direct_%d", SkScalarRound(rad));
+            name.printf("blurrect_direct_%d", SkScalarRoundToInt(rad));
         }
 
         setName(name);
@@ -88,23 +88,17 @@
 protected:
     virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
         SkMask mask;
-        SkBlurMask::BlurRect(&mask, r, radius(), SkBlurMask::kNormal_Style,
-                             SkBlurMask::kHigh_Quality);
+        SkBlurMask::BlurRect(&mask, r, this->radius(), SkBlurMask::kNormal_Style);
         SkMask::FreeImage(mask.fImage);
     }
+private:
+    typedef BlurRectBench INHERITED;
 };
 
 class BlurRectSeparableBench: public BlurRectBench {
-    SkMask fSrcMask;
+
 public:
-    BlurRectSeparableBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
-        SkString name;
-        if (SkScalarFraction(rad) != 0) {
-            name.printf("blurrect_separable_%.2f", SkScalarToFloat(rad));
-        } else {
-            name.printf("blurrect_separable_%d", SkScalarRound(rad));
-        }
-        setName(name);
+    BlurRectSeparableBench(void *param, SkScalar rad) : INHERITED(param, rad) {
         fSrcMask.fImage = NULL;
     }
 
@@ -123,21 +117,106 @@
 
         memset(fSrcMask.fImage, 0xff, fSrcMask.computeTotalImageSize());
     }
+    
+    SkMask fSrcMask;
+private:
+    typedef BlurRectBench INHERITED;
+};
+
+class BlurRectBoxFilterBench: public BlurRectSeparableBench {
+public:
+    BlurRectBoxFilterBench(void *param, SkScalar rad) : INHERITED(param, rad) {
+        SkString name;
+        if (SkScalarFraction(rad) != 0) {
+            name.printf("blurrect_boxfilter_%.2f", SkScalarToFloat(rad));
+        } else {
+            name.printf("blurrect_boxfilter_%d", SkScalarRoundToInt(rad));
+        }
+        setName(name);
+    }
+
+protected:
 
     virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
         SkMask mask;
-        SkBlurMask::BlurSeparable(&mask, fSrcMask, radius(),
+        mask.fImage = NULL;
+        SkBlurMask::BlurSeparable(&mask, fSrcMask, this->radius(),
                                   SkBlurMask::kNormal_Style,
                                   SkBlurMask::kHigh_Quality);
         SkMask::FreeImage(mask.fImage);
     }
+private:
+    typedef BlurRectSeparableBench INHERITED;
 };
 
-DEF_BENCH(return new BlurRectSeparableBench(p, SMALL);)
-DEF_BENCH(return new BlurRectSeparableBench(p, BIG);)
-DEF_BENCH(return new BlurRectSeparableBench(p, REALBIG);)
-DEF_BENCH(return new BlurRectSeparableBench(p, REAL);)
+class BlurRectGaussianBench: public BlurRectSeparableBench {
+public:
+    BlurRectGaussianBench(void *param, SkScalar rad) : INHERITED(param, rad) {
+        SkString name;
+        if (SkScalarFraction(rad) != 0) {
+            name.printf("blurrect_gaussian_%.2f", SkScalarToFloat(rad));
+        } else {
+            name.printf("blurrect_gaussian_%d", SkScalarRoundToInt(rad));
+        }
+        setName(name);
+    }
+
+protected:
+
+    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
+        SkMask mask;
+        mask.fImage = NULL;
+        SkBlurMask::BlurGroundTruth(&mask, fSrcMask, this->radius(),
+                                    SkBlurMask::kNormal_Style);
+        SkMask::FreeImage(mask.fImage);
+    }
+private:
+    typedef BlurRectSeparableBench INHERITED;
+};
+
+DEF_BENCH(return new BlurRectBoxFilterBench(p, SMALL);)
+DEF_BENCH(return new BlurRectBoxFilterBench(p, BIG);)
+DEF_BENCH(return new BlurRectBoxFilterBench(p, REALBIG);)
+DEF_BENCH(return new BlurRectBoxFilterBench(p, REAL);)
+DEF_BENCH(return new BlurRectGaussianBench(p, SMALL);)
+DEF_BENCH(return new BlurRectGaussianBench(p, BIG);)
+DEF_BENCH(return new BlurRectGaussianBench(p, REALBIG);)
+DEF_BENCH(return new BlurRectGaussianBench(p, REAL);)
 DEF_BENCH(return new BlurRectDirectBench(p, SMALL);)
 DEF_BENCH(return new BlurRectDirectBench(p, BIG);)
 DEF_BENCH(return new BlurRectDirectBench(p, REALBIG);)
 DEF_BENCH(return new BlurRectDirectBench(p, REAL);)
+
+DEF_BENCH(return new BlurRectDirectBench(p, SkIntToScalar(5));)
+DEF_BENCH(return new BlurRectDirectBench(p, SkIntToScalar(20));)
+
+DEF_BENCH(return new BlurRectBoxFilterBench(p, SkIntToScalar(5));)
+DEF_BENCH(return new BlurRectBoxFilterBench(p, SkIntToScalar(20));)
+
+#if 0
+// disable Gaussian benchmarks; the algorithm works well enough
+// and serves as a baseline for ground truth, but it's too slow
+// to use in production for non-trivial radii, so no real point
+// in having the bots benchmark it all the time.
+
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(1));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(2));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(3));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(4));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(5));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(6));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(7));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(8));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(9));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(10));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(11));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(12));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(13));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(14));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(15));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(16));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(17));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(18));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(19));)
+DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(20));)
+#endif