BlurRectBench.cpp revision efbe8e9bedda21a3e061ebf3d96431a0f250a654
1/*
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 */
7
8#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 {
22    int         fLoopCount;
23    SkScalar    fRadius;
24    SkString    fName;
25
26public:
27    BlurRectBench(void *param, SkScalar rad) : INHERITED(param) {
28        fRadius = rad;
29
30        if (fRadius > SkIntToScalar(25)) {
31            fLoopCount = 100;
32        } else if (fRadius > SkIntToScalar(5)) {
33            fLoopCount = 1000;
34        } else {
35            fLoopCount = 10000;
36        }
37    }
38
39protected:
40    virtual const char* onGetName() {
41        return fName.c_str();
42    }
43
44    SkScalar radius() const {
45        return fRadius;
46    }
47
48    void setName(const SkString& name) {
49        fName = name;
50    }
51
52    virtual void onDraw(SkCanvas* canvas) {
53        SkPaint paint;
54        this->setupPaint(&paint);
55
56        paint.setAntiAlias(true);
57
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) : BlurRectBench(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", SkScalarRound(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, radius(), SkBlurMask::kNormal_Style,
92                             SkBlurMask::kHigh_Quality);
93        SkMask::FreeImage(mask.fImage);
94    }
95};
96
97class BlurRectSeparableBench: public BlurRectBench {
98    SkMask fSrcMask;
99public:
100    BlurRectSeparableBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
101        SkString name;
102        if (SkScalarFraction(rad) != 0) {
103            name.printf("blurrect_separable_%.2f", SkScalarToFloat(rad));
104        } else {
105            name.printf("blurrect_separable_%d", SkScalarRound(rad));
106        }
107        setName(name);
108        fSrcMask.fImage = NULL;
109    }
110
111    ~BlurRectSeparableBench() {
112        SkMask::FreeImage(fSrcMask.fImage);
113    }
114
115protected:
116    virtual void preBenchSetup(const SkRect& r) SK_OVERRIDE {
117        SkMask::FreeImage(fSrcMask.fImage);
118
119        r.roundOut(&fSrcMask.fBounds);
120        fSrcMask.fFormat = SkMask::kA8_Format;
121        fSrcMask.fRowBytes = fSrcMask.fBounds.width();
122        fSrcMask.fImage = SkMask::AllocImage(fSrcMask.computeTotalImageSize());
123
124        memset(fSrcMask.fImage, 0xff, fSrcMask.computeTotalImageSize());
125    }
126
127    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
128        SkMask mask;
129        SkBlurMask::BlurSeparable(&mask, fSrcMask, radius(),
130                                  SkBlurMask::kNormal_Style,
131                                  SkBlurMask::kHigh_Quality);
132        SkMask::FreeImage(mask.fImage);
133    }
134};
135
136DEF_BENCH(return new BlurRectSeparableBench(p, SMALL);)
137DEF_BENCH(return new BlurRectSeparableBench(p, BIG);)
138DEF_BENCH(return new BlurRectSeparableBench(p, REALBIG);)
139DEF_BENCH(return new BlurRectSeparableBench(p, REAL);)
140DEF_BENCH(return new BlurRectDirectBench(p, SMALL);)
141DEF_BENCH(return new BlurRectDirectBench(p, BIG);)
142DEF_BENCH(return new BlurRectDirectBench(p, REALBIG);)
143DEF_BENCH(return new BlurRectDirectBench(p, REAL);)
144