blob: 46a515de299705f5c7ce77222057929aee28e5bc [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 */
tfarinaf168b862014-06-19 12:32:29 -07007#include "Benchmark.h"
reed@android.combd700c32009-01-05 03:34:50 +00008#include "SkCanvas.h"
mtklein@google.comc2897432013-09-10 19:23:38 +00009#include "SkCommandLineFlags.h"
reed@android.combd700c32009-01-05 03:34:50 +000010#include "SkPaint.h"
11#include "SkRandom.h"
reed@google.com981d4792011-03-09 12:55:47 +000012#include "SkShader.h"
mtklein@google.comc2897432013-09-10 19:23:38 +000013#include "SkString.h"
14
15DEFINE_double(strokeWidth, -1.0, "If set, use this stroke width in RectBench.");
reed@android.combd700c32009-01-05 03:34:50 +000016
tfarinaf168b862014-06-19 12:32:29 -070017class RectBench : public Benchmark {
reed@android.combd700c32009-01-05 03:34:50 +000018public:
mike@reedtribe.org2ecead52011-04-02 13:37:23 +000019 int fShift, fStroke;
reed@android.combd700c32009-01-05 03:34:50 +000020 enum {
21 W = 640,
22 H = 480,
mtklein@google.comc2897432013-09-10 19:23:38 +000023 N = 300,
reed@android.combd700c32009-01-05 03:34:50 +000024 };
25 SkRect fRects[N];
26 SkColor fColors[N];
27
mtklein@google.com410e6e82013-09-13 19:52:27 +000028 RectBench(int shift, int stroke = 0)
29 : fShift(shift)
commit-bot@chromium.org000d7322013-12-05 12:07:44 +000030 , fStroke(stroke) {}
reed@google.com1fcd51e2011-01-05 15:50:27 +000031
reed@android.comd2c37442009-01-08 03:00:57 +000032 SkString fName;
33 const char* computeName(const char root[]) {
mike@reedtribe.org2ecead52011-04-02 13:37:23 +000034 fName.printf("%s_%d", root, fShift);
35 if (fStroke > 0) {
36 fName.appendf("_stroke_%d", fStroke);
37 }
reed@android.comd2c37442009-01-08 03:00:57 +000038 return fName.c_str();
39 }
reed@google.com1fcd51e2011-01-05 15:50:27 +000040
joshualitt7d4b4582015-09-24 08:08:23 -070041 bool isVisual() override { return true; }
42
reed@android.combd700c32009-01-05 03:34:50 +000043protected:
44 virtual void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) {
45 c->drawRect(r, p);
46 }
47
reed57b76712015-09-25 04:49:43 -070048 const char* onGetName() override { return computeName("rects"); }
commit-bot@chromium.org000d7322013-12-05 12:07:44 +000049
joshualitt8a6697a2015-09-30 12:11:07 -070050 void onDelayedSetup() override {
commit-bot@chromium.org000d7322013-12-05 12:07:44 +000051 SkRandom rand;
52 const SkScalar offset = SK_Scalar1/3;
53 for (int i = 0; i < N; i++) {
54 int x = rand.nextU() % W;
55 int y = rand.nextU() % H;
56 int w = rand.nextU() % W;
57 int h = rand.nextU() % H;
58 w >>= fShift;
59 h >>= fShift;
60 x -= w/2;
61 y -= h/2;
62 fRects[i].set(SkIntToScalar(x), SkIntToScalar(y),
63 SkIntToScalar(x+w), SkIntToScalar(y+h));
64 fRects[i].offset(offset, offset);
65 fColors[i] = rand.nextU() | 0xFF808080;
66 }
67 }
68
mtkleina1ebeb22015-10-01 09:43:39 -070069 void onDraw(int loops, SkCanvas* canvas) override {
reed@android.combd700c32009-01-05 03:34:50 +000070 SkPaint paint;
mike@reedtribe.org2ecead52011-04-02 13:37:23 +000071 if (fStroke > 0) {
72 paint.setStyle(SkPaint::kStroke_Style);
73 paint.setStrokeWidth(SkIntToScalar(fStroke));
74 }
commit-bot@chromium.org33614712013-12-03 18:17:16 +000075 for (int i = 0; i < loops; i++) {
mtklein@google.comc2897432013-09-10 19:23:38 +000076 paint.setColor(fColors[i % N]);
reed@android.com4bc19832009-01-19 20:08:35 +000077 this->setupPaint(&paint);
mtklein@google.comc2897432013-09-10 19:23:38 +000078 this->drawThisRect(canvas, fRects[i % N], paint);
reed@android.combd700c32009-01-05 03:34:50 +000079 }
80 }
reed@android.come9d00602009-09-02 21:12:42 +000081private:
tfarinaf168b862014-06-19 12:32:29 -070082 typedef Benchmark INHERITED;
reed@android.combd700c32009-01-05 03:34:50 +000083};
84
reed@google.com2d078b62012-11-15 19:52:07 +000085class SrcModeRectBench : public RectBench {
86public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000087 SrcModeRectBench() : INHERITED(1, 0) {
reedcfb6bdf2016-03-29 11:32:50 -070088 fMode = SkXfermode::Make(SkXfermode::kSrc_Mode);
reed@google.com2d078b62012-11-15 19:52:07 +000089 }
90
91protected:
mtklein36352bf2015-03-25 18:17:31 -070092 void setupPaint(SkPaint* paint) override {
reed@google.com2d078b62012-11-15 19:52:07 +000093 this->INHERITED::setupPaint(paint);
94 // srcmode is most interesting when we're not opaque
95 paint->setAlpha(0x80);
96 paint->setXfermode(fMode);
97 }
98
mtklein36352bf2015-03-25 18:17:31 -070099 const char* onGetName() override {
reed@google.com2d078b62012-11-15 19:52:07 +0000100 fName.set(this->INHERITED::onGetName());
101 fName.prepend("srcmode_");
102 return fName.c_str();
103 }
104
105private:
106 SkString fName;
reedcfb6bdf2016-03-29 11:32:50 -0700107 sk_sp<SkXfermode> fMode;
reed@google.com2d078b62012-11-15 19:52:07 +0000108
109 typedef RectBench INHERITED;
110};
111
joshualitt8db65a62015-09-24 12:42:02 -0700112class TransparentRectBench : public RectBench {
113public:
114 TransparentRectBench() : INHERITED(1, 0) {}
115
116protected:
117 void setupPaint(SkPaint* paint) override {
118 this->INHERITED::setupPaint(paint);
119 // draw non opaque rect
120 paint->setAlpha(0x80);
121 }
122
123 const char* onGetName() override {
124 fName.set(this->INHERITED::onGetName());
125 fName.prepend("transparent_");
126 return fName.c_str();
127 }
128
129private:
130 SkString fName;
131
132 typedef RectBench INHERITED;
133};
134
135
reed@android.combd700c32009-01-05 03:34:50 +0000136class OvalBench : public RectBench {
reed@android.comd2c37442009-01-08 03:00:57 +0000137public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000138 OvalBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
reed@android.combd700c32009-01-05 03:34:50 +0000139protected:
reed57b76712015-09-25 04:49:43 -0700140 void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override {
reed@android.combd700c32009-01-05 03:34:50 +0000141 c->drawOval(r, p);
142 }
reed57b76712015-09-25 04:49:43 -0700143 const char* onGetName() override { return computeName("ovals"); }
reed@android.combd700c32009-01-05 03:34:50 +0000144};
145
146class RRectBench : public RectBench {
reed@android.comd2c37442009-01-08 03:00:57 +0000147public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000148 RRectBench(int shift, int stroke = 0) : RectBench(shift, stroke) {}
reed@android.combd700c32009-01-05 03:34:50 +0000149protected:
reed57b76712015-09-25 04:49:43 -0700150 void drawThisRect(SkCanvas* c, const SkRect& r, const SkPaint& p) override {
reed@android.combd700c32009-01-05 03:34:50 +0000151 c->drawRoundRect(r, r.width() / 4, r.height() / 4, p);
152 }
reed57b76712015-09-25 04:49:43 -0700153 const char* onGetName() override { return computeName("rrects"); }
reed@android.combd700c32009-01-05 03:34:50 +0000154};
155
156class PointsBench : public RectBench {
157public:
158 SkCanvas::PointMode fMode;
159 const char* fName;
160
mtklein@google.com410e6e82013-09-13 19:52:27 +0000161 PointsBench(SkCanvas::PointMode mode, const char* name)
162 : RectBench(2)
163 , fMode(mode) {
reed@android.combd700c32009-01-05 03:34:50 +0000164 fName = name;
165 }
166
167protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700168 void onDraw(int loops, SkCanvas* canvas) override {
agl@chromium.org652807b2010-04-27 15:47:34 +0000169 SkScalar gSizes[] = {
reed@android.combd700c32009-01-05 03:34:50 +0000170 SkIntToScalar(7), 0
171 };
agl@chromium.org652807b2010-04-27 15:47:34 +0000172 size_t sizes = SK_ARRAY_COUNT(gSizes);
173
mtklein@google.comc2897432013-09-10 19:23:38 +0000174 if (FLAGS_strokeWidth >= 0) {
mtklein@google.comb87bf832013-09-10 19:51:10 +0000175 gSizes[0] = (SkScalar)FLAGS_strokeWidth;
agl@chromium.org652807b2010-04-27 15:47:34 +0000176 sizes = 1;
177 }
reed@android.combd700c32009-01-05 03:34:50 +0000178
179 SkPaint paint;
reed@android.combd700c32009-01-05 03:34:50 +0000180 paint.setStrokeCap(SkPaint::kRound_Cap);
agl@chromium.org652807b2010-04-27 15:47:34 +0000181
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000182 for (int loop = 0; loop < loops; loop++) {
mtklein@google.comc2897432013-09-10 19:23:38 +0000183 for (size_t i = 0; i < sizes; i++) {
184 paint.setStrokeWidth(gSizes[i]);
185 this->setupPaint(&paint);
186 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
187 paint.setColor(fColors[i % N]);
188 }
reed@android.combd700c32009-01-05 03:34:50 +0000189 }
190 }
reed57b76712015-09-25 04:49:43 -0700191 const char* onGetName() override { return fName; }
reed@android.combd700c32009-01-05 03:34:50 +0000192};
193
reed@google.com981d4792011-03-09 12:55:47 +0000194/*******************************************************************************
195 * to bench BlitMask [Opaque, Black, color, shader]
196 *******************************************************************************/
197
198class BlitMaskBench : public RectBench {
199public:
200 enum kMaskType {
201 kMaskOpaque = 0,
202 kMaskBlack,
203 kMaskColor,
204 KMaskShader
205 };
206 SkCanvas::PointMode fMode;
207 const char* fName;
208
mtklein@google.com410e6e82013-09-13 19:52:27 +0000209 BlitMaskBench(SkCanvas::PointMode mode,
reed@google.com981d4792011-03-09 12:55:47 +0000210 BlitMaskBench::kMaskType type, const char* name) :
mtklein@google.com410e6e82013-09-13 19:52:27 +0000211 RectBench(2), fMode(mode), _type(type) {
reed@google.com981d4792011-03-09 12:55:47 +0000212 fName = name;
213 }
214
215protected:
mtkleina1ebeb22015-10-01 09:43:39 -0700216 void onDraw(int loops, SkCanvas* canvas) override {
reed@google.com981d4792011-03-09 12:55:47 +0000217 SkScalar gSizes[] = {
218 SkIntToScalar(13), SkIntToScalar(24)
219 };
220 size_t sizes = SK_ARRAY_COUNT(gSizes);
221
mtklein@google.comc2897432013-09-10 19:23:38 +0000222 if (FLAGS_strokeWidth >= 0) {
mtklein@google.comb87bf832013-09-10 19:51:10 +0000223 gSizes[0] = (SkScalar)FLAGS_strokeWidth;
reed@google.com981d4792011-03-09 12:55:47 +0000224 sizes = 1;
225 }
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000226 SkRandom rand;
reed@google.com981d4792011-03-09 12:55:47 +0000227 SkColor color = 0xFF000000;
228 U8CPU alpha = 0xFF;
229 SkPaint paint;
230 paint.setStrokeCap(SkPaint::kRound_Cap);
231 if (_type == KMaskShader) {
232 SkBitmap srcBM;
reed6c225732014-06-09 19:52:07 -0700233 srcBM.allocN32Pixels(10, 1);
reed@google.com981d4792011-03-09 12:55:47 +0000234 srcBM.eraseColor(0xFF00FF00);
235
reedc6f28f72016-03-14 12:22:10 -0700236 paint.setShader(SkShader::MakeBitmapShader(srcBM, SkShader::kClamp_TileMode,
237 SkShader::kClamp_TileMode));
reed@google.com981d4792011-03-09 12:55:47 +0000238 }
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000239 for (int loop = 0; loop < loops; loop++) {
mtklein@google.comc2897432013-09-10 19:23:38 +0000240 for (size_t i = 0; i < sizes; i++) {
241 switch (_type) {
242 case kMaskOpaque:
243 color = fColors[i];
244 alpha = 0xFF;
245 break;
246 case kMaskBlack:
247 alpha = 0xFF;
248 color = 0xFF000000;
249 break;
250 case kMaskColor:
251 color = fColors[i];
252 alpha = rand.nextU() & 255;
253 break;
254 case KMaskShader:
255 break;
256 }
257 paint.setStrokeWidth(gSizes[i]);
258 this->setupPaint(&paint);
259 paint.setColor(color);
260 paint.setAlpha(alpha);
261 canvas->drawPoints(fMode, N * 2, SkTCast<SkPoint*>(fRects), paint);
262 }
263 }
reed@google.com981d4792011-03-09 12:55:47 +0000264 }
reed57b76712015-09-25 04:49:43 -0700265 const char* onGetName() override { return fName; }
reed@google.com981d4792011-03-09 12:55:47 +0000266private:
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000267 typedef RectBench INHERITED;
268 kMaskType _type;
reed@google.com981d4792011-03-09 12:55:47 +0000269};
270
halcanary385fe4d2015-08-26 13:07:48 -0700271DEF_BENCH(return new RectBench(1);)
272DEF_BENCH(return new RectBench(1, 4);)
273DEF_BENCH(return new RectBench(3);)
274DEF_BENCH(return new RectBench(3, 4);)
275DEF_BENCH(return new OvalBench(1);)
276DEF_BENCH(return new OvalBench(3);)
277DEF_BENCH(return new OvalBench(1, 4);)
278DEF_BENCH(return new OvalBench(3, 4);)
279DEF_BENCH(return new RRectBench(1);)
280DEF_BENCH(return new RRectBench(1, 4);)
281DEF_BENCH(return new RRectBench(3);)
282DEF_BENCH(return new RRectBench(3, 4);)
283DEF_BENCH(return new PointsBench(SkCanvas::kPoints_PointMode, "points");)
284DEF_BENCH(return new PointsBench(SkCanvas::kLines_PointMode, "lines");)
285DEF_BENCH(return new PointsBench(SkCanvas::kPolygon_PointMode, "polygon");)
reed@google.com981d4792011-03-09 12:55:47 +0000286
halcanary385fe4d2015-08-26 13:07:48 -0700287DEF_BENCH(return new SrcModeRectBench();)
robertphillips@google.com370d8352013-05-02 13:57:52 +0000288
joshualitt8db65a62015-09-24 12:42:02 -0700289DEF_BENCH(return new TransparentRectBench();)
290
reed@google.com981d4792011-03-09 12:55:47 +0000291/* init the blitmask bench
292 */
halcanary385fe4d2015-08-26 13:07:48 -0700293DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
294 BlitMaskBench::kMaskOpaque,
295 "maskopaque");)
296DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
297 BlitMaskBench::kMaskBlack,
298 "maskblack");)
299DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
300 BlitMaskBench::kMaskColor,
301 "maskcolor");)
302DEF_BENCH(return new BlitMaskBench(SkCanvas::kPoints_PointMode,
303 BlitMaskBench::KMaskShader,
304 "maskshader");)