blob: de8be6c75881773bbf12a5b631893dc6c0e3abac [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 */
bungemand3ebb482015-08-05 13:57:49 -07007
tfarinaf168b862014-06-19 12:32:29 -07008#include "Benchmark.h"
reed@google.comd34658a2011-04-11 13:12:51 +00009#include "SkBitmap.h"
10#include "SkCanvas.h"
11#include "SkColorPriv.h"
12#include "SkPaint.h"
bungemand3ebb482015-08-05 13:57:49 -070013#include "SkPath.h"
tomhudson@google.com6e8d3352011-06-22 17:16:35 +000014#include "SkRandom.h"
reed@google.comd34658a2011-04-11 13:12:51 +000015#include "SkShader.h"
16#include "SkString.h"
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +000017#include "SkTArray.h"
18
reed@google.comd34658a2011-04-11 13:12:51 +000019enum Flags {
20 kStroke_Flag = 1 << 0,
21 kBig_Flag = 1 << 1
22};
23
24#define FLAGS00 Flags(0)
25#define FLAGS01 Flags(kStroke_Flag)
26#define FLAGS10 Flags(kBig_Flag)
27#define FLAGS11 Flags(kStroke_Flag | kBig_Flag)
28
tfarinaf168b862014-06-19 12:32:29 -070029class PathBench : public Benchmark {
reed@google.comd34658a2011-04-11 13:12:51 +000030 SkPaint fPaint;
31 SkString fName;
32 Flags fFlags;
reed@google.comd34658a2011-04-11 13:12:51 +000033public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000034 PathBench(Flags flags) : fFlags(flags) {
reed@google.comd34658a2011-04-11 13:12:51 +000035 fPaint.setStyle(flags & kStroke_Flag ? SkPaint::kStroke_Style :
36 SkPaint::kFill_Style);
37 fPaint.setStrokeWidth(SkIntToScalar(5));
38 fPaint.setStrokeJoin(SkPaint::kBevel_Join);
39 }
40
41 virtual void appendName(SkString*) = 0;
42 virtual void makePath(SkPath*) = 0;
tomhudson@google.com6e8d3352011-06-22 17:16:35 +000043 virtual int complexity() { return 0; }
reed@google.comd34658a2011-04-11 13:12:51 +000044
45protected:
mtklein36352bf2015-03-25 18:17:31 -070046 const char* onGetName() override {
reed@google.comd34658a2011-04-11 13:12:51 +000047 fName.printf("path_%s_%s_",
48 fFlags & kStroke_Flag ? "stroke" : "fill",
49 fFlags & kBig_Flag ? "big" : "small");
50 this->appendName(&fName);
51 return fName.c_str();
52 }
53
mtkleina1ebeb22015-10-01 09:43:39 -070054 void onDraw(int loops, SkCanvas* canvas) override {
reed@google.comd34658a2011-04-11 13:12:51 +000055 SkPaint paint(fPaint);
56 this->setupPaint(&paint);
57
58 SkPath path;
59 this->makePath(&path);
60 if (fFlags & kBig_Flag) {
robertphillips1d24b8d2015-03-26 19:57:08 -070061 const SkMatrix m = SkMatrix::MakeScale(SkIntToScalar(10), SkIntToScalar(10));
reed@google.comd34658a2011-04-11 13:12:51 +000062 path.transform(m);
63 }
64
commit-bot@chromium.org33614712013-12-03 18:17:16 +000065 int count = loops;
reed@google.comd34658a2011-04-11 13:12:51 +000066 if (fFlags & kBig_Flag) {
67 count >>= 2;
68 }
tomhudson@google.com6e8d3352011-06-22 17:16:35 +000069 count >>= (3 * complexity());
reed@google.comd34658a2011-04-11 13:12:51 +000070
71 for (int i = 0; i < count; i++) {
72 canvas->drawPath(path, paint);
73 }
74 }
75
76private:
tfarinaf168b862014-06-19 12:32:29 -070077 typedef Benchmark INHERITED;
reed@google.comd34658a2011-04-11 13:12:51 +000078};
79
80class TrianglePathBench : public PathBench {
81public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000082 TrianglePathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +000083
mtklein36352bf2015-03-25 18:17:31 -070084 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +000085 name->append("triangle");
86 }
mtklein36352bf2015-03-25 18:17:31 -070087 void makePath(SkPath* path) override {
reed@google.comd34658a2011-04-11 13:12:51 +000088 static const int gCoord[] = {
89 10, 10, 15, 5, 20, 20
90 };
91 path->moveTo(SkIntToScalar(gCoord[0]), SkIntToScalar(gCoord[1]));
92 path->lineTo(SkIntToScalar(gCoord[2]), SkIntToScalar(gCoord[3]));
93 path->lineTo(SkIntToScalar(gCoord[4]), SkIntToScalar(gCoord[5]));
94 path->close();
95 }
96private:
97 typedef PathBench INHERITED;
98};
99
100class RectPathBench : public PathBench {
101public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000102 RectPathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000103
mtklein36352bf2015-03-25 18:17:31 -0700104 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000105 name->append("rect");
106 }
mtklein36352bf2015-03-25 18:17:31 -0700107 void makePath(SkPath* path) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000108 SkRect r = { 10, 10, 20, 20 };
109 path->addRect(r);
110 }
111private:
112 typedef PathBench INHERITED;
113};
114
liyuqiana27f6692016-06-20 14:05:27 -0700115class RotatedRectBench : public PathBench {
116public:
117 RotatedRectBench(Flags flags, bool aa, int degrees) : INHERITED(flags) {
118 fAA = aa;
119 fDegrees = degrees;
120 }
121
122 void appendName(SkString* name) override {
123 SkString suffix;
124 suffix.printf("rotated_rect_%s_%d", fAA ? "aa" : "noaa", fDegrees);
125 name->append(suffix);
126 }
127
128 void makePath(SkPath* path) override {
129 SkRect r = { 10, 10, 20, 20 };
130 path->addRect(r);
131 SkMatrix rotateMatrix;
132 rotateMatrix.setRotate((SkScalar)fDegrees);
133 path->transform(rotateMatrix);
134 }
135
136 virtual void setupPaint(SkPaint* paint) override {
137 PathBench::setupPaint(paint);
138 paint->setAntiAlias(fAA);
139 }
140private:
141 typedef PathBench INHERITED;
142 int fDegrees;
143 bool fAA;
144};
145
reed@google.comd34658a2011-04-11 13:12:51 +0000146class OvalPathBench : public PathBench {
147public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000148 OvalPathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000149
mtklein36352bf2015-03-25 18:17:31 -0700150 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000151 name->append("oval");
152 }
mtklein36352bf2015-03-25 18:17:31 -0700153 void makePath(SkPath* path) override {
jvanverth@google.come2bfd8b2013-01-24 15:45:35 +0000154 SkRect r = { 10, 10, 23, 20 };
reed@google.comd34658a2011-04-11 13:12:51 +0000155 path->addOval(r);
156 }
157private:
158 typedef PathBench INHERITED;
159};
160
bsalomon@google.com1647a192012-04-11 15:34:46 +0000161class CirclePathBench: public PathBench {
162public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000163 CirclePathBench(Flags flags) : INHERITED(flags) {}
bsalomon@google.com1647a192012-04-11 15:34:46 +0000164
mtklein36352bf2015-03-25 18:17:31 -0700165 void appendName(SkString* name) override {
bsalomon@google.com1647a192012-04-11 15:34:46 +0000166 name->append("circle");
167 }
mtklein36352bf2015-03-25 18:17:31 -0700168 void makePath(SkPath* path) override {
bsalomon@google.com1647a192012-04-11 15:34:46 +0000169 path->addCircle(SkIntToScalar(20), SkIntToScalar(20),
170 SkIntToScalar(10));
171 }
172private:
173 typedef PathBench INHERITED;
174};
175
Yuqian Li8eedbfc2017-01-11 13:55:49 +0000176class NonAACirclePathBench: public CirclePathBench {
177public:
178 NonAACirclePathBench(Flags flags) : INHERITED(flags) {}
179
180 void appendName(SkString* name) override {
181 name->append("nonaacircle");
182 }
183
184 void setupPaint(SkPaint* paint) override {
185 CirclePathBench::setupPaint(paint);
186 paint->setAntiAlias(false);
187 }
188
189private:
190 typedef CirclePathBench INHERITED;
191};
192
Yuqian Li131c1fb2016-12-12 16:24:47 -0500193// Test max speedup of Analytic AA for concave paths
194class AAAConcavePathBench : public PathBench {
195public:
196 AAAConcavePathBench(Flags flags) : INHERITED(flags) {}
197
198 void appendName(SkString* name) override {
199 name->append("concave_aaa");
200 }
201
202 void makePath(SkPath* path) override {
203 path->moveTo(10, 10);
204 path->lineTo(15, 10);
205 path->lineTo(15, 5);
206 path->lineTo(40, 40);
207 path->close();
208 }
209
210private:
211 typedef PathBench INHERITED;
212};
213
214// Test max speedup of Analytic AA for convex paths
215class AAAConvexPathBench : public PathBench {
216public:
217 AAAConvexPathBench(Flags flags) : INHERITED(flags) {}
218
219 void appendName(SkString* name) override {
220 name->append("convex_aaa");
221 }
222
223 void makePath(SkPath* path) override {
224 path->moveTo(10, 10);
225 path->lineTo(15, 10);
226 path->lineTo(40, 50);
227 path->close();
228 }
229
230private:
231 typedef PathBench INHERITED;
232};
233
reed@google.comd34658a2011-04-11 13:12:51 +0000234class SawToothPathBench : public PathBench {
235public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000236 SawToothPathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000237
mtklein36352bf2015-03-25 18:17:31 -0700238 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000239 name->append("sawtooth");
240 }
mtkleinf0599002015-07-13 06:18:39 -0700241 void makePath(SkPath* path) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000242 SkScalar x = SkIntToScalar(20);
243 SkScalar y = SkIntToScalar(20);
244 const SkScalar x0 = x;
245 const SkScalar dx = SK_Scalar1 * 5;
246 const SkScalar dy = SK_Scalar1 * 10;
247
248 path->moveTo(x, y);
249 for (int i = 0; i < 32; i++) {
250 x += dx;
251 path->lineTo(x, y - dy);
252 x += dx;
253 path->lineTo(x, y + dy);
254 }
255 path->lineTo(x, y + 2 * dy);
256 path->lineTo(x0, y + 2 * dy);
257 path->close();
258 }
mtklein36352bf2015-03-25 18:17:31 -0700259 int complexity() override { return 1; }
reed@google.comd34658a2011-04-11 13:12:51 +0000260private:
261 typedef PathBench INHERITED;
262};
263
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000264class LongCurvedPathBench : public PathBench {
265public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000266 LongCurvedPathBench(Flags flags) : INHERITED(flags) {}
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000267
mtklein36352bf2015-03-25 18:17:31 -0700268 void appendName(SkString* name) override {
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000269 name->append("long_curved");
270 }
mtklein36352bf2015-03-25 18:17:31 -0700271 void makePath(SkPath* path) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000272 SkRandom rand (12);
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000273 int i;
274 for (i = 0; i < 100; i++) {
275 path->quadTo(SkScalarMul(rand.nextUScalar1(), SkIntToScalar(640)),
276 SkScalarMul(rand.nextUScalar1(), SkIntToScalar(480)),
277 SkScalarMul(rand.nextUScalar1(), SkIntToScalar(640)),
278 SkScalarMul(rand.nextUScalar1(), SkIntToScalar(480)));
279 }
280 path->close();
281 }
mtklein36352bf2015-03-25 18:17:31 -0700282 int complexity() override { return 2; }
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000283private:
284 typedef PathBench INHERITED;
285};
286
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000287class LongLinePathBench : public PathBench {
288public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000289 LongLinePathBench(Flags flags) : INHERITED(flags) {}
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000290
mtklein36352bf2015-03-25 18:17:31 -0700291 void appendName(SkString* name) override {
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000292 name->append("long_line");
293 }
mtklein36352bf2015-03-25 18:17:31 -0700294 void makePath(SkPath* path) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000295 SkRandom rand;
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000296 path->moveTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
297 for (size_t i = 1; i < 100; i++) {
298 path->lineTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
299 }
300 }
mtklein36352bf2015-03-25 18:17:31 -0700301 int complexity() override { return 2; }
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000302private:
303 typedef PathBench INHERITED;
304};
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000305
tfarinaf168b862014-06-19 12:32:29 -0700306class RandomPathBench : public Benchmark {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000307public:
mtklein36352bf2015-03-25 18:17:31 -0700308 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000309 return backend == kNonRendering_Backend;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000310 }
311
312protected:
313 void createData(int minVerbs,
314 int maxVerbs,
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000315 bool allowMoves = true,
halcanary96fcdcc2015-08-27 07:41:13 -0700316 SkRect* bounds = nullptr) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000317 SkRect tempBounds;
halcanary96fcdcc2015-08-27 07:41:13 -0700318 if (nullptr == bounds) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000319 tempBounds.setXYWH(0, 0, SK_Scalar1, SK_Scalar1);
320 bounds = &tempBounds;
321 }
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000322 fVerbCnts.reset(kNumVerbCnts);
323 for (int i = 0; i < kNumVerbCnts; ++i) {
324 fVerbCnts[i] = fRandom.nextRangeU(minVerbs, maxVerbs + 1);
325 }
326 fVerbs.reset(kNumVerbs);
327 for (int i = 0; i < kNumVerbs; ++i) {
328 do {
329 fVerbs[i] = static_cast<SkPath::Verb>(fRandom.nextULessThan(SkPath::kDone_Verb));
330 } while (!allowMoves && SkPath::kMove_Verb == fVerbs[i]);
331 }
332 fPoints.reset(kNumPoints);
333 for (int i = 0; i < kNumPoints; ++i) {
334 fPoints[i].set(fRandom.nextRangeScalar(bounds->fLeft, bounds->fRight),
335 fRandom.nextRangeScalar(bounds->fTop, bounds->fBottom));
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000336 }
337 this->restartMakingPaths();
338 }
339
340 void restartMakingPaths() {
341 fCurrPath = 0;
342 fCurrVerb = 0;
343 fCurrPoint = 0;
344 }
345
346 void makePath(SkPath* path) {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000347 int vCount = fVerbCnts[(fCurrPath++) & (kNumVerbCnts - 1)];
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000348 for (int v = 0; v < vCount; ++v) {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000349 int verb = fVerbs[(fCurrVerb++) & (kNumVerbs - 1)];
350 switch (verb) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000351 case SkPath::kMove_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000352 path->moveTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000353 break;
354 case SkPath::kLine_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000355 path->lineTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000356 break;
357 case SkPath::kQuad_Verb:
bsalomon@google.com373ebc62012-09-26 13:08:56 +0000358 path->quadTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
359 fPoints[(fCurrPoint + 1) & (kNumPoints - 1)]);
360 fCurrPoint += 2;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000361 break;
reed@google.com277c3f82013-05-31 15:17:50 +0000362 case SkPath::kConic_Verb:
363 path->conicTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
364 fPoints[(fCurrPoint + 1) & (kNumPoints - 1)],
365 SK_ScalarHalf);
366 fCurrPoint += 2;
367 break;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000368 case SkPath::kCubic_Verb:
bsalomon@google.com373ebc62012-09-26 13:08:56 +0000369 path->cubicTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
370 fPoints[(fCurrPoint + 1) & (kNumPoints - 1)],
371 fPoints[(fCurrPoint + 2) & (kNumPoints - 1)]);
372 fCurrPoint += 3;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000373 break;
374 case SkPath::kClose_Verb:
375 path->close();
376 break;
377 default:
378 SkDEBUGFAIL("Unexpected path verb");
379 break;
380 }
381 }
382 }
383
384 void finishedMakingPaths() {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000385 fVerbCnts.reset(0);
386 fVerbs.reset(0);
387 fPoints.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000388 }
389
390private:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000391 enum {
392 // these should all be pow 2
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000393 kNumVerbCnts = 1 << 5,
394 kNumVerbs = 1 << 5,
395 kNumPoints = 1 << 5,
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000396 };
397 SkAutoTArray<int> fVerbCnts;
398 SkAutoTArray<SkPath::Verb> fVerbs;
399 SkAutoTArray<SkPoint> fPoints;
400 int fCurrPath;
401 int fCurrVerb;
402 int fCurrPoint;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000403 SkRandom fRandom;
tfarinaf168b862014-06-19 12:32:29 -0700404 typedef Benchmark INHERITED;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000405};
406
407class PathCreateBench : public RandomPathBench {
408public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000409 PathCreateBench() {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000410 }
411
412protected:
mtklein36352bf2015-03-25 18:17:31 -0700413 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000414 return "path_create";
415 }
416
joshualitt8a6697a2015-09-30 12:11:07 -0700417 void onDelayedSetup() override {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000418 this->createData(10, 100);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000419 }
420
mtkleina1ebeb22015-10-01 09:43:39 -0700421 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000422 for (int i = 0; i < loops; ++i) {
commit-bot@chromium.org8f881172014-01-06 20:19:14 +0000423 if (i % 1000 == 0) {
424 fPath.reset(); // PathRef memory can grow without bound otherwise.
425 }
426 this->makePath(&fPath);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000427 }
428 this->restartMakingPaths();
429 }
430
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000431private:
commit-bot@chromium.org8f881172014-01-06 20:19:14 +0000432 SkPath fPath;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000433
434 typedef RandomPathBench INHERITED;
435};
436
437class PathCopyBench : public RandomPathBench {
438public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000439 PathCopyBench() {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000440 }
441
442protected:
mtklein36352bf2015-03-25 18:17:31 -0700443 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000444 return "path_copy";
445 }
joshualitt8a6697a2015-09-30 12:11:07 -0700446 void onDelayedSetup() override {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000447 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000448 fPaths.reset(kPathCnt);
449 fCopies.reset(kPathCnt);
450 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000451 this->makePath(&fPaths[i]);
452 }
453 this->finishedMakingPaths();
454 }
mtkleina1ebeb22015-10-01 09:43:39 -0700455 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000456 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000457 int idx = i & (kPathCnt - 1);
458 fCopies[idx] = fPaths[idx];
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000459 }
460 }
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000461
462private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000463 enum {
464 // must be a pow 2
465 kPathCnt = 1 << 5,
466 };
467 SkAutoTArray<SkPath> fPaths;
468 SkAutoTArray<SkPath> fCopies;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000469
470 typedef RandomPathBench INHERITED;
471};
472
473class PathTransformBench : public RandomPathBench {
474public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000475 PathTransformBench(bool inPlace) : fInPlace(inPlace) {}
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000476
477protected:
mtklein36352bf2015-03-25 18:17:31 -0700478 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000479 return fInPlace ? "path_transform_in_place" : "path_transform_copy";
480 }
481
joshualitt8a6697a2015-09-30 12:11:07 -0700482 void onDelayedSetup() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000483 fMatrix.setScale(5 * SK_Scalar1, 6 * SK_Scalar1);
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000484 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000485 fPaths.reset(kPathCnt);
486 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000487 this->makePath(&fPaths[i]);
488 }
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000489 this->finishedMakingPaths();
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000490 if (!fInPlace) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000491 fTransformed.reset(kPathCnt);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000492 }
493 }
494
mtkleina1ebeb22015-10-01 09:43:39 -0700495 void onDraw(int loops, SkCanvas*) override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000496 if (fInPlace) {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000497 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000498 fPaths[i & (kPathCnt - 1)].transform(fMatrix);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000499 }
500 } else {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000501 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000502 int idx = i & (kPathCnt - 1);
503 fPaths[idx].transform(fMatrix, &fTransformed[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000504 }
505 }
506 }
507
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000508private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000509 enum {
510 // must be a pow 2
511 kPathCnt = 1 << 5,
512 };
513 SkAutoTArray<SkPath> fPaths;
514 SkAutoTArray<SkPath> fTransformed;
515
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000516 SkMatrix fMatrix;
517 bool fInPlace;
518 typedef RandomPathBench INHERITED;
519};
520
521class PathEqualityBench : public RandomPathBench {
522public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000523 PathEqualityBench() { }
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000524
525protected:
mtklein36352bf2015-03-25 18:17:31 -0700526 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000527 return "path_equality_50%";
528 }
529
joshualitt8a6697a2015-09-30 12:11:07 -0700530 void onDelayedSetup() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000531 fParity = 0;
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000532 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000533 fPaths.reset(kPathCnt);
534 fCopies.reset(kPathCnt);
535 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000536 this->makePath(&fPaths[i]);
537 fCopies[i] = fPaths[i];
538 }
539 this->finishedMakingPaths();
540 }
541
mtkleina1ebeb22015-10-01 09:43:39 -0700542 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000543 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000544 int idx = i & (kPathCnt - 1);
545 fParity ^= (fPaths[idx] == fCopies[idx & ~0x1]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000546 }
547 }
548
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000549private:
550 bool fParity; // attempt to keep compiler from optimizing out the ==
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000551 enum {
552 // must be a pow 2
553 kPathCnt = 1 << 5,
554 };
555 SkAutoTArray<SkPath> fPaths;
556 SkAutoTArray<SkPath> fCopies;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000557 typedef RandomPathBench INHERITED;
558};
559
560class SkBench_AddPathTest : public RandomPathBench {
561public:
562 enum AddType {
563 kAdd_AddType,
564 kAddTrans_AddType,
565 kAddMatrix_AddType,
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000566 kReverseAdd_AddType,
567 kReversePathTo_AddType,
568 };
569
mtklein@google.com410e6e82013-09-13 19:52:27 +0000570 SkBench_AddPathTest(AddType type) : fType(type) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000571 fMatrix.setRotate(60 * SK_Scalar1);
572 }
573
574protected:
mtklein36352bf2015-03-25 18:17:31 -0700575 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000576 switch (fType) {
577 case kAdd_AddType:
578 return "path_add_path";
579 case kAddTrans_AddType:
580 return "path_add_path_trans";
581 case kAddMatrix_AddType:
582 return "path_add_path_matrix";
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000583 case kReverseAdd_AddType:
584 return "path_reverse_add_path";
585 case kReversePathTo_AddType:
586 return "path_reverse_path_to";
587 default:
588 SkDEBUGFAIL("Bad add type");
589 return "";
590 }
591 }
592
joshualitt8a6697a2015-09-30 12:11:07 -0700593 void onDelayedSetup() override {
commit-bot@chromium.orga1a097e2013-11-14 16:53:22 +0000594 // reversePathTo assumes a single contour path.
595 bool allowMoves = kReversePathTo_AddType != fType;
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000596 this->createData(10, 100, allowMoves);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000597 fPaths0.reset(kPathCnt);
598 fPaths1.reset(kPathCnt);
599 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000600 this->makePath(&fPaths0[i]);
601 this->makePath(&fPaths1[i]);
602 }
603 this->finishedMakingPaths();
604 }
605
mtkleina1ebeb22015-10-01 09:43:39 -0700606 void onDraw(int loops, SkCanvas*) override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000607 switch (fType) {
608 case kAdd_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000609 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000610 int idx = i & (kPathCnt - 1);
611 SkPath result = fPaths0[idx];
612 result.addPath(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000613 }
614 break;
615 case kAddTrans_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000616 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000617 int idx = i & (kPathCnt - 1);
618 SkPath result = fPaths0[idx];
619 result.addPath(fPaths1[idx], 2 * SK_Scalar1, 5 * SK_Scalar1);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000620 }
621 break;
622 case kAddMatrix_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000623 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000624 int idx = i & (kPathCnt - 1);
625 SkPath result = fPaths0[idx];
626 result.addPath(fPaths1[idx], fMatrix);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000627 }
628 break;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000629 case kReverseAdd_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000630 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000631 int idx = i & (kPathCnt - 1);
632 SkPath result = fPaths0[idx];
633 result.reverseAddPath(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000634 }
635 break;
636 case kReversePathTo_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000637 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000638 int idx = i & (kPathCnt - 1);
639 SkPath result = fPaths0[idx];
640 result.reversePathTo(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000641 }
642 break;
643 }
644 }
645
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000646private:
647 AddType fType; // or reverseAddPath
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000648 enum {
649 // must be a pow 2
650 kPathCnt = 1 << 5,
651 };
652 SkAutoTArray<SkPath> fPaths0;
653 SkAutoTArray<SkPath> fPaths1;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000654 SkMatrix fMatrix;
655 typedef RandomPathBench INHERITED;
656};
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000657
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000658
tfarinaf168b862014-06-19 12:32:29 -0700659class CirclesBench : public Benchmark {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000660protected:
661 SkString fName;
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000662 Flags fFlags;
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000663
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000664public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000665 CirclesBench(Flags flags) : fFlags(flags) {
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000666 fName.printf("circles_%s", fFlags & kStroke_Flag ? "stroke" : "fill");
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000667 }
668
669protected:
mtklein36352bf2015-03-25 18:17:31 -0700670 const char* onGetName() override {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000671 return fName.c_str();
672 }
673
mtkleina1ebeb22015-10-01 09:43:39 -0700674 void onDraw(int loops, SkCanvas* canvas) override {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000675 SkPaint paint;
676
677 paint.setColor(SK_ColorBLACK);
678 paint.setAntiAlias(true);
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000679 if (fFlags & kStroke_Flag) {
680 paint.setStyle(SkPaint::kStroke_Style);
681 }
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000682
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000683 SkRandom rand;
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000684
685 SkRect r;
686
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000687 for (int i = 0; i < loops; ++i) {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000688 SkScalar radius = rand.nextUScalar1() * 3;
689 r.fLeft = rand.nextUScalar1() * 300;
690 r.fTop = rand.nextUScalar1() * 300;
691 r.fRight = r.fLeft + 2 * radius;
692 r.fBottom = r.fTop + 2 * radius;
693
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000694 if (fFlags & kStroke_Flag) {
695 paint.setStrokeWidth(rand.nextUScalar1() * 5.0f);
696 }
697
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000698 SkPath temp;
699
700 // mimic how Chrome does circles
701 temp.arcTo(r, 0, 0, false);
702 temp.addOval(r, SkPath::kCCW_Direction);
703 temp.arcTo(r, 360, 0, true);
704 temp.close();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000705
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000706 canvas->drawPath(temp, paint);
707 }
708 }
709
710private:
tfarinaf168b862014-06-19 12:32:29 -0700711 typedef Benchmark INHERITED;
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000712};
713
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000714
robertphillips@google.com158618e2012-10-23 16:56:56 +0000715// Chrome creates its own round rects with each corner possibly being different.
716// In its "zero radius" incarnation it creates degenerate round rects.
skia.committer@gmail.com1e34ff72012-10-24 02:01:24 +0000717// Note: PathTest::test_arb_round_rect_is_convex and
robertphillips@google.com158618e2012-10-23 16:56:56 +0000718// test_arb_zero_rad_round_rect_is_rect perform almost exactly
robertphillips@google.comb95eaa82012-10-18 15:26:12 +0000719// the same test (but with no drawing)
tfarinaf168b862014-06-19 12:32:29 -0700720class ArbRoundRectBench : public Benchmark {
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000721protected:
722 SkString fName;
723
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000724public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000725 ArbRoundRectBench(bool zeroRad) : fZeroRad(zeroRad) {
robertphillips@google.com158618e2012-10-23 16:56:56 +0000726 if (zeroRad) {
727 fName.printf("zeroradroundrect");
728 } else {
729 fName.printf("arbroundrect");
730 }
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000731 }
732
733protected:
mtklein36352bf2015-03-25 18:17:31 -0700734 const char* onGetName() override {
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000735 return fName.c_str();
736 }
737
skia.committer@gmail.com989a95e2012-10-18 02:01:23 +0000738 static void add_corner_arc(SkPath* path, const SkRect& rect,
739 SkScalar xIn, SkScalar yIn,
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000740 int startAngle)
741 {
742
743 SkScalar rx = SkMinScalar(rect.width(), xIn);
744 SkScalar ry = SkMinScalar(rect.height(), yIn);
745
746 SkRect arcRect;
747 arcRect.set(-rx, -ry, rx, ry);
748 switch (startAngle) {
749 case 0:
750 arcRect.offset(rect.fRight - arcRect.fRight, rect.fBottom - arcRect.fBottom);
751 break;
752 case 90:
753 arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fBottom - arcRect.fBottom);
754 break;
755 case 180:
756 arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fTop - arcRect.fTop);
757 break;
758 case 270:
759 arcRect.offset(rect.fRight - arcRect.fRight, rect.fTop - arcRect.fTop);
760 break;
761 default:
762 break;
763 }
764
765 path->arcTo(arcRect, SkIntToScalar(startAngle), SkIntToScalar(90), false);
766 }
767
skia.committer@gmail.com989a95e2012-10-18 02:01:23 +0000768 static void make_arb_round_rect(SkPath* path, const SkRect& r,
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000769 SkScalar xCorner, SkScalar yCorner) {
770 // we are lazy here and use the same x & y for each corner
771 add_corner_arc(path, r, xCorner, yCorner, 270);
772 add_corner_arc(path, r, xCorner, yCorner, 0);
773 add_corner_arc(path, r, xCorner, yCorner, 90);
774 add_corner_arc(path, r, xCorner, yCorner, 180);
robertphillips@google.com158618e2012-10-23 16:56:56 +0000775 path->close();
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000776
robertphillips@google.comb95eaa82012-10-18 15:26:12 +0000777 SkASSERT(path->isConvex());
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000778 }
779
mtkleina1ebeb22015-10-01 09:43:39 -0700780 void onDraw(int loops, SkCanvas* canvas) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000781 SkRandom rand;
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000782 SkRect r;
783
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000784 for (int i = 0; i < loops; ++i) {
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000785 SkPaint paint;
786 paint.setColor(0xff000000 | rand.nextU());
787 paint.setAntiAlias(true);
788
robertphillips@google.com158618e2012-10-23 16:56:56 +0000789 SkScalar size = rand.nextUScalar1() * 30;
790 if (size < SK_Scalar1) {
robertphillips@google.comb95eaa82012-10-18 15:26:12 +0000791 continue;
792 }
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000793 r.fLeft = rand.nextUScalar1() * 300;
794 r.fTop = rand.nextUScalar1() * 300;
robertphillips@google.com158618e2012-10-23 16:56:56 +0000795 r.fRight = r.fLeft + 2 * size;
796 r.fBottom = r.fTop + 2 * size;
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000797
798 SkPath temp;
799
robertphillips@google.com158618e2012-10-23 16:56:56 +0000800 if (fZeroRad) {
801 make_arb_round_rect(&temp, r, 0, 0);
802
halcanary96fcdcc2015-08-27 07:41:13 -0700803 SkASSERT(temp.isRect(nullptr));
robertphillips@google.com158618e2012-10-23 16:56:56 +0000804 } else {
805 make_arb_round_rect(&temp, r, r.width() / 10, r.height() / 15);
806 }
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000807
808 canvas->drawPath(temp, paint);
809 }
810 }
811
812private:
robertphillips@google.com158618e2012-10-23 16:56:56 +0000813 bool fZeroRad; // should 0 radius rounds rects be tested?
814
tfarinaf168b862014-06-19 12:32:29 -0700815 typedef Benchmark INHERITED;
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000816};
817
tfarinaf168b862014-06-19 12:32:29 -0700818class ConservativelyContainsBench : public Benchmark {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000819public:
820 enum Type {
821 kRect_Type,
822 kRoundRect_Type,
823 kOval_Type,
824 };
825
mtklein@google.com410e6e82013-09-13 19:52:27 +0000826 ConservativelyContainsBench(Type type) {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000827 fParity = false;
828 fName = "conservatively_contains_";
829 switch (type) {
830 case kRect_Type:
831 fName.append("rect");
832 fPath.addRect(kBaseRect);
833 break;
834 case kRoundRect_Type:
835 fName.append("round_rect");
836 fPath.addRoundRect(kBaseRect, kRRRadii[0], kRRRadii[1]);
837 break;
838 case kOval_Type:
839 fName.append("oval");
840 fPath.addOval(kBaseRect);
841 break;
842 }
843 }
844
mtklein36352bf2015-03-25 18:17:31 -0700845 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000846 return backend == kNonRendering_Backend;
847 }
848
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000849private:
mtklein36352bf2015-03-25 18:17:31 -0700850 const char* onGetName() override {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000851 return fName.c_str();
852 }
853
mtkleina1ebeb22015-10-01 09:43:39 -0700854 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000855 for (int i = 0; i < loops; ++i) {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000856 const SkRect& rect = fQueryRects[i % kQueryRectCnt];
857 fParity = fParity != fPath.conservativelyContainsRect(rect);
858 }
859 }
860
joshualitt8a6697a2015-09-30 12:11:07 -0700861 void onDelayedSetup() override {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000862 fQueryRects.setCount(kQueryRectCnt);
863
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000864 SkRandom rand;
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000865 for (int i = 0; i < kQueryRectCnt; ++i) {
866 SkSize size;
867 SkPoint xy;
868 size.fWidth = rand.nextRangeScalar(kQueryMin.fWidth, kQueryMax.fWidth);
869 size.fHeight = rand.nextRangeScalar(kQueryMin.fHeight, kQueryMax.fHeight);
870 xy.fX = rand.nextRangeScalar(kBounds.fLeft, kBounds.fRight - size.fWidth);
871 xy.fY = rand.nextRangeScalar(kBounds.fTop, kBounds.fBottom - size.fHeight);
872
873 fQueryRects[i] = SkRect::MakeXYWH(xy.fX, xy.fY, size.fWidth, size.fHeight);
874 }
875 }
876
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000877 enum {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000878 kQueryRectCnt = 400,
879 };
880 static const SkRect kBounds; // bounds for all random query rects
881 static const SkSize kQueryMin; // minimum query rect size, should be <= kQueryMax
882 static const SkSize kQueryMax; // max query rect size, should < kBounds
883 static const SkRect kBaseRect; // rect that is used to construct the path
884 static const SkScalar kRRRadii[2]; // x and y radii for round rect
885
886 SkString fName;
887 SkPath fPath;
888 bool fParity;
889 SkTDArray<SkRect> fQueryRects;
890
tfarinaf168b862014-06-19 12:32:29 -0700891 typedef Benchmark INHERITED;
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000892};
893
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000894///////////////////////////////////////////////////////////////////////////////
895
896#include "SkGeometry.h"
897
reed55011032015-03-26 09:10:22 -0700898class ConicBench_Chop : public Benchmark {
reedb6402032015-03-20 13:23:43 -0700899protected:
900 SkConic fRQ, fDst[2];
901 SkString fName;
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000902public:
reed55011032015-03-26 09:10:22 -0700903 ConicBench_Chop() : fName("conic-chop") {
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000904 fRQ.fPts[0].set(0, 0);
905 fRQ.fPts[1].set(100, 0);
906 fRQ.fPts[2].set(100, 100);
907 fRQ.fW = SkScalarCos(SK_ScalarPI/4);
reedb6402032015-03-20 13:23:43 -0700908 }
909
mtklein36352bf2015-03-25 18:17:31 -0700910 bool isSuitableFor(Backend backend) override {
reedb6402032015-03-20 13:23:43 -0700911 return backend == kNonRendering_Backend;
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000912 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000913
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000914private:
mtklein36352bf2015-03-25 18:17:31 -0700915 const char* onGetName() override { return fName.c_str(); }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000916
mtkleina1ebeb22015-10-01 09:43:39 -0700917 void onDraw(int loops, SkCanvas*) override {
reed55011032015-03-26 09:10:22 -0700918 for (int i = 0; i < loops; ++i) {
919 fRQ.chop(fDst);
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000920 }
921 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000922
tfarinaf168b862014-06-19 12:32:29 -0700923 typedef Benchmark INHERITED;
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000924};
reed55011032015-03-26 09:10:22 -0700925DEF_BENCH( return new ConicBench_Chop; )
reedb6402032015-03-20 13:23:43 -0700926
reed55011032015-03-26 09:10:22 -0700927class ConicBench_EvalPos : public ConicBench_Chop {
928 const bool fUseV2;
reedb6402032015-03-20 13:23:43 -0700929public:
reed55011032015-03-26 09:10:22 -0700930 ConicBench_EvalPos(bool useV2) : fUseV2(useV2) {
reedb6402032015-03-20 13:23:43 -0700931 fName.printf("conic-eval-pos%d", useV2);
932 }
mtkleina1ebeb22015-10-01 09:43:39 -0700933 void onDraw(int loops, SkCanvas*) override {
reedb6402032015-03-20 13:23:43 -0700934 if (fUseV2) {
935 for (int i = 0; i < loops; ++i) {
936 for (int j = 0; j < 1000; ++j) {
937 fDst[0].fPts[0] = fRQ.evalAt(0.4f);
938 }
939 }
940 } else {
941 for (int i = 0; i < loops; ++i) {
942 for (int j = 0; j < 1000; ++j) {
halcanary96fcdcc2015-08-27 07:41:13 -0700943 fRQ.evalAt(0.4f, &fDst[0].fPts[0], nullptr);
reedb6402032015-03-20 13:23:43 -0700944 }
945 }
946 }
947 }
948};
949DEF_BENCH( return new ConicBench_EvalPos(false); )
950DEF_BENCH( return new ConicBench_EvalPos(true); )
951
reed55011032015-03-26 09:10:22 -0700952class ConicBench_EvalTan : public ConicBench_Chop {
953 const bool fUseV2;
reedb6402032015-03-20 13:23:43 -0700954public:
reed55011032015-03-26 09:10:22 -0700955 ConicBench_EvalTan(bool useV2) : fUseV2(useV2) {
reedb6402032015-03-20 13:23:43 -0700956 fName.printf("conic-eval-tan%d", useV2);
957 }
mtkleina1ebeb22015-10-01 09:43:39 -0700958 void onDraw(int loops, SkCanvas*) override {
reedb6402032015-03-20 13:23:43 -0700959 if (fUseV2) {
960 for (int i = 0; i < loops; ++i) {
961 for (int j = 0; j < 1000; ++j) {
962 fDst[0].fPts[0] = fRQ.evalTangentAt(0.4f);
963 }
964 }
965 } else {
966 for (int i = 0; i < loops; ++i) {
967 for (int j = 0; j < 1000; ++j) {
halcanary96fcdcc2015-08-27 07:41:13 -0700968 fRQ.evalAt(0.4f, nullptr, &fDst[0].fPts[0]);
reedb6402032015-03-20 13:23:43 -0700969 }
970 }
971 }
972 }
973};
974DEF_BENCH( return new ConicBench_EvalTan(false); )
975DEF_BENCH( return new ConicBench_EvalTan(true); )
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000976
977///////////////////////////////////////////////////////////////////////////////
978
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000979static void rand_conic(SkConic* conic, SkRandom& rand) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000980 for (int i = 0; i < 3; ++i) {
981 conic->fPts[i].set(rand.nextUScalar1() * 100, rand.nextUScalar1() * 100);
982 }
983 if (rand.nextUScalar1() > 0.5f) {
984 conic->fW = rand.nextUScalar1();
985 } else {
986 conic->fW = 1 + rand.nextUScalar1() * 4;
987 }
988}
989
tfarinaf168b862014-06-19 12:32:29 -0700990class ConicBench : public Benchmark {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000991public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000992 ConicBench() {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000993 SkRandom rand;
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000994 for (int i = 0; i < CONICS; ++i) {
995 rand_conic(&fConics[i], rand);
996 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000997 }
998
mtklein36352bf2015-03-25 18:17:31 -0700999 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +00001000 return backend == kNonRendering_Backend;
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001001 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001002
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001003protected:
1004 enum {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001005 CONICS = 100
1006 };
1007 SkConic fConics[CONICS];
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001008
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001009private:
tfarinaf168b862014-06-19 12:32:29 -07001010 typedef Benchmark INHERITED;
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001011};
1012
1013class ConicBench_ComputeError : public ConicBench {
1014public:
mtklein@google.com410e6e82013-09-13 19:52:27 +00001015 ConicBench_ComputeError() {}
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001016
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001017protected:
mtklein36352bf2015-03-25 18:17:31 -07001018 const char* onGetName() override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001019 return "conic-compute-error";
1020 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001021
mtkleina1ebeb22015-10-01 09:43:39 -07001022 void onDraw(int loops, SkCanvas*) override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001023 SkVector err;
commit-bot@chromium.org33614712013-12-03 18:17:16 +00001024 for (int i = 0; i < loops; ++i) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001025 for (int j = 0; j < CONICS; ++j) {
1026 fConics[j].computeAsQuadError(&err);
1027 }
1028 }
1029 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001030
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001031private:
1032 typedef ConicBench INHERITED;
1033};
1034
1035class ConicBench_asQuadTol : public ConicBench {
1036public:
mtklein@google.com410e6e82013-09-13 19:52:27 +00001037 ConicBench_asQuadTol() {}
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001038
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001039protected:
mtklein36352bf2015-03-25 18:17:31 -07001040 const char* onGetName() override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001041 return "conic-asQuadTol";
1042 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001043
mtkleina1ebeb22015-10-01 09:43:39 -07001044 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +00001045 for (int i = 0; i < loops; ++i) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001046 for (int j = 0; j < CONICS; ++j) {
1047 fConics[j].asQuadTol(SK_ScalarHalf);
1048 }
1049 }
1050 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001051
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001052private:
1053 typedef ConicBench INHERITED;
1054};
1055
1056class ConicBench_quadPow2 : public ConicBench {
1057public:
mtklein@google.com410e6e82013-09-13 19:52:27 +00001058 ConicBench_quadPow2() {}
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001059
1060protected:
mtklein36352bf2015-03-25 18:17:31 -07001061 const char* onGetName() override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001062 return "conic-quadPow2";
1063 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001064
mtkleina1ebeb22015-10-01 09:43:39 -07001065 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +00001066 for (int i = 0; i < loops; ++i) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001067 for (int j = 0; j < CONICS; ++j) {
1068 fConics[j].computeQuadPOW2(SK_ScalarHalf);
1069 }
1070 }
1071 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001072
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001073private:
1074 typedef ConicBench INHERITED;
1075};
1076
1077///////////////////////////////////////////////////////////////////////////////
1078
Mike Reed0d7dac82017-02-02 17:45:56 -08001079class TightBoundsBench : public Benchmark {
1080 SkPath fPath;
1081 SkString fName;
1082 bool (*fProc)(const SkPath&, SkRect*);
1083
1084public:
1085 TightBoundsBench(bool (*proc)(const SkPath&, SkRect*), const char suffix[]) : fProc(proc) {
1086 fName.printf("tight_bounds_%s", suffix);
1087
1088 const int N = 100;
1089 SkRandom rand;
1090 for (int i = 0; i < N; ++i) {
1091 fPath.moveTo(rand.nextF()*100, rand.nextF()*100);
1092 fPath.lineTo(rand.nextF()*100, rand.nextF()*100);
1093 fPath.quadTo(rand.nextF()*100, rand.nextF()*100, rand.nextF()*100, rand.nextF()*100);
1094 fPath.conicTo(rand.nextF()*100, rand.nextF()*100, rand.nextF()*100, rand.nextF()*100,
1095 rand.nextF()*10);
1096 fPath.cubicTo(rand.nextF()*100, rand.nextF()*100, rand.nextF()*100, rand.nextF()*100,
1097 rand.nextF()*100, rand.nextF()*100);
1098 }
1099 }
1100
1101protected:
1102 bool isSuitableFor(Backend backend) override {
1103 return backend == kNonRendering_Backend;
1104 }
1105
1106 const char* onGetName() override { return fName.c_str(); }
1107
1108 void onDraw(int loops, SkCanvas* canvas) override {
1109 SkRect bounds;
1110 for (int i = 0; i < loops*100; ++i) {
1111 fProc(fPath, &bounds);
1112 }
1113 }
1114
1115private:
1116 typedef Benchmark INHERITED;
1117};
1118
1119
bsalomon@google.com9bee33a2012-11-13 21:51:38 +00001120const SkRect ConservativelyContainsBench::kBounds = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
1121const SkSize ConservativelyContainsBench::kQueryMin = SkSize::Make(SkIntToScalar(1), SkIntToScalar(1));
1122const SkSize ConservativelyContainsBench::kQueryMax = SkSize::Make(SkIntToScalar(40), SkIntToScalar(40));
1123const SkRect ConservativelyContainsBench::kBaseRect = SkRect::MakeXYWH(SkIntToScalar(25), SkIntToScalar(25), SkIntToScalar(50), SkIntToScalar(50));
1124const SkScalar ConservativelyContainsBench::kRRRadii[2] = {SkIntToScalar(5), SkIntToScalar(10)};
1125
mtklein@google.com410e6e82013-09-13 19:52:27 +00001126DEF_BENCH( return new TrianglePathBench(FLAGS00); )
1127DEF_BENCH( return new TrianglePathBench(FLAGS01); )
1128DEF_BENCH( return new TrianglePathBench(FLAGS10); )
1129DEF_BENCH( return new TrianglePathBench(FLAGS11); )
reed@google.comd34658a2011-04-11 13:12:51 +00001130
mtklein@google.com410e6e82013-09-13 19:52:27 +00001131DEF_BENCH( return new RectPathBench(FLAGS00); )
1132DEF_BENCH( return new RectPathBench(FLAGS01); )
1133DEF_BENCH( return new RectPathBench(FLAGS10); )
1134DEF_BENCH( return new RectPathBench(FLAGS11); )
reed@google.comd34658a2011-04-11 13:12:51 +00001135
liyuqiana27f6692016-06-20 14:05:27 -07001136DEF_BENCH( return new RotatedRectBench(FLAGS00, false, 45));
1137DEF_BENCH( return new RotatedRectBench(FLAGS10, false, 45));
1138DEF_BENCH( return new RotatedRectBench(FLAGS00, true, 45));
1139DEF_BENCH( return new RotatedRectBench(FLAGS10, true, 45));
1140
mtklein@google.com410e6e82013-09-13 19:52:27 +00001141DEF_BENCH( return new OvalPathBench(FLAGS00); )
1142DEF_BENCH( return new OvalPathBench(FLAGS01); )
1143DEF_BENCH( return new OvalPathBench(FLAGS10); )
1144DEF_BENCH( return new OvalPathBench(FLAGS11); )
reed@google.comd34658a2011-04-11 13:12:51 +00001145
mtklein@google.com410e6e82013-09-13 19:52:27 +00001146DEF_BENCH( return new CirclePathBench(FLAGS00); )
1147DEF_BENCH( return new CirclePathBench(FLAGS01); )
1148DEF_BENCH( return new CirclePathBench(FLAGS10); )
1149DEF_BENCH( return new CirclePathBench(FLAGS11); )
bsalomon@google.com1647a192012-04-11 15:34:46 +00001150
Yuqian Li8eedbfc2017-01-11 13:55:49 +00001151DEF_BENCH( return new NonAACirclePathBench(FLAGS00); )
1152DEF_BENCH( return new NonAACirclePathBench(FLAGS10); )
1153
Yuqian Li131c1fb2016-12-12 16:24:47 -05001154DEF_BENCH( return new AAAConcavePathBench(FLAGS00); )
1155DEF_BENCH( return new AAAConcavePathBench(FLAGS10); )
1156DEF_BENCH( return new AAAConvexPathBench(FLAGS00); )
1157DEF_BENCH( return new AAAConvexPathBench(FLAGS10); )
1158
mtklein@google.com410e6e82013-09-13 19:52:27 +00001159DEF_BENCH( return new SawToothPathBench(FLAGS00); )
1160DEF_BENCH( return new SawToothPathBench(FLAGS01); )
reed@google.comd34658a2011-04-11 13:12:51 +00001161
mtklein@google.com410e6e82013-09-13 19:52:27 +00001162DEF_BENCH( return new LongCurvedPathBench(FLAGS00); )
1163DEF_BENCH( return new LongCurvedPathBench(FLAGS01); )
1164DEF_BENCH( return new LongLinePathBench(FLAGS00); )
1165DEF_BENCH( return new LongLinePathBench(FLAGS01); )
tomhudson@google.com6e8d3352011-06-22 17:16:35 +00001166
mtklein@google.com410e6e82013-09-13 19:52:27 +00001167DEF_BENCH( return new PathCreateBench(); )
1168DEF_BENCH( return new PathCopyBench(); )
1169DEF_BENCH( return new PathTransformBench(true); )
1170DEF_BENCH( return new PathTransformBench(false); )
1171DEF_BENCH( return new PathEqualityBench(); )
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +00001172
mtklein@google.com410e6e82013-09-13 19:52:27 +00001173DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAdd_AddType); )
1174DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAddTrans_AddType); )
1175DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAddMatrix_AddType); )
mtklein@google.com410e6e82013-09-13 19:52:27 +00001176DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kReverseAdd_AddType); )
1177DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kReversePathTo_AddType); )
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +00001178
mtklein@google.com410e6e82013-09-13 19:52:27 +00001179DEF_BENCH( return new CirclesBench(FLAGS00); )
1180DEF_BENCH( return new CirclesBench(FLAGS01); )
1181DEF_BENCH( return new ArbRoundRectBench(false); )
1182DEF_BENCH( return new ArbRoundRectBench(true); )
1183DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kRect_Type); )
1184DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kRoundRect_Type); )
1185DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kOval_Type); )
mike@reedtribe.org8d551012013-04-14 02:40:50 +00001186
Mike Reed0d7dac82017-02-02 17:45:56 -08001187#include "SkPathOps.h"
1188#include "SkPathPriv.h"
1189DEF_BENCH( return new TightBoundsBench(SkPathPriv::ComputeTightBounds, "priv"); )
1190DEF_BENCH( return new TightBoundsBench(TightBounds, "pathops"); )
reedb6402032015-03-20 13:23:43 -07001191
Mike Klein3f376a52014-07-16 20:23:43 -04001192// These seem to be optimized away, which is troublesome for timing.
1193/*
mtklein@google.com410e6e82013-09-13 19:52:27 +00001194DEF_BENCH( return new ConicBench_Chop5() )
mtklein@google.com410e6e82013-09-13 19:52:27 +00001195DEF_BENCH( return new ConicBench_ComputeError() )
1196DEF_BENCH( return new ConicBench_asQuadTol() )
1197DEF_BENCH( return new ConicBench_quadPow2() )
Mike Klein3f376a52014-07-16 20:23:43 -04001198*/