blob: d10625bfcee45851b23becb1d2a5ccf07fadc34f [file] [log] [blame]
reed@google.com84e9c082011-04-13 17:44:24 +00001#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 },
reed@google.com80adceb2011-04-13 18:32:19 +000080 { MakeRadial, "radial1", 10 },
reed@google.com84e9c082011-04-13 17:44:24 +000081 { 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
reed@google.com72415162011-06-15 21:17:37 +000092static const char* tilemodename(SkShader::TileMode tm) {
93 switch (tm) {
94 case SkShader::kClamp_TileMode:
95 return "clamp";
96 case SkShader::kRepeat_TileMode:
97 return "repeat";
98 case SkShader::kMirror_TileMode:
99 return "mirror";
100 default:
101 SkASSERT(!"unknown tilemode");
102 return "error";
103 }
104}
105
reed@google.com84e9c082011-04-13 17:44:24 +0000106///////////////////////////////////////////////////////////////////////////////
107
108class GradientBench : public SkBenchmark {
109 SkString fName;
110 SkShader* fShader;
111 int fCount;
112 enum {
113 W = 400,
114 H = 400,
115 N = 1
116 };
117public:
reed@google.com72415162011-06-15 21:17:37 +0000118 GradientBench(void* param, GradType gt,
119 SkShader::TileMode tm = SkShader::kClamp_TileMode) : INHERITED(param) {
120 fName.printf("gradient_%s_%s", gGrads[gt].fName, tilemodename(tm));
reed@google.com84e9c082011-04-13 17:44:24 +0000121
122 const SkPoint pts[2] = {
123 { 0, 0 },
124 { SkIntToScalar(W), SkIntToScalar(H) }
125 };
126
127 fCount = N * gGrads[gt].fRepeat;
reed@google.com72415162011-06-15 21:17:37 +0000128 fShader = gGrads[gt].fMaker(pts, gGradData[0], tm, NULL);
reed@google.com84e9c082011-04-13 17:44:24 +0000129 }
130
131 virtual ~GradientBench() {
132 fShader->unref();
133 }
134
135protected:
136 virtual const char* onGetName() {
137 return fName.c_str();
138 }
139
140 virtual void onDraw(SkCanvas* canvas) {
141 SkPaint paint;
142 this->setupPaint(&paint);
143
144 paint.setShader(fShader);
145
146 SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) };
147 for (int i = 0; i < fCount; i++) {
148 canvas->drawRect(r, paint);
149 }
150 }
151
152private:
153 typedef SkBenchmark INHERITED;
154};
155
reed@google.com8ac7a0f2011-06-16 13:14:19 +0000156class Gradient2Bench : public SkBenchmark {
157public:
158 Gradient2Bench(void* param) : INHERITED(param) {}
159
160protected:
161 virtual const char* onGetName() {
162 return "gradient_create";
163 }
164
165 virtual void onDraw(SkCanvas* canvas) {
166 SkPaint paint;
167 this->setupPaint(&paint);
168
169 const SkRect r = { 0, 0, SkIntToScalar(4), SkIntToScalar(4) };
170 const SkPoint pts[] = { 0, 0, SkIntToScalar(100), SkIntToScalar(100) };
171
172 for (int i = 0; i < 1000; i++) {
173 SkColor colors[] = { SK_ColorBLACK, SkColorSetARGB(i, i, i, i), SK_ColorWHITE };
174 SkShader* s = SkGradientShader::CreateLinear(pts, colors, NULL,
175 SK_ARRAY_COUNT(colors),
176 SkShader::kClamp_TileMode);
177 paint.setShader(s)->unref();
178 canvas->drawRect(r, paint);
179 }
180 }
181
182private:
183 typedef SkBenchmark INHERITED;
184};
185
reed@google.com84e9c082011-04-13 17:44:24 +0000186static SkBenchmark* Fact0(void* p) { return new GradientBench(p, kLinear_GradType); }
reed@google.com8ac7a0f2011-06-16 13:14:19 +0000187static SkBenchmark* Fact01(void* p) { return new GradientBench(p, kLinear_GradType, SkShader::kMirror_TileMode); }
reed@google.com84e9c082011-04-13 17:44:24 +0000188static SkBenchmark* Fact1(void* p) { return new GradientBench(p, kRadial_GradType); }
reed@google.com72415162011-06-15 21:17:37 +0000189static SkBenchmark* Fact11(void* p) { return new GradientBench(p, kRadial_GradType, SkShader::kMirror_TileMode); }
reed@google.com84e9c082011-04-13 17:44:24 +0000190static SkBenchmark* Fact2(void* p) { return new GradientBench(p, kSweep_GradType); }
191static SkBenchmark* Fact3(void* p) { return new GradientBench(p, kRadial2_GradType); }
reed@google.com8ac7a0f2011-06-16 13:14:19 +0000192static SkBenchmark* Fact31(void* p) { return new GradientBench(p, kRadial2_GradType, SkShader::kMirror_TileMode); }
193
194static SkBenchmark* Fact4(void* p) { return new Gradient2Bench(p); }
reed@google.com84e9c082011-04-13 17:44:24 +0000195
196static BenchRegistry gReg0(Fact0);
reed@google.com8ac7a0f2011-06-16 13:14:19 +0000197static BenchRegistry gReg01(Fact01);
reed@google.com84e9c082011-04-13 17:44:24 +0000198static BenchRegistry gReg1(Fact1);
reed@google.com72415162011-06-15 21:17:37 +0000199static BenchRegistry gReg11(Fact11);
reed@google.com84e9c082011-04-13 17:44:24 +0000200static BenchRegistry gReg2(Fact2);
201static BenchRegistry gReg3(Fact3);
reed@google.com8ac7a0f2011-06-16 13:14:19 +0000202static BenchRegistry gReg31(Fact31);
203
204static BenchRegistry gReg4(Fact4);
reed@google.com84e9c082011-04-13 17:44:24 +0000205