blob: 901304442f9ff068832a8e216535d543979054d7 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
reed@android.combd700c32009-01-05 03:34:50 +00008#include "SkBenchmark.h"
9#include "SkCanvas.h"
mtklein@google.comc2897432013-09-10 19:23:38 +000010#include "SkCommandLineFlags.h"
reed@android.combd700c32009-01-05 03:34:50 +000011#include "SkPaint.h"
12#include "SkRandom.h"
reed@google.com981d4792011-03-09 12:55:47 +000013#include "SkShader.h"
mtklein@google.comc2897432013-09-10 19:23:38 +000014#include "SkString.h"
15
16DEFINE_double(strokeWidth, -1.0, "If set, use this stroke width in RectBench.");
reed@android.combd700c32009-01-05 03:34:50 +000017
18class RectBench : public SkBenchmark {
19public:
mike@reedtribe.org2ecead52011-04-02 13:37:23 +000020 int fShift, fStroke;
reed@android.combd700c32009-01-05 03:34:50 +000021 enum {
22 W = 640,
23 H = 480,
mtklein@google.comc2897432013-09-10 19:23:38 +000024 N = 300,
reed@android.combd700c32009-01-05 03:34:50 +000025 };
26 SkRect fRects[N];
27 SkColor fColors[N];
28
mtklein@google.com410e6e82013-09-13 19:52:27 +000029 RectBench(int shift, int stroke = 0)
30 : fShift(shift)
commit-bot@chromium.org000d7322013-12-05 12:07:44 +000031 , fStroke(stroke) {}
reed@google.com1fcd51e2011-01-05 15:50:27 +000032
reed@android.comd2c37442009-01-08 03:00:57 +000033 SkString fName;
34 const char* computeName(const char root[]) {
mike@reedtribe.org2ecead52011-04-02 13:37:23 +000035 fName.printf("%s_%d", root, fShift);
36 if (fStroke > 0) {
37 fName.appendf("_stroke_%d", fStroke);
38 }
reed@android.comd2c37442009-01-08 03:00:57 +000039 return fName.c_str();
40 }
reed@google.com1fcd51e2011-01-05 15:50:27 +000041
reed@android.combd700c32009-01-05 03:34:50 +000042protected:
43 virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
44 c->drawRect(r, p);
45 }
46
reed@android.com4bc19832009-01-19 20:08:35 +000047 virtual const char* onGetName() { return computeName("rects"); }
commit-bot@chromium.org000d7322013-12-05 12:07:44 +000048
49 virtual void onPreDraw() {
50 SkRandom rand;
51 const SkScalar offset = SK_Scalar1/3;
52 for (int i = 0; i < N; i++) {
53 int x = rand.nextU() % W;
54 int y = rand.nextU() % H;
55 int w = rand.nextU() % W;
56 int h = rand.nextU() % H;
57 w >>= fShift;
58 h >>= fShift;
59 x -= w/2;
60 y -= h/2;
61 fRects[i].set(SkIntToScalar(x), SkIntToScalar(y),
62 SkIntToScalar(x+w), SkIntToScalar(y+h));
63 fRects[i].offset(offset, offset);
64 fColors[i] = rand.nextU() | 0xFF808080;
65 }
66 }
67
commit-bot@chromium.org33614712013-12-03 18:17:16 +000068 virtual void onDraw(const int loops, SkCanvas* canvas) {
reed@android.combd700c32009-01-05 03:34:50 +000069 SkPaint paint;
mike@reedtribe.org2ecead52011-04-02 13:37:23 +000070 if (fStroke > 0) {
71 paint.setStyle(SkPaint::kStroke_Style);
72 paint.setStrokeWidth(SkIntToScalar(fStroke));
73 }
commit-bot@chromium.org33614712013-12-03 18:17:16 +000074 for (int i = 0; i < loops; i++) {
mtklein@google.comc2897432013-09-10 19:23:38 +000075 paint.setColor(fColors[i % N]);
reed@android.com4bc19832009-01-19 20:08:35 +000076 this->setupPaint(&paint);
mtklein@google.comc2897432013-09-10 19:23:38 +000077 this->drawThisRect(canvas, fRects[i % N], paint);
reed@android.combd700c32009-01-05 03:34:50 +000078 }
79 }
reed@android.come9d00602009-09-02 21:12:42 +000080private:
81 typedef SkBenchmark INHERITED;
reed@android.combd700c32009-01-05 03:34:50 +000082};
83
reed@google.com2d078b62012-11-15 19:52:07 +000084class SrcModeRectBench : public RectBench {
85public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000086 SrcModeRectBench() : INHERITED(1, 0) {
reed@google.com2d078b62012-11-15 19:52:07 +000087 fMode = SkXfermode::Create(SkXfermode::kSrc_Mode);
88 }
skia.committer@gmail.com884e60b2012-11-16 02:01:17 +000089
reed@google.com2d078b62012-11-15 19:52:07 +000090 virtual ~SrcModeRectBench() {
91 SkSafeUnref(fMode);
92 }
93
94protected:
95 virtual void setupPaint(SkPaint* paint) SK_OVERRIDE {
96 this->INHERITED::setupPaint(paint);
97 // srcmode is most interesting when we're not opaque
98 paint->setAlpha(0x80);
99 paint->setXfermode(fMode);
100 }
101
102 virtual const char* onGetName() SK_OVERRIDE {
103 fName.set(this->INHERITED::onGetName());
104 fName.prepend("srcmode_");
105 return fName.c_str();
106 }
107
108private:
109 SkString fName;
110 SkXfermode* fMode;
111
112 typedef RectBench INHERITED;
113};
114
reed@android.combd700c32009-01-05 03:34:50 +0000115class OvalBench : public RectBench {
reed@android.comd2c37442009-01-08 03:00:57 +0000116public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000117 OvalBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
reed@android.combd700c32009-01-05 03:34:50 +0000118protected:
119 virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
120 c->drawOval(r, p);
121 }
reed@android.comd2c37442009-01-08 03:00:57 +0000122 virtual const char* onGetName() { return computeName("ovals"); }
reed@android.combd700c32009-01-05 03:34:50 +0000123};
124
125class RRectBench : public RectBench {
reed@android.comd2c37442009-01-08 03:00:57 +0000126public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000127 RRectBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
reed@android.combd700c32009-01-05 03:34:50 +0000128protected:
129 virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
130 c->drawRoundRect(r, r.width() / 4, r.height() / 4, p);
131 }
reed@android.com4bc19832009-01-19 20:08:35 +0000132 virtual const char* onGetName() { return computeName("rrects"); }
reed@android.combd700c32009-01-05 03:34:50 +0000133};
134
135class PointsBench : public RectBench {
136public:
137 SkCanvas::PointMode fMode;
138 const char* fName;
139
mtklein@google.com410e6e82013-09-13 19:52:27 +0000140 PointsBench(SkCanvas::PointMode mode, const char* name)
141 : RectBench(2)
142 , fMode(mode) {
reed@android.combd700c32009-01-05 03:34:50 +0000143 fName = name;
144 }
145
146protected:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000147 virtual void onDraw(const int loops, SkCanvas* canvas) {
agl@chromium.org652807b2010-04-27 15:47:34 +0000148 SkScalar gSizes[] = {
reed@android.combd700c32009-01-05 03:34:50 +0000149 SkIntToScalar(7), 0
150 };
agl@chromium.org652807b2010-04-27 15:47:34 +0000151 size_t sizes = SK_ARRAY_COUNT(gSizes);
152
mtklein@google.comc2897432013-09-10 19:23:38 +0000153 if (FLAGS_strokeWidth >= 0) {
mtklein@google.comb87bf832013-09-10 19:51:10 +0000154 gSizes[0] = (SkScalar)FLAGS_strokeWidth;
agl@chromium.org652807b2010-04-27 15:47:34 +0000155 sizes = 1;
156 }
reed@android.combd700c32009-01-05 03:34:50 +0000157
158 SkPaint paint;
reed@android.combd700c32009-01-05 03:34:50 +0000159 paint.setStrokeCap(SkPaint::kRound_Cap);
agl@chromium.org652807b2010-04-27 15:47:34 +0000160
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000161 for (int loop = 0; loop < loops; loop++) {
mtklein@google.comc2897432013-09-10 19:23:38 +0000162 for (size_t i = 0; i < sizes; i++) {
163 paint.setStrokeWidth(gSizes[i]);
164 this->setupPaint(&paint);
165 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
166 paint.setColor(fColors[i % N]);
167 }
reed@android.combd700c32009-01-05 03:34:50 +0000168 }
169 }
170 virtual const char* onGetName() { return fName; }
171};
172
robertphillips@google.com12310e42012-12-14 22:10:30 +0000173class AARectBench : public SkBenchmark {
174public:
175 enum {
176 W = 640,
177 H = 480,
178 };
179
mtklein@google.com410e6e82013-09-13 19:52:27 +0000180 AARectBench(bool rotate) : fRotate(rotate) {}
robertphillips@google.com12310e42012-12-14 22:10:30 +0000181
182protected:
183
skia.committer@gmail.com2fd42c42013-05-03 07:01:00 +0000184 virtual const char* onGetName() {
robertphillips@google.com370d8352013-05-02 13:57:52 +0000185 if (fRotate) {
skia.committer@gmail.com2fd42c42013-05-03 07:01:00 +0000186 return "aarects_rotated";
robertphillips@google.com370d8352013-05-02 13:57:52 +0000187 }
skia.committer@gmail.com2fd42c42013-05-03 07:01:00 +0000188 return "aarects";
robertphillips@google.com370d8352013-05-02 13:57:52 +0000189 }
robertphillips@google.com12310e42012-12-14 22:10:30 +0000190
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000191 virtual void onDraw(const int loops, SkCanvas* canvas) {
commit-bot@chromium.org4b413c82013-11-25 19:44:07 +0000192 static const SkScalar kHalfRectSize = 0.75f;
robertphillips@google.com370d8352013-05-02 13:57:52 +0000193
robertphillips@google.com12310e42012-12-14 22:10:30 +0000194 SkPaint paint;
195 this->setupPaint(&paint);
196 paint.setAntiAlias(true);
197 paint.setColor(SK_ColorBLACK);
robertphillips@google.com370d8352013-05-02 13:57:52 +0000198 SkRect r = { -kHalfRectSize, -kHalfRectSize, kHalfRectSize, kHalfRectSize };
199 int rot = 0;
robertphillips@google.com12310e42012-12-14 22:10:30 +0000200
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000201 for (int i = 0; i < loops; i++) {
mtklein@google.comc2897432013-09-10 19:23:38 +0000202 // Draw small aa rects in a grid across the screen
203 for (SkScalar y = kHalfRectSize+SK_Scalar1; y < H; y += 2*kHalfRectSize+2) {
204 for (SkScalar x = kHalfRectSize+SK_Scalar1; x < W; x += 2*kHalfRectSize+2) {
205 canvas->save();
206 canvas->translate(x, y);
robertphillips@google.com370d8352013-05-02 13:57:52 +0000207
mtklein@google.comc2897432013-09-10 19:23:38 +0000208 if (fRotate) {
209 SkMatrix rotate;
210 rotate.setRotate(SkIntToScalar(rot));
211 canvas->concat(rotate);
212 rot += 10;
213 }
214
215 canvas->drawRect(r, paint);
216 canvas->restore();
robertphillips@google.com370d8352013-05-02 13:57:52 +0000217 }
robertphillips@google.com12310e42012-12-14 22:10:30 +0000218 }
219 }
220
221 }
222private:
robertphillips@google.com370d8352013-05-02 13:57:52 +0000223 bool fRotate;
robertphillips@google.com12310e42012-12-14 22:10:30 +0000224 typedef SkBenchmark INHERITED;
225};
226
reed@google.com981d4792011-03-09 12:55:47 +0000227/*******************************************************************************
228 * to bench BlitMask [Opaque, Black, color, shader]
229 *******************************************************************************/
230
231class BlitMaskBench : public RectBench {
232public:
233 enum kMaskType {
234 kMaskOpaque = 0,
235 kMaskBlack,
236 kMaskColor,
237 KMaskShader
238 };
239 SkCanvas::PointMode fMode;
240 const char* fName;
241
mtklein@google.com410e6e82013-09-13 19:52:27 +0000242 BlitMaskBench(SkCanvas::PointMode mode,
reed@google.com981d4792011-03-09 12:55:47 +0000243 BlitMaskBench::kMaskType type, const char* name) :
mtklein@google.com410e6e82013-09-13 19:52:27 +0000244 RectBench(2), fMode(mode), _type(type) {
reed@google.com981d4792011-03-09 12:55:47 +0000245 fName = name;
246 }
247
248protected:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000249 virtual void onDraw(const int loops, SkCanvas* canvas) {
reed@google.com981d4792011-03-09 12:55:47 +0000250 SkScalar gSizes[] = {
251 SkIntToScalar(13), SkIntToScalar(24)
252 };
253 size_t sizes = SK_ARRAY_COUNT(gSizes);
254
mtklein@google.comc2897432013-09-10 19:23:38 +0000255 if (FLAGS_strokeWidth >= 0) {
mtklein@google.comb87bf832013-09-10 19:51:10 +0000256 gSizes[0] = (SkScalar)FLAGS_strokeWidth;
reed@google.com981d4792011-03-09 12:55:47 +0000257 sizes = 1;
258 }
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000259 SkRandom rand;
reed@google.com981d4792011-03-09 12:55:47 +0000260 SkColor color = 0xFF000000;
261 U8CPU alpha = 0xFF;
262 SkPaint paint;
263 paint.setStrokeCap(SkPaint::kRound_Cap);
264 if (_type == KMaskShader) {
265 SkBitmap srcBM;
266 srcBM.setConfig(SkBitmap::kARGB_8888_Config, 10, 1);
267 srcBM.allocPixels();
268 srcBM.eraseColor(0xFF00FF00);
269
270 SkShader* s;
271 s = SkShader::CreateBitmapShader(srcBM, SkShader::kClamp_TileMode,
272 SkShader::kClamp_TileMode);
273 paint.setShader(s)->unref();
274 }
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000275 for (int loop = 0; loop < loops; loop++) {
mtklein@google.comc2897432013-09-10 19:23:38 +0000276 for (size_t i = 0; i < sizes; i++) {
277 switch (_type) {
278 case kMaskOpaque:
279 color = fColors[i];
280 alpha = 0xFF;
281 break;
282 case kMaskBlack:
283 alpha = 0xFF;
284 color = 0xFF000000;
285 break;
286 case kMaskColor:
287 color = fColors[i];
288 alpha = rand.nextU() & 255;
289 break;
290 case KMaskShader:
291 break;
292 }
293 paint.setStrokeWidth(gSizes[i]);
294 this->setupPaint(&paint);
295 paint.setColor(color);
296 paint.setAlpha(alpha);
297 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
298 }
299 }
reed@google.com981d4792011-03-09 12:55:47 +0000300 }
301 virtual const char* onGetName() { return fName; }
302private:
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000303 typedef RectBench INHERITED;
304 kMaskType _type;
reed@google.com981d4792011-03-09 12:55:47 +0000305};
306
307
mtklein@google.com410e6e82013-09-13 19:52:27 +0000308DEF_BENCH( return SkNEW_ARGS(RectBench, (1)); )
309DEF_BENCH( return SkNEW_ARGS(RectBench, (1, 4)); )
310DEF_BENCH( return SkNEW_ARGS(RectBench, (3)); )
311DEF_BENCH( return SkNEW_ARGS(RectBench, (3, 4)); )
312DEF_BENCH( return SkNEW_ARGS(OvalBench, (1)); )
313DEF_BENCH( return SkNEW_ARGS(OvalBench, (3)); )
314DEF_BENCH( return SkNEW_ARGS(OvalBench, (1, 4)); )
315DEF_BENCH( return SkNEW_ARGS(OvalBench, (3, 4)); )
316DEF_BENCH( return SkNEW_ARGS(RRectBench, (1)); )
317DEF_BENCH( return SkNEW_ARGS(RRectBench, (1, 4)); )
318DEF_BENCH( return SkNEW_ARGS(RRectBench, (3)); )
319DEF_BENCH( return SkNEW_ARGS(RRectBench, (3, 4)); )
320DEF_BENCH( return SkNEW_ARGS(PointsBench, (SkCanvas::kPoints_PointMode, "points")); )
321DEF_BENCH( return SkNEW_ARGS(PointsBench, (SkCanvas::kLines_PointMode, "lines")); )
322DEF_BENCH( return SkNEW_ARGS(PointsBench, (SkCanvas::kPolygon_PointMode, "polygon")); )
reed@android.combd700c32009-01-05 03:34:50 +0000323
mtklein@google.com410e6e82013-09-13 19:52:27 +0000324DEF_BENCH( return SkNEW_ARGS(SrcModeRectBench, ()); )
robertphillips@google.com370d8352013-05-02 13:57:52 +0000325
mtklein@google.com410e6e82013-09-13 19:52:27 +0000326DEF_BENCH( return SkNEW_ARGS(AARectBench, (false)); )
327DEF_BENCH( return SkNEW_ARGS(AARectBench, (true)); )
reed@google.com2d078b62012-11-15 19:52:07 +0000328
reed@google.com981d4792011-03-09 12:55:47 +0000329/* init the blitmask bench
330 */
reed@google.com60712f32012-11-15 18:06:00 +0000331DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
mtklein@google.com410e6e82013-09-13 19:52:27 +0000332 (SkCanvas::kPoints_PointMode,
reed@google.com981d4792011-03-09 12:55:47 +0000333 BlitMaskBench::kMaskOpaque, "maskopaque")
reed@google.com60712f32012-11-15 18:06:00 +0000334 ); )
335DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
mtklein@google.com410e6e82013-09-13 19:52:27 +0000336 (SkCanvas::kPoints_PointMode,
reed@google.com981d4792011-03-09 12:55:47 +0000337 BlitMaskBench::kMaskBlack, "maskblack")
reed@google.com60712f32012-11-15 18:06:00 +0000338 ); )
339DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
mtklein@google.com410e6e82013-09-13 19:52:27 +0000340 (SkCanvas::kPoints_PointMode,
reed@google.com981d4792011-03-09 12:55:47 +0000341 BlitMaskBench::kMaskColor, "maskcolor")
reed@google.com60712f32012-11-15 18:06:00 +0000342 ); )
343DEF_BENCH( return SkNEW_ARGS(BlitMaskBench,
mtklein@google.com410e6e82013-09-13 19:52:27 +0000344 (SkCanvas::kPoints_PointMode,
reed@google.com981d4792011-03-09 12:55:47 +0000345 BlitMaskBench::KMaskShader, "maskshader")
reed@google.com60712f32012-11-15 18:06:00 +0000346 ); )