BlurRectBench.cpp revision d454ec135eeef48edea7ebc47a61ff39bd654576
12363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver/*
22363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver * Copyright 2013 Google Inc.
32363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver *
42363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver * Use of this source code is governed by a BSD-style license that can be
52363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver * found in the LICENSE file.
62363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver */
72363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver
82363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkBenchmark.h"
92363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkCanvas.h"
102363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkPaint.h"
112363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkRandom.h"
122363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkShader.h"
132363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkString.h"
142363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#include "SkBlurMask.h"
152363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver
162363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#define SMALL   SkIntToScalar(2)
172363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#define REAL    SkFloatToScalar(1.5f)
182363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#define BIG     SkIntToScalar(10)
192363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver#define REALBIG SkFloatToScalar(30.5f)
202363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver
212363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruverclass BlurRectBench: public SkBenchmark {
222363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver    int         fLoopCount;
232363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver    SkScalar    fRadius;
242363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver    SkString    fName;
252363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver
262363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruverpublic:
272363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver    BlurRectBench(void *param, SkScalar rad) : INHERITED(param) {
282363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver        fRadius = rad;
292363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver
302363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver        if (fRadius > SkIntToScalar(25)) {
312363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver            fLoopCount = 100;
322363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver        } else if (fRadius > SkIntToScalar(5)) {
332363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver            fLoopCount = 1000;
342363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver        } else {
352363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver            fLoopCount = 10000;
362363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver        }
372363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver    }
382363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver
392363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruverprotected:
402363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver    virtual const char* onGetName() {
41d7cd52308e6120e6750c4f46d7357e8e5033619cBen Gruver        return fName.c_str();
422363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver    }
43d7cd52308e6120e6750c4f46d7357e8e5033619cBen Gruver
442363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver    SkScalar radius() const {
452363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver        return fRadius;
462363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver    }
472363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver
482363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver    void setName(const SkString& name) {
492363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver        fName = name;
502363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver    }
512363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver
522363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver    virtual void onDraw(SkCanvas* canvas) {
532363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver        SkPaint paint;
542363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver        this->setupPaint(&paint);
552363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver
56d7cd52308e6120e6750c4f46d7357e8e5033619cBen Gruver        paint.setAntiAlias(true);
572363e6e43ccd826a315b2f1feb1850a6ccd68f84Ben Gruver
58        SkScalar pad = fRadius*3/2 + SK_Scalar1;
59        SkRect r = SkRect::MakeWH(2 * pad + SK_Scalar1, 2 * pad + SK_Scalar1);
60
61        preBenchSetup(r);
62
63        for (int i = 0; i < SkBENCHLOOP(fLoopCount); i++) {
64            makeBlurryRect(r);
65        }
66    }
67
68    virtual void makeBlurryRect(const SkRect&) = 0;
69    virtual void preBenchSetup(const SkRect&) {}
70private:
71    typedef SkBenchmark INHERITED;
72};
73
74
75class BlurRectDirectBench: public BlurRectBench {
76 public:
77    BlurRectDirectBench(void *param, SkScalar rad) : INHERITED(param, rad) {
78        SkString name;
79
80        if (SkScalarFraction(rad) != 0) {
81            name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad));
82        } else {
83            name.printf("blurrect_direct_%d", SkScalarRoundToInt(rad));
84        }
85
86        setName(name);
87    }
88protected:
89    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
90        SkMask mask;
91        SkBlurMask::BlurRect(&mask, r, this->radius(), SkBlurMask::kNormal_Style);
92        SkMask::FreeImage(mask.fImage);
93    }
94private:
95    typedef BlurRectBench INHERITED;
96};
97
98class BlurRectSeparableBench: public BlurRectBench {
99
100public:
101    BlurRectSeparableBench(void *param, SkScalar rad) : INHERITED(param, rad) {
102        fSrcMask.fImage = NULL;
103    }
104
105    ~BlurRectSeparableBench() {
106        SkMask::FreeImage(fSrcMask.fImage);
107    }
108
109protected:
110    virtual void preBenchSetup(const SkRect& r) SK_OVERRIDE {
111        SkMask::FreeImage(fSrcMask.fImage);
112
113        r.roundOut(&fSrcMask.fBounds);
114        fSrcMask.fFormat = SkMask::kA8_Format;
115        fSrcMask.fRowBytes = fSrcMask.fBounds.width();
116        fSrcMask.fImage = SkMask::AllocImage(fSrcMask.computeTotalImageSize());
117
118        memset(fSrcMask.fImage, 0xff, fSrcMask.computeTotalImageSize());
119    }
120
121    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:
139
140    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
141        SkMask mask;
142        mask.fImage = NULL;
143        SkBlurMask::BlurSeparable(&mask, fSrcMask, this->radius(),
144                                  SkBlurMask::kNormal_Style,
145                                  SkBlurMask::kHigh_Quality);
146        SkMask::FreeImage(mask.fImage);
147    }
148private:
149    typedef BlurRectSeparableBench INHERITED;
150};
151
152class 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);)
185DEF_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);)
189
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
223