blob: 7f9e0ce10a1b39b931fb991bfc9c74bdb1733c70 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
2 * Copyright 2011 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 */
Mike Reed75ae4212018-01-23 11:24:08 -05007
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "bench/Benchmark.h"
9#include "include/core/SkBitmap.h"
10#include "include/core/SkCanvas.h"
11#include "include/core/SkPaint.h"
12#include "include/core/SkShader.h"
13#include "include/core/SkString.h"
14#include "include/effects/SkGradientShader.h"
15#include "include/utils/SkRandom.h"
16#include "tools/flags/CommandLineFlags.h"
mtklein@google.comc2897432013-09-10 19:23:38 +000017
Mike Klein84836b72019-03-21 11:31:36 -050018static DEFINE_double(strokeWidth, -1.0, "If set, use this stroke width in RectBench.");
reed@android.combd700c32009-01-05 03:34:50 +000019
tfarinaf168b862014-06-19 12:32:29 -070020class RectBench : public Benchmark {
reed@android.combd700c32009-01-05 03:34:50 +000021public:
mike@reedtribe.org2ecead52011-04-02 13:37:23 +000022 int fShift, fStroke;
reed@android.combd700c32009-01-05 03:34:50 +000023 enum {
24 W = 640,
25 H = 480,
mtklein@google.comc2897432013-09-10 19:23:38 +000026 N = 300,
reed@android.combd700c32009-01-05 03:34:50 +000027 };
28 SkRect fRects[N];
29 SkColor fColors[N];
Michael Ludwigdde8b552018-11-20 14:58:23 -050030 bool fAA;
31 bool fPerspective;
reed@android.combd700c32009-01-05 03:34:50 +000032
Michael Ludwigdde8b552018-11-20 14:58:23 -050033 RectBench(int shift, int stroke = 0, bool aa = true, bool perspective = false)
mtklein@google.com410e6e82013-09-13 19:52:27 +000034 : fShift(shift)
Michael Ludwigdde8b552018-11-20 14:58:23 -050035 , fStroke(stroke)
36 , fAA(aa)
37 , fPerspective(perspective) {}
reed@google.com1fcd51e2011-01-05 15:50:27 +000038
reed@android.comd2c37442009-01-08 03:00:57 +000039 const char* computeName(const char root[]) {
Brian Salomon3349c6f2017-03-01 09:49:58 -050040 fBaseName.printf("%s_%d", root, fShift);
mike@reedtribe.org2ecead52011-04-02 13:37:23 +000041 if (fStroke > 0) {
Brian Salomon3349c6f2017-03-01 09:49:58 -050042 fBaseName.appendf("_stroke_%d", fStroke);
mike@reedtribe.org2ecead52011-04-02 13:37:23 +000043 }
Michael Ludwigdde8b552018-11-20 14:58:23 -050044 if (fAA) {
45 fBaseName.appendf("_aa");
46 } else {
47 fBaseName.appendf("_bw");
48 }
49 if (fPerspective) {
50 fBaseName.appendf("_persp");
51 }
Brian Salomon3349c6f2017-03-01 09:49:58 -050052 return fBaseName.c_str();
reed@android.comd2c37442009-01-08 03:00:57 +000053 }
reed@google.com1fcd51e2011-01-05 15:50:27 +000054
reed@android.combd700c32009-01-05 03:34:50 +000055protected:
Brian Salomondac5f6b2017-02-28 16:11:04 -050056
reed@android.combd700c32009-01-05 03:34:50 +000057 virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
58 c->drawRect(r, p);
59 }
60
reed57b76712015-09-25 04:49:43 -070061 const char* onGetName() override { return computeName("rects"); }
commit-bot@chromium.org000d7322013-12-05 12:07:44 +000062
joshualitt8a6697a2015-09-30 12:11:07 -070063 void onDelayedSetup() override {
commit-bot@chromium.org000d7322013-12-05 12:07:44 +000064 SkRandom rand;
65 const SkScalar offset = SK_Scalar1/3;
66 for (int i = 0; i < N; i++) {
67 int x = rand.nextU() % W;
68 int y = rand.nextU() % H;
69 int w = rand.nextU() % W;
70 int h = rand.nextU() % H;
71 w >>= fShift;
72 h >>= fShift;
73 x -= w/2;
74 y -= h/2;
Mike Reed92b33352019-08-24 19:39:13 -040075 fRects[i].setXYWH(SkIntToScalar(x), SkIntToScalar(y),
76 SkIntToScalar(w), SkIntToScalar(h));
commit-bot@chromium.org000d7322013-12-05 12:07:44 +000077 fRects[i].offset(offset, offset);
78 fColors[i] = rand.nextU() | 0xFF808080;
79 }
80 }
81
mtkleina1ebeb22015-10-01 09:43:39 -070082 void onDraw(int loops, SkCanvas* canvas) override {
reed@android.combd700c32009-01-05 03:34:50 +000083 SkPaint paint;
mike@reedtribe.org2ecead52011-04-02 13:37:23 +000084 if (fStroke > 0) {
85 paint.setStyle(SkPaint::kStroke_Style);
86 paint.setStrokeWidth(SkIntToScalar(fStroke));
87 }
Michael Ludwigdde8b552018-11-20 14:58:23 -050088 if (fPerspective) {
89 // Apply some fixed perspective to change how ops may draw the rects
90 SkMatrix perspective;
91 perspective.setIdentity();
92 perspective.setPerspX(1e-4f);
93 perspective.setPerspY(1e-3f);
94 perspective.setSkewX(0.1f);
95 canvas->concat(perspective);
96 }
commit-bot@chromium.org33614712013-12-03 18:17:16 +000097 for (int i = 0; i < loops; i++) {
mtklein@google.comc2897432013-09-10 19:23:38 +000098 paint.setColor(fColors[i % N]);
reed@android.com4bc19832009-01-19 20:08:35 +000099 this->setupPaint(&paint);
mtklein@google.comc2897432013-09-10 19:23:38 +0000100 this->drawThisRect(canvas, fRects[i % N], paint);
reed@android.combd700c32009-01-05 03:34:50 +0000101 }
102 }
Brian Salomon3349c6f2017-03-01 09:49:58 -0500103
Michael Ludwigdde8b552018-11-20 14:58:23 -0500104 void setupPaint(SkPaint* paint) override {
105 this->INHERITED::setupPaint(paint);
106 paint->setAntiAlias(fAA);
107 }
108
reed@android.come9d00602009-09-02 21:12:42 +0000109private:
Brian Salomon3349c6f2017-03-01 09:49:58 -0500110 SkString fBaseName;
tfarinaf168b862014-06-19 12:32:29 -0700111 typedef Benchmark INHERITED;
reed@android.combd700c32009-01-05 03:34:50 +0000112};
113
reed@google.com2d078b62012-11-15 19:52:07 +0000114class SrcModeRectBench : public RectBench {
115public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000116 SrcModeRectBench() : INHERITED(1, 0) {
reed374772b2016-10-05 17:33:02 -0700117 fMode = SkBlendMode::kSrc;
reed@google.com2d078b62012-11-15 19:52:07 +0000118 }
119
120protected:
mtklein36352bf2015-03-25 18:17:31 -0700121 void setupPaint(SkPaint* paint) override {
reed@google.com2d078b62012-11-15 19:52:07 +0000122 this->INHERITED::setupPaint(paint);
123 // srcmode is most interesting when we're not opaque
124 paint->setAlpha(0x80);
reed374772b2016-10-05 17:33:02 -0700125 paint->setBlendMode(fMode);
reed@google.com2d078b62012-11-15 19:52:07 +0000126 }
127
mtklein36352bf2015-03-25 18:17:31 -0700128 const char* onGetName() override {
reed@google.com2d078b62012-11-15 19:52:07 +0000129 fName.set(this->INHERITED::onGetName());
130 fName.prepend("srcmode_");
131 return fName.c_str();
132 }
133
134private:
reed374772b2016-10-05 17:33:02 -0700135 SkBlendMode fMode;
Brian Salomon3349c6f2017-03-01 09:49:58 -0500136 SkString fName;
reed@google.com2d078b62012-11-15 19:52:07 +0000137
138 typedef RectBench INHERITED;
139};
140
joshualitt8db65a62015-09-24 12:42:02 -0700141class TransparentRectBench : public RectBench {
142public:
143 TransparentRectBench() : INHERITED(1, 0) {}
144
145protected:
146 void setupPaint(SkPaint* paint) override {
147 this->INHERITED::setupPaint(paint);
148 // draw non opaque rect
149 paint->setAlpha(0x80);
150 }
151
152 const char* onGetName() override {
153 fName.set(this->INHERITED::onGetName());
154 fName.prepend("transparent_");
155 return fName.c_str();
156 }
157
158private:
Brian Salomon3349c6f2017-03-01 09:49:58 -0500159 SkString fName;
joshualitt8db65a62015-09-24 12:42:02 -0700160 typedef RectBench INHERITED;
161};
162
Michael Ludwigdde8b552018-11-20 14:58:23 -0500163// Adds a shader to the paint that requires local coordinates to be used
164class LocalCoordsRectBench : public RectBench {
165public:
166 LocalCoordsRectBench(bool aa, bool perspective = false) : INHERITED(1, 0, aa, perspective) { }
167
168protected:
169 void onDelayedSetup() override {
170 this->INHERITED::onDelayedSetup();
171 // Create the shader once, so that isn't included in the timing
172 SkPoint pts[2] = { {0.f, 0.f}, {50.f, 50.f} };
173 SkColor colors[] = { SK_ColorWHITE, SK_ColorBLUE };
Mike Reedfae8fce2019-04-03 10:27:45 -0400174 fShader = SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp);
Michael Ludwigdde8b552018-11-20 14:58:23 -0500175 }
176
177 void setupPaint(SkPaint* paint) override {
178 this->INHERITED::setupPaint(paint);
179 paint->setShader(fShader);
180 }
181
182 const char* onGetName() override {
183 fName.set(this->INHERITED::onGetName());
184 fName.append("_localcoords");
185 return fName.c_str();
186 }
187
188private:
189 SkString fName;
190 sk_sp<SkShader> fShader;
191
192 typedef RectBench INHERITED;
193};
194
joshualitt8db65a62015-09-24 12:42:02 -0700195
reed@android.combd700c32009-01-05 03:34:50 +0000196class OvalBench : public RectBench {
reed@android.comd2c37442009-01-08 03:00:57 +0000197public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000198 OvalBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
reed@android.combd700c32009-01-05 03:34:50 +0000199protected:
reed57b76712015-09-25 04:49:43 -0700200 void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override {
reed@android.combd700c32009-01-05 03:34:50 +0000201 c->drawOval(r, p);
202 }
reed57b76712015-09-25 04:49:43 -0700203 const char* onGetName() override { return computeName("ovals"); }
reed@android.combd700c32009-01-05 03:34:50 +0000204};
205
206class RRectBench : public RectBench {
reed@android.comd2c37442009-01-08 03:00:57 +0000207public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000208 RRectBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
reed@android.combd700c32009-01-05 03:34:50 +0000209protected:
reed57b76712015-09-25 04:49:43 -0700210 void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override {
reed@android.combd700c32009-01-05 03:34:50 +0000211 c->drawRoundRect(r, r.width() / 4, r.height() / 4, p);
212 }
reed57b76712015-09-25 04:49:43 -0700213 const char* onGetName() override { return computeName("rrects"); }
reed@android.combd700c32009-01-05 03:34:50 +0000214};
215
216class PointsBench : public RectBench {
217public:
218 SkCanvas::PointMode fMode;
reed@android.combd700c32009-01-05 03:34:50 +0000219
mtklein@google.com410e6e82013-09-13 19:52:27 +0000220 PointsBench(SkCanvas::PointMode mode, const char* name)
221 : RectBench(2)
222 , fMode(mode) {
reed@android.combd700c32009-01-05 03:34:50 +0000223 fName = name;
224 }
225
226protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700227 void onDraw(int loops, SkCanvas* canvas) override {
agl@chromium.org652807b2010-04-27 15:47:34 +0000228 SkScalar gSizes[] = {
reed@android.combd700c32009-01-05 03:34:50 +0000229 SkIntToScalar(7), 0
230 };
agl@chromium.org652807b2010-04-27 15:47:34 +0000231 size_t sizes = SK_ARRAY_COUNT(gSizes);
232
mtklein@google.comc2897432013-09-10 19:23:38 +0000233 if (FLAGS_strokeWidth >= 0) {
mtklein@google.comb87bf832013-09-10 19:51:10 +0000234 gSizes[0] = (SkScalar)FLAGS_strokeWidth;
agl@chromium.org652807b2010-04-27 15:47:34 +0000235 sizes = 1;
236 }
reed@android.combd700c32009-01-05 03:34:50 +0000237
238 SkPaint paint;
reed@android.combd700c32009-01-05 03:34:50 +0000239 paint.setStrokeCap(SkPaint::kRound_Cap);
agl@chromium.org652807b2010-04-27 15:47:34 +0000240
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000241 for (int loop = 0; loop < loops; loop++) {
mtklein@google.comc2897432013-09-10 19:23:38 +0000242 for (size_t i = 0; i < sizes; i++) {
243 paint.setStrokeWidth(gSizes[i]);
244 this->setupPaint(&paint);
Mike Kleine72e7732018-06-14 14:41:22 -0400245 canvas->drawPoints(fMode, N * 2, reinterpret_cast<SkPoint*>(fRects), paint);
mtklein@google.comc2897432013-09-10 19:23:38 +0000246 paint.setColor(fColors[i % N]);
247 }
reed@android.combd700c32009-01-05 03:34:50 +0000248 }
249 }
Brian Salomondac5f6b2017-02-28 16:11:04 -0500250 const char* onGetName() override { return fName.c_str(); }
Brian Salomon3349c6f2017-03-01 09:49:58 -0500251
252private:
253 SkString fName;
254
reed@android.combd700c32009-01-05 03:34:50 +0000255};
256
reed@google.com981d4792011-03-09 12:55:47 +0000257/*******************************************************************************
258 * to bench BlitMask [Opaque, Black, color, shader]
259 *******************************************************************************/
260
261class BlitMaskBench : public RectBench {
262public:
263 enum kMaskType {
264 kMaskOpaque = 0,
265 kMaskBlack,
266 kMaskColor,
267 KMaskShader
268 };
269 SkCanvas::PointMode fMode;
reed@google.com981d4792011-03-09 12:55:47 +0000270
mtklein@google.com410e6e82013-09-13 19:52:27 +0000271 BlitMaskBench(SkCanvas::PointMode mode,
reed@google.com981d4792011-03-09 12:55:47 +0000272 BlitMaskBench::kMaskType type, const char* name) :
mtklein@google.com410e6e82013-09-13 19:52:27 +0000273 RectBench(2), fMode(mode), _type(type) {
reed@google.com981d4792011-03-09 12:55:47 +0000274 fName = name;
275 }
276
277protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700278 void onDraw(int loops, SkCanvas* canvas) override {
reed@google.com981d4792011-03-09 12:55:47 +0000279 SkScalar gSizes[] = {
280 SkIntToScalar(13), SkIntToScalar(24)
281 };
282 size_t sizes = SK_ARRAY_COUNT(gSizes);
283
mtklein@google.comc2897432013-09-10 19:23:38 +0000284 if (FLAGS_strokeWidth >= 0) {
mtklein@google.comb87bf832013-09-10 19:51:10 +0000285 gSizes[0] = (SkScalar)FLAGS_strokeWidth;
reed@google.com981d4792011-03-09 12:55:47 +0000286 sizes = 1;
287 }
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000288 SkRandom rand;
reed@google.com981d4792011-03-09 12:55:47 +0000289 SkColor color = 0xFF000000;
290 U8CPU alpha = 0xFF;
291 SkPaint paint;
292 paint.setStrokeCap(SkPaint::kRound_Cap);
293 if (_type == KMaskShader) {
294 SkBitmap srcBM;
reed6c225732014-06-09 19:52:07 -0700295 srcBM.allocN32Pixels(10, 1);
reed@google.com981d4792011-03-09 12:55:47 +0000296 srcBM.eraseColor(0xFF00FF00);
297
Mike Reed50acf8f2019-04-08 13:20:23 -0400298 paint.setShader(srcBM.makeShader());
reed@google.com981d4792011-03-09 12:55:47 +0000299 }
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000300 for (int loop = 0; loop < loops; loop++) {
mtklein@google.comc2897432013-09-10 19:23:38 +0000301 for (size_t i = 0; i < sizes; i++) {
302 switch (_type) {
303 case kMaskOpaque:
304 color = fColors[i];
305 alpha = 0xFF;
306 break;
307 case kMaskBlack:
308 alpha = 0xFF;
309 color = 0xFF000000;
310 break;
311 case kMaskColor:
312 color = fColors[i];
313 alpha = rand.nextU() & 255;
314 break;
315 case KMaskShader:
316 break;
317 }
318 paint.setStrokeWidth(gSizes[i]);
319 this->setupPaint(&paint);
320 paint.setColor(color);
321 paint.setAlpha(alpha);
Mike Kleine72e7732018-06-14 14:41:22 -0400322 canvas->drawPoints(fMode, N * 2, reinterpret_cast<SkPoint*>(fRects), paint);
mtklein@google.comc2897432013-09-10 19:23:38 +0000323 }
324 }
reed@google.com981d4792011-03-09 12:55:47 +0000325 }
Brian Salomondac5f6b2017-02-28 16:11:04 -0500326 const char* onGetName() override { return fName.c_str(); }
Brian Salomon3349c6f2017-03-01 09:49:58 -0500327
reed@google.com981d4792011-03-09 12:55:47 +0000328private:
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000329 typedef RectBench INHERITED;
330 kMaskType _type;
Brian Salomon3349c6f2017-03-01 09:49:58 -0500331 SkString fName;
reed@google.com981d4792011-03-09 12:55:47 +0000332};
333
Michael Ludwigdde8b552018-11-20 14:58:23 -0500334// AA rects
335DEF_BENCH(return new RectBench(1, 0, true);)
336DEF_BENCH(return new RectBench(1, 4, true);)
337DEF_BENCH(return new RectBench(3, 0, true);)
338DEF_BENCH(return new RectBench(3, 4, true);)
339// Non-AA rects
340DEF_BENCH(return new RectBench(1, 0, false);)
341DEF_BENCH(return new RectBench(1, 4, false);)
342DEF_BENCH(return new RectBench(3, 0, false);)
343DEF_BENCH(return new RectBench(3, 4, false);)
344
halcanary385fe4d2015-08-26 13:07:48 -0700345DEF_BENCH(return new OvalBench(1);)
346DEF_BENCH(return new OvalBench(3);)
347DEF_BENCH(return new OvalBench(1, 4);)
348DEF_BENCH(return new OvalBench(3, 4);)
349DEF_BENCH(return new RRectBench(1);)
350DEF_BENCH(return new RRectBench(1, 4);)
351DEF_BENCH(return new RRectBench(3);)
352DEF_BENCH(return new RRectBench(3, 4);)
353DEF_BENCH(return new PointsBench(SkCanvas::kPoints_PointMode, "points");)
354DEF_BENCH(return new PointsBench(SkCanvas::kLines_PointMode, "lines");)
355DEF_BENCH(return new PointsBench(SkCanvas::kPolygon_PointMode, "polygon");)
reed@google.com981d4792011-03-09 12:55:47 +0000356
halcanary385fe4d2015-08-26 13:07:48 -0700357DEF_BENCH(return new SrcModeRectBench();)
robertphillips@google.com370d8352013-05-02 13:57:52 +0000358
joshualitt8db65a62015-09-24 12:42:02 -0700359DEF_BENCH(return new TransparentRectBench();)
360
Michael Ludwigdde8b552018-11-20 14:58:23 -0500361DEF_BENCH(return new LocalCoordsRectBench(true);)
362DEF_BENCH(return new LocalCoordsRectBench(false);)
363
364// Perspective rects
365DEF_BENCH(return new RectBench(1, 0, true, true);)
366DEF_BENCH(return new RectBench(1, 0, false, true);)
367DEF_BENCH(return new LocalCoordsRectBench(true, true);)
368DEF_BENCH(return new LocalCoordsRectBench(false, true);)
369
reed@google.com981d4792011-03-09 12:55:47 +0000370/* init the blitmask bench
371 */
halcanary385fe4d2015-08-26 13:07:48 -0700372DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
373 BlitMaskBench::kMaskOpaque,
374 "maskopaque");)
375DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
376 BlitMaskBench::kMaskBlack,
377 "maskblack");)
378DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
379 BlitMaskBench::kMaskColor,
380 "maskcolor");)
381DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
382 BlitMaskBench::KMaskShader,
383 "maskshader");)