blob: 8767deefa2e2c10cd83eb3f374c7a7cf3e8c25e0 [file] [log] [blame]
humper@google.com7c7292c2013-01-04 20:29:03 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
reed@google.comcb88d322013-01-07 21:54:25 +00007
humper@google.com7c7292c2013-01-04 20:29:03 +00008#include "SkBenchmark.h"
9#include "SkCanvas.h"
10#include "SkPaint.h"
11#include "SkRandom.h"
12#include "SkShader.h"
13#include "SkString.h"
14#include "SkBlurMask.h"
15
16#define SMALL SkIntToScalar(2)
17#define REAL SkFloatToScalar(1.5f)
18#define BIG SkIntToScalar(10)
19#define REALBIG SkFloatToScalar(30.5f)
20
21class BlurRectBench: public SkBenchmark {
djsollen@google.comefbe8e92013-02-07 18:58:35 +000022 int fLoopCount;
humper@google.com7c7292c2013-01-04 20:29:03 +000023 SkScalar fRadius;
24 SkString fName;
25
26public:
27 BlurRectBench(void *param, SkScalar rad) : INHERITED(param) {
28 fRadius = rad;
djsollen@google.comefbe8e92013-02-07 18:58:35 +000029
30 if (fRadius > SkIntToScalar(25)) {
31 fLoopCount = 100;
32 } else if (fRadius > SkIntToScalar(5)) {
33 fLoopCount = 1000;
34 } else {
35 fLoopCount = 10000;
36 }
humper@google.com7c7292c2013-01-04 20:29:03 +000037 }
38
39protected:
40 virtual const char* onGetName() {
41 return fName.c_str();
42 }
skia.committer@gmail.com8ae714b2013-01-05 02:02:05 +000043
humper@google.com7c7292c2013-01-04 20:29:03 +000044 SkScalar radius() const {
45 return fRadius;
46 }
skia.committer@gmail.com8ae714b2013-01-05 02:02:05 +000047
reed@google.comcb88d322013-01-07 21:54:25 +000048 void setName(const SkString& name) {
humper@google.com7c7292c2013-01-04 20:29:03 +000049 fName = name;
50 }
51
52 virtual void onDraw(SkCanvas* canvas) {
53 SkPaint paint;
54 this->setupPaint(&paint);
55
56 paint.setAntiAlias(true);
57
reed@google.comcb88d322013-01-07 21:54:25 +000058 SkScalar pad = fRadius*3/2 + SK_Scalar1;
59 SkRect r = SkRect::MakeWH(2 * pad + SK_Scalar1, 2 * pad + SK_Scalar1);
skia.committer@gmail.com8ae714b2013-01-05 02:02:05 +000060
reed@google.comcb88d322013-01-07 21:54:25 +000061 preBenchSetup(r);
skia.committer@gmail.com8ae714b2013-01-05 02:02:05 +000062
djsollen@google.comefbe8e92013-02-07 18:58:35 +000063 for (int i = 0; i < SkBENCHLOOP(fLoopCount); i++) {
reed@google.comcb88d322013-01-07 21:54:25 +000064 makeBlurryRect(r);
humper@google.com7c7292c2013-01-04 20:29:03 +000065 }
66 }
skia.committer@gmail.com8ae714b2013-01-05 02:02:05 +000067
reed@google.comcb88d322013-01-07 21:54:25 +000068 virtual void makeBlurryRect(const SkRect&) = 0;
69 virtual void preBenchSetup(const SkRect&) {}
humper@google.com7c7292c2013-01-04 20:29:03 +000070private:
71 typedef SkBenchmark INHERITED;
72};
73
74
75class BlurRectDirectBench: public BlurRectBench {
76 public:
humper@google.coma99a92c2013-02-20 16:42:06 +000077 BlurRectDirectBench(void *param, SkScalar rad) : INHERITED(param, rad) {
humper@google.com7c7292c2013-01-04 20:29:03 +000078 SkString name;
skia.committer@gmail.com8ae714b2013-01-05 02:02:05 +000079
humper@google.com7c7292c2013-01-04 20:29:03 +000080 if (SkScalarFraction(rad) != 0) {
81 name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad));
82 } else {
humper@google.coma99a92c2013-02-20 16:42:06 +000083 name.printf("blurrect_direct_%d", SkScalarRoundToInt(rad));
humper@google.com7c7292c2013-01-04 20:29:03 +000084 }
skia.committer@gmail.com8ae714b2013-01-05 02:02:05 +000085
reed@google.comcb88d322013-01-07 21:54:25 +000086 setName(name);
humper@google.com7c7292c2013-01-04 20:29:03 +000087 }
88protected:
reed@google.comcb88d322013-01-07 21:54:25 +000089 virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
humper@google.com7c7292c2013-01-04 20:29:03 +000090 SkMask mask;
humper@google.coma99a92c2013-02-20 16:42:06 +000091 SkBlurMask::BlurRect(&mask, r, this->radius(), SkBlurMask::kNormal_Style);
bsalomon@google.com33cdbde2013-01-11 20:54:44 +000092 SkMask::FreeImage(mask.fImage);
humper@google.com7c7292c2013-01-04 20:29:03 +000093 }
humper@google.coma99a92c2013-02-20 16:42:06 +000094private:
95 typedef BlurRectBench INHERITED;
humper@google.com7c7292c2013-01-04 20:29:03 +000096};
97
98class BlurRectSeparableBench: public BlurRectBench {
humper@google.coma99a92c2013-02-20 16:42:06 +000099
humper@google.com7c7292c2013-01-04 20:29:03 +0000100public:
humper@google.coma99a92c2013-02-20 16:42:06 +0000101 BlurRectSeparableBench(void *param, SkScalar rad) : INHERITED(param, rad) {
bsalomon@google.com33cdbde2013-01-11 20:54:44 +0000102 fSrcMask.fImage = NULL;
103 }
104
105 ~BlurRectSeparableBench() {
106 SkMask::FreeImage(fSrcMask.fImage);
humper@google.com7c7292c2013-01-04 20:29:03 +0000107 }
108
109protected:
reed@google.comcb88d322013-01-07 21:54:25 +0000110 virtual void preBenchSetup(const SkRect& r) SK_OVERRIDE {
bsalomon@google.com33cdbde2013-01-11 20:54:44 +0000111 SkMask::FreeImage(fSrcMask.fImage);
112
reed@google.comcb88d322013-01-07 21:54:25 +0000113 r.roundOut(&fSrcMask.fBounds);
humper@google.com7c7292c2013-01-04 20:29:03 +0000114 fSrcMask.fFormat = SkMask::kA8_Format;
reed@google.comcb88d322013-01-07 21:54:25 +0000115 fSrcMask.fRowBytes = fSrcMask.fBounds.width();
116 fSrcMask.fImage = SkMask::AllocImage(fSrcMask.computeTotalImageSize());
skia.committer@gmail.com8ae714b2013-01-05 02:02:05 +0000117
reed@google.comcb88d322013-01-07 21:54:25 +0000118 memset(fSrcMask.fImage, 0xff, fSrcMask.computeTotalImageSize());
humper@google.com7c7292c2013-01-04 20:29:03 +0000119 }
skia.committer@gmail.comd454ec12013-02-21 07:15:03 +0000120
humper@google.coma99a92c2013-02-20 16:42:06 +0000121 SkMask fSrcMask;
122private:
123 typedef BlurRectBench INHERITED;
124};
125
126class BlurRectBoxFilterBench: public BlurRectSeparableBench {
127public:
128 BlurRectBoxFilterBench(void *param, SkScalar rad) : INHERITED(param, rad) {
129 SkString name;
130 if (SkScalarFraction(rad) != 0) {
131 name.printf("blurrect_boxfilter_%.2f", SkScalarToFloat(rad));
132 } else {
133 name.printf("blurrect_boxfilter_%d", SkScalarRoundToInt(rad));
134 }
135 setName(name);
136 }
137
138protected:
skia.committer@gmail.com8ae714b2013-01-05 02:02:05 +0000139
reed@google.comcb88d322013-01-07 21:54:25 +0000140 virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
humper@google.com7c7292c2013-01-04 20:29:03 +0000141 SkMask mask;
humper@google.coma99a92c2013-02-20 16:42:06 +0000142 mask.fImage = NULL;
143 SkBlurMask::BlurSeparable(&mask, fSrcMask, this->radius(),
reed@google.comcb88d322013-01-07 21:54:25 +0000144 SkBlurMask::kNormal_Style,
145 SkBlurMask::kHigh_Quality);
bsalomon@google.com33cdbde2013-01-11 20:54:44 +0000146 SkMask::FreeImage(mask.fImage);
humper@google.com7c7292c2013-01-04 20:29:03 +0000147 }
humper@google.coma99a92c2013-02-20 16:42:06 +0000148private:
149 typedef BlurRectSeparableBench INHERITED;
humper@google.com7c7292c2013-01-04 20:29:03 +0000150};
151
humper@google.coma99a92c2013-02-20 16:42:06 +0000152class BlurRectGaussianBench: public BlurRectSeparableBench {
153public:
154 BlurRectGaussianBench(void *param, SkScalar rad) : INHERITED(param, rad) {
155 SkString name;
156 if (SkScalarFraction(rad) != 0) {
157 name.printf("blurrect_gaussian_%.2f", SkScalarToFloat(rad));
158 } else {
159 name.printf("blurrect_gaussian_%d", SkScalarRoundToInt(rad));
160 }
161 setName(name);
162 }
163
164protected:
165
166 virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
167 SkMask mask;
168 mask.fImage = NULL;
169 SkBlurMask::BlurGroundTruth(&mask, fSrcMask, this->radius(),
170 SkBlurMask::kNormal_Style);
171 SkMask::FreeImage(mask.fImage);
172 }
173private:
174 typedef BlurRectSeparableBench INHERITED;
175};
176
177DEF_BENCH(return new BlurRectBoxFilterBench(p, SMALL);)
178DEF_BENCH(return new BlurRectBoxFilterBench(p, BIG);)
179DEF_BENCH(return new BlurRectBoxFilterBench(p, REALBIG);)
180DEF_BENCH(return new BlurRectBoxFilterBench(p, REAL);)
181DEF_BENCH(return new BlurRectGaussianBench(p, SMALL);)
182DEF_BENCH(return new BlurRectGaussianBench(p, BIG);)
183DEF_BENCH(return new BlurRectGaussianBench(p, REALBIG);)
184DEF_BENCH(return new BlurRectGaussianBench(p, REAL);)
humper@google.com7c7292c2013-01-04 20:29:03 +0000185DEF_BENCH(return new BlurRectDirectBench(p, SMALL);)
186DEF_BENCH(return new BlurRectDirectBench(p, BIG);)
187DEF_BENCH(return new BlurRectDirectBench(p, REALBIG);)
188DEF_BENCH(return new BlurRectDirectBench(p, REAL);)
humper@google.coma99a92c2013-02-20 16:42:06 +0000189
190DEF_BENCH(return new BlurRectDirectBench(p, SkIntToScalar(5));)
191DEF_BENCH(return new BlurRectDirectBench(p, SkIntToScalar(20));)
192
193DEF_BENCH(return new BlurRectBoxFilterBench(p, SkIntToScalar(5));)
194DEF_BENCH(return new BlurRectBoxFilterBench(p, SkIntToScalar(20));)
195
196#if 0
197// disable Gaussian benchmarks; the algorithm works well enough
198// and serves as a baseline for ground truth, but it's too slow
199// to use in production for non-trivial radii, so no real point
200// in having the bots benchmark it all the time.
201
202DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(1));)
203DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(2));)
204DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(3));)
205DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(4));)
206DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(5));)
207DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(6));)
208DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(7));)
209DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(8));)
210DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(9));)
211DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(10));)
212DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(11));)
213DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(12));)
214DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(13));)
215DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(14));)
216DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(15));)
217DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(16));)
218DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(17));)
219DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(18));)
220DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(19));)
221DEF_BENCH(return new BlurRectGaussianBench(p, SkIntToScalar(20));)
222#endif