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