GradientBench.cpp revision 35e2e62b55598210f6999fc2ea26ff8f41446ffe
1#include "SkBenchmark.h"
2#include "SkBitmap.h"
3#include "SkCanvas.h"
4#include "SkColorPriv.h"
5#include "SkGradientShader.h"
6#include "SkPaint.h"
7#include "SkShader.h"
8#include "SkString.h"
9#include "SkUnitMapper.h"
10
11struct GradData {
12    int             fCount;
13    const SkColor*  fColors;
14    const SkScalar* fPos;
15};
16
17static const SkColor gColors[] = {
18    SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
19};
20static const SkScalar gPos0[] = { 0, SK_Scalar1 };
21static const SkScalar gPos1[] = { SK_Scalar1/4, SK_Scalar1*3/4 };
22static const SkScalar gPos2[] = {
23    0, SK_Scalar1/8, SK_Scalar1/2, SK_Scalar1*7/8, SK_Scalar1
24};
25
26static const GradData gGradData[] = {
27    { 2, gColors, NULL },
28    { 2, gColors, gPos0 },
29    { 2, gColors, gPos1 },
30    { 5, gColors, NULL },
31    { 5, gColors, gPos2 }
32};
33
34static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
35                            SkShader::TileMode tm, SkUnitMapper* mapper) {
36    return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos,
37                                          data.fCount, tm, mapper);
38}
39
40static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
41                            SkShader::TileMode tm, SkUnitMapper* mapper) {
42    SkPoint center;
43    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
44               SkScalarAve(pts[0].fY, pts[1].fY));
45    return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
46                                          data.fPos, data.fCount, tm, mapper);
47}
48
49static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
50                           SkShader::TileMode tm, SkUnitMapper* mapper) {
51    SkPoint center;
52    center.set(SkScalarAve(pts[0].fX, pts[1].fX),
53               SkScalarAve(pts[0].fY, pts[1].fY));
54    return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
55                                         data.fPos, data.fCount, mapper);
56}
57
58static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
59                             SkShader::TileMode tm, SkUnitMapper* mapper) {
60    SkPoint center0, center1;
61    center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
62                SkScalarAve(pts[0].fY, pts[1].fY));
63    center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
64                SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
65    return SkGradientShader::CreateTwoPointRadial(
66                                                  center1, (pts[1].fX - pts[0].fX) / 7,
67                                                  center0, (pts[1].fX - pts[0].fX) / 2,
68                                                  data.fColors, data.fPos, data.fCount, tm, mapper);
69}
70
71typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
72                               SkShader::TileMode tm, SkUnitMapper* mapper);
73
74static const struct {
75    GradMaker   fMaker;
76    const char* fName;
77    int         fRepeat;
78} gGrads[] = {
79    { MakeLinear,   "linear",  15 },
80    { MakeRadial,   "radial1", 10 },
81    { MakeSweep,    "sweep",    1 },
82    { Make2Radial,  "radial2",  5 },
83};
84
85enum GradType { // these must match the order in gGrads
86    kLinear_GradType,
87    kRadial_GradType,
88    kSweep_GradType,
89    kRadial2_GradType
90};
91
92///////////////////////////////////////////////////////////////////////////////
93
94class GradientBench : public SkBenchmark {
95    SkString fName;
96    SkShader* fShader;
97    int      fCount;
98    enum {
99        W   = 400,
100        H   = 400,
101        N   = 1
102    };
103public:
104    GradientBench(void* param, GradType gt) : INHERITED(param) {
105        fName.printf("gradient_%s", gGrads[gt].fName);
106
107        const SkPoint pts[2] = {
108            { 0, 0 },
109            { SkIntToScalar(W), SkIntToScalar(H) }
110        };
111
112        fCount = N * gGrads[gt].fRepeat;
113        fShader = gGrads[gt].fMaker(pts, gGradData[0],
114                                    SkShader::kClamp_TileMode, NULL);
115    }
116
117    virtual ~GradientBench() {
118        fShader->unref();
119    }
120
121protected:
122    virtual const char* onGetName() {
123        return fName.c_str();
124    }
125
126    virtual void onDraw(SkCanvas* canvas) {
127        SkPaint paint;
128        this->setupPaint(&paint);
129
130        paint.setShader(fShader);
131
132        SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) };
133        for (int i = 0; i < fCount; i++) {
134            canvas->drawRect(r, paint);
135        }
136    }
137
138private:
139    typedef SkBenchmark INHERITED;
140};
141
142static SkBenchmark* Fact0(void* p) { return new GradientBench(p, kLinear_GradType); }
143static SkBenchmark* Fact1(void* p) { return new GradientBench(p, kRadial_GradType); }
144static SkBenchmark* Fact2(void* p) { return new GradientBench(p, kSweep_GradType); }
145static SkBenchmark* Fact3(void* p) { return new GradientBench(p, kRadial2_GradType); }
146
147static BenchRegistry gReg0(Fact0);
148static BenchRegistry gReg1(Fact1);
149static BenchRegistry gReg2(Fact2);
150static BenchRegistry gReg3(Fact3);
151
152