blob: 964a0e8c6d7281156b6d490865b6ce4ccd569c52 [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
Yuqian Lid29f0e72017-09-14 07:49:41 -070065 for (int i = 0; i < loops; i++) {
reed@google.comd34658a2011-04-11 13:12:51 +000066 canvas->drawPath(path, paint);
67 }
68 }
69
70private:
tfarinaf168b862014-06-19 12:32:29 -070071 typedef Benchmark INHERITED;
reed@google.comd34658a2011-04-11 13:12:51 +000072};
73
74class TrianglePathBench : public PathBench {
75public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000076 TrianglePathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +000077
mtklein36352bf2015-03-25 18:17:31 -070078 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +000079 name->append("triangle");
80 }
mtklein36352bf2015-03-25 18:17:31 -070081 void makePath(SkPath* path) override {
reed@google.comd34658a2011-04-11 13:12:51 +000082 static const int gCoord[] = {
83 10, 10, 15, 5, 20, 20
84 };
85 path->moveTo(SkIntToScalar(gCoord[0]), SkIntToScalar(gCoord[1]));
86 path->lineTo(SkIntToScalar(gCoord[2]), SkIntToScalar(gCoord[3]));
87 path->lineTo(SkIntToScalar(gCoord[4]), SkIntToScalar(gCoord[5]));
88 path->close();
89 }
90private:
91 typedef PathBench INHERITED;
92};
93
94class RectPathBench : public PathBench {
95public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000096 RectPathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +000097
mtklein36352bf2015-03-25 18:17:31 -070098 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +000099 name->append("rect");
100 }
mtklein36352bf2015-03-25 18:17:31 -0700101 void makePath(SkPath* path) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000102 SkRect r = { 10, 10, 20, 20 };
103 path->addRect(r);
104 }
105private:
106 typedef PathBench INHERITED;
107};
108
liyuqiana27f6692016-06-20 14:05:27 -0700109class RotatedRectBench : public PathBench {
110public:
111 RotatedRectBench(Flags flags, bool aa, int degrees) : INHERITED(flags) {
112 fAA = aa;
113 fDegrees = degrees;
114 }
115
116 void appendName(SkString* name) override {
117 SkString suffix;
118 suffix.printf("rotated_rect_%s_%d", fAA ? "aa" : "noaa", fDegrees);
119 name->append(suffix);
120 }
121
122 void makePath(SkPath* path) override {
123 SkRect r = { 10, 10, 20, 20 };
124 path->addRect(r);
125 SkMatrix rotateMatrix;
126 rotateMatrix.setRotate((SkScalar)fDegrees);
127 path->transform(rotateMatrix);
128 }
129
130 virtual void setupPaint(SkPaint* paint) override {
131 PathBench::setupPaint(paint);
132 paint->setAntiAlias(fAA);
133 }
134private:
135 typedef PathBench INHERITED;
136 int fDegrees;
137 bool fAA;
138};
139
reed@google.comd34658a2011-04-11 13:12:51 +0000140class OvalPathBench : public PathBench {
141public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000142 OvalPathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000143
mtklein36352bf2015-03-25 18:17:31 -0700144 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000145 name->append("oval");
146 }
mtklein36352bf2015-03-25 18:17:31 -0700147 void makePath(SkPath* path) override {
jvanverth@google.come2bfd8b2013-01-24 15:45:35 +0000148 SkRect r = { 10, 10, 23, 20 };
reed@google.comd34658a2011-04-11 13:12:51 +0000149 path->addOval(r);
150 }
151private:
152 typedef PathBench INHERITED;
153};
154
bsalomon@google.com1647a192012-04-11 15:34:46 +0000155class CirclePathBench: public PathBench {
156public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000157 CirclePathBench(Flags flags) : INHERITED(flags) {}
bsalomon@google.com1647a192012-04-11 15:34:46 +0000158
mtklein36352bf2015-03-25 18:17:31 -0700159 void appendName(SkString* name) override {
bsalomon@google.com1647a192012-04-11 15:34:46 +0000160 name->append("circle");
161 }
mtklein36352bf2015-03-25 18:17:31 -0700162 void makePath(SkPath* path) override {
bsalomon@google.com1647a192012-04-11 15:34:46 +0000163 path->addCircle(SkIntToScalar(20), SkIntToScalar(20),
164 SkIntToScalar(10));
165 }
166private:
167 typedef PathBench INHERITED;
168};
169
Yuqian Li8eedbfc2017-01-11 13:55:49 +0000170class NonAACirclePathBench: public CirclePathBench {
171public:
172 NonAACirclePathBench(Flags flags) : INHERITED(flags) {}
173
174 void appendName(SkString* name) override {
175 name->append("nonaacircle");
176 }
177
178 void setupPaint(SkPaint* paint) override {
179 CirclePathBench::setupPaint(paint);
180 paint->setAntiAlias(false);
181 }
182
183private:
184 typedef CirclePathBench INHERITED;
185};
186
Yuqian Li131c1fb2016-12-12 16:24:47 -0500187// Test max speedup of Analytic AA for concave paths
188class AAAConcavePathBench : public PathBench {
189public:
190 AAAConcavePathBench(Flags flags) : INHERITED(flags) {}
191
192 void appendName(SkString* name) override {
193 name->append("concave_aaa");
194 }
195
196 void makePath(SkPath* path) override {
197 path->moveTo(10, 10);
198 path->lineTo(15, 10);
199 path->lineTo(15, 5);
200 path->lineTo(40, 40);
201 path->close();
202 }
203
204private:
205 typedef PathBench INHERITED;
206};
207
208// Test max speedup of Analytic AA for convex paths
209class AAAConvexPathBench : public PathBench {
210public:
211 AAAConvexPathBench(Flags flags) : INHERITED(flags) {}
212
213 void appendName(SkString* name) override {
214 name->append("convex_aaa");
215 }
216
217 void makePath(SkPath* path) override {
218 path->moveTo(10, 10);
219 path->lineTo(15, 10);
220 path->lineTo(40, 50);
221 path->close();
222 }
223
224private:
225 typedef PathBench INHERITED;
226};
227
reed@google.comd34658a2011-04-11 13:12:51 +0000228class SawToothPathBench : public PathBench {
229public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000230 SawToothPathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000231
mtklein36352bf2015-03-25 18:17:31 -0700232 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000233 name->append("sawtooth");
234 }
mtkleinf0599002015-07-13 06:18:39 -0700235 void makePath(SkPath* path) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000236 SkScalar x = SkIntToScalar(20);
237 SkScalar y = SkIntToScalar(20);
238 const SkScalar x0 = x;
239 const SkScalar dx = SK_Scalar1 * 5;
240 const SkScalar dy = SK_Scalar1 * 10;
241
242 path->moveTo(x, y);
243 for (int i = 0; i < 32; i++) {
244 x += dx;
245 path->lineTo(x, y - dy);
246 x += dx;
247 path->lineTo(x, y + dy);
248 }
249 path->lineTo(x, y + 2 * dy);
250 path->lineTo(x0, y + 2 * dy);
251 path->close();
252 }
mtklein36352bf2015-03-25 18:17:31 -0700253 int complexity() override { return 1; }
reed@google.comd34658a2011-04-11 13:12:51 +0000254private:
255 typedef PathBench INHERITED;
256};
257
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000258class LongCurvedPathBench : public PathBench {
259public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000260 LongCurvedPathBench(Flags flags) : INHERITED(flags) {}
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000261
mtklein36352bf2015-03-25 18:17:31 -0700262 void appendName(SkString* name) override {
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000263 name->append("long_curved");
264 }
mtklein36352bf2015-03-25 18:17:31 -0700265 void makePath(SkPath* path) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000266 SkRandom rand (12);
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000267 int i;
268 for (i = 0; i < 100; i++) {
Mike Reeddf85c382017-02-14 10:59:19 -0500269 path->quadTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480,
270 rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000271 }
272 path->close();
273 }
mtklein36352bf2015-03-25 18:17:31 -0700274 int complexity() override { return 2; }
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000275private:
276 typedef PathBench INHERITED;
277};
278
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000279class LongLinePathBench : public PathBench {
280public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000281 LongLinePathBench(Flags flags) : INHERITED(flags) {}
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000282
mtklein36352bf2015-03-25 18:17:31 -0700283 void appendName(SkString* name) override {
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000284 name->append("long_line");
285 }
mtklein36352bf2015-03-25 18:17:31 -0700286 void makePath(SkPath* path) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000287 SkRandom rand;
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000288 path->moveTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
289 for (size_t i = 1; i < 100; i++) {
290 path->lineTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
291 }
292 }
mtklein36352bf2015-03-25 18:17:31 -0700293 int complexity() override { return 2; }
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000294private:
295 typedef PathBench INHERITED;
296};
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000297
tfarinaf168b862014-06-19 12:32:29 -0700298class RandomPathBench : public Benchmark {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000299public:
mtklein36352bf2015-03-25 18:17:31 -0700300 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000301 return backend == kNonRendering_Backend;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000302 }
303
304protected:
305 void createData(int minVerbs,
306 int maxVerbs,
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000307 bool allowMoves = true,
halcanary96fcdcc2015-08-27 07:41:13 -0700308 SkRect* bounds = nullptr) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000309 SkRect tempBounds;
halcanary96fcdcc2015-08-27 07:41:13 -0700310 if (nullptr == bounds) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000311 tempBounds.setXYWH(0, 0, SK_Scalar1, SK_Scalar1);
312 bounds = &tempBounds;
313 }
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000314 fVerbCnts.reset(kNumVerbCnts);
315 for (int i = 0; i < kNumVerbCnts; ++i) {
316 fVerbCnts[i] = fRandom.nextRangeU(minVerbs, maxVerbs + 1);
317 }
318 fVerbs.reset(kNumVerbs);
319 for (int i = 0; i < kNumVerbs; ++i) {
320 do {
321 fVerbs[i] = static_cast<SkPath::Verb>(fRandom.nextULessThan(SkPath::kDone_Verb));
322 } while (!allowMoves && SkPath::kMove_Verb == fVerbs[i]);
323 }
324 fPoints.reset(kNumPoints);
325 for (int i = 0; i < kNumPoints; ++i) {
326 fPoints[i].set(fRandom.nextRangeScalar(bounds->fLeft, bounds->fRight),
327 fRandom.nextRangeScalar(bounds->fTop, bounds->fBottom));
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000328 }
329 this->restartMakingPaths();
330 }
331
332 void restartMakingPaths() {
333 fCurrPath = 0;
334 fCurrVerb = 0;
335 fCurrPoint = 0;
336 }
337
338 void makePath(SkPath* path) {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000339 int vCount = fVerbCnts[(fCurrPath++) & (kNumVerbCnts - 1)];
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000340 for (int v = 0; v < vCount; ++v) {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000341 int verb = fVerbs[(fCurrVerb++) & (kNumVerbs - 1)];
342 switch (verb) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000343 case SkPath::kMove_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000344 path->moveTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000345 break;
346 case SkPath::kLine_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000347 path->lineTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000348 break;
349 case SkPath::kQuad_Verb:
bsalomon@google.com373ebc62012-09-26 13:08:56 +0000350 path->quadTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
351 fPoints[(fCurrPoint + 1) & (kNumPoints - 1)]);
352 fCurrPoint += 2;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000353 break;
reed@google.com277c3f82013-05-31 15:17:50 +0000354 case SkPath::kConic_Verb:
355 path->conicTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
356 fPoints[(fCurrPoint + 1) & (kNumPoints - 1)],
357 SK_ScalarHalf);
358 fCurrPoint += 2;
359 break;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000360 case SkPath::kCubic_Verb:
bsalomon@google.com373ebc62012-09-26 13:08:56 +0000361 path->cubicTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
362 fPoints[(fCurrPoint + 1) & (kNumPoints - 1)],
363 fPoints[(fCurrPoint + 2) & (kNumPoints - 1)]);
364 fCurrPoint += 3;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000365 break;
366 case SkPath::kClose_Verb:
367 path->close();
368 break;
369 default:
370 SkDEBUGFAIL("Unexpected path verb");
371 break;
372 }
373 }
374 }
375
376 void finishedMakingPaths() {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000377 fVerbCnts.reset(0);
378 fVerbs.reset(0);
379 fPoints.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000380 }
381
382private:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000383 enum {
384 // these should all be pow 2
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000385 kNumVerbCnts = 1 << 5,
386 kNumVerbs = 1 << 5,
387 kNumPoints = 1 << 5,
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000388 };
389 SkAutoTArray<int> fVerbCnts;
390 SkAutoTArray<SkPath::Verb> fVerbs;
391 SkAutoTArray<SkPoint> fPoints;
392 int fCurrPath;
393 int fCurrVerb;
394 int fCurrPoint;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000395 SkRandom fRandom;
tfarinaf168b862014-06-19 12:32:29 -0700396 typedef Benchmark INHERITED;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000397};
398
399class PathCreateBench : public RandomPathBench {
400public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000401 PathCreateBench() {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000402 }
403
404protected:
mtklein36352bf2015-03-25 18:17:31 -0700405 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000406 return "path_create";
407 }
408
joshualitt8a6697a2015-09-30 12:11:07 -0700409 void onDelayedSetup() override {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000410 this->createData(10, 100);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000411 }
412
mtkleina1ebeb22015-10-01 09:43:39 -0700413 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000414 for (int i = 0; i < loops; ++i) {
commit-bot@chromium.org8f881172014-01-06 20:19:14 +0000415 if (i % 1000 == 0) {
416 fPath.reset(); // PathRef memory can grow without bound otherwise.
417 }
418 this->makePath(&fPath);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000419 }
420 this->restartMakingPaths();
421 }
422
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000423private:
commit-bot@chromium.org8f881172014-01-06 20:19:14 +0000424 SkPath fPath;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000425
426 typedef RandomPathBench INHERITED;
427};
428
429class PathCopyBench : public RandomPathBench {
430public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000431 PathCopyBench() {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000432 }
433
434protected:
mtklein36352bf2015-03-25 18:17:31 -0700435 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000436 return "path_copy";
437 }
joshualitt8a6697a2015-09-30 12:11:07 -0700438 void onDelayedSetup() override {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000439 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000440 fPaths.reset(kPathCnt);
441 fCopies.reset(kPathCnt);
442 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000443 this->makePath(&fPaths[i]);
444 }
445 this->finishedMakingPaths();
446 }
mtkleina1ebeb22015-10-01 09:43:39 -0700447 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000448 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000449 int idx = i & (kPathCnt - 1);
450 fCopies[idx] = fPaths[idx];
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000451 }
452 }
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000453
454private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000455 enum {
456 // must be a pow 2
457 kPathCnt = 1 << 5,
458 };
459 SkAutoTArray<SkPath> fPaths;
460 SkAutoTArray<SkPath> fCopies;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000461
462 typedef RandomPathBench INHERITED;
463};
464
465class PathTransformBench : public RandomPathBench {
466public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000467 PathTransformBench(bool inPlace) : fInPlace(inPlace) {}
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000468
469protected:
mtklein36352bf2015-03-25 18:17:31 -0700470 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000471 return fInPlace ? "path_transform_in_place" : "path_transform_copy";
472 }
473
joshualitt8a6697a2015-09-30 12:11:07 -0700474 void onDelayedSetup() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000475 fMatrix.setScale(5 * SK_Scalar1, 6 * SK_Scalar1);
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000476 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000477 fPaths.reset(kPathCnt);
478 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000479 this->makePath(&fPaths[i]);
480 }
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000481 this->finishedMakingPaths();
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000482 if (!fInPlace) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000483 fTransformed.reset(kPathCnt);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000484 }
485 }
486
mtkleina1ebeb22015-10-01 09:43:39 -0700487 void onDraw(int loops, SkCanvas*) override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000488 if (fInPlace) {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000489 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000490 fPaths[i & (kPathCnt - 1)].transform(fMatrix);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000491 }
492 } else {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000493 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000494 int idx = i & (kPathCnt - 1);
495 fPaths[idx].transform(fMatrix, &fTransformed[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000496 }
497 }
498 }
499
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000500private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000501 enum {
502 // must be a pow 2
503 kPathCnt = 1 << 5,
504 };
505 SkAutoTArray<SkPath> fPaths;
506 SkAutoTArray<SkPath> fTransformed;
507
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000508 SkMatrix fMatrix;
509 bool fInPlace;
510 typedef RandomPathBench INHERITED;
511};
512
513class PathEqualityBench : public RandomPathBench {
514public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000515 PathEqualityBench() { }
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000516
517protected:
mtklein36352bf2015-03-25 18:17:31 -0700518 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000519 return "path_equality_50%";
520 }
521
joshualitt8a6697a2015-09-30 12:11:07 -0700522 void onDelayedSetup() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000523 fParity = 0;
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000524 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000525 fPaths.reset(kPathCnt);
526 fCopies.reset(kPathCnt);
527 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000528 this->makePath(&fPaths[i]);
529 fCopies[i] = fPaths[i];
530 }
531 this->finishedMakingPaths();
532 }
533
mtkleina1ebeb22015-10-01 09:43:39 -0700534 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000535 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000536 int idx = i & (kPathCnt - 1);
537 fParity ^= (fPaths[idx] == fCopies[idx & ~0x1]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000538 }
539 }
540
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000541private:
542 bool fParity; // attempt to keep compiler from optimizing out the ==
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000543 enum {
544 // must be a pow 2
545 kPathCnt = 1 << 5,
546 };
547 SkAutoTArray<SkPath> fPaths;
548 SkAutoTArray<SkPath> fCopies;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000549 typedef RandomPathBench INHERITED;
550};
551
552class SkBench_AddPathTest : public RandomPathBench {
553public:
554 enum AddType {
555 kAdd_AddType,
556 kAddTrans_AddType,
557 kAddMatrix_AddType,
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000558 kReverseAdd_AddType,
559 kReversePathTo_AddType,
560 };
561
mtklein@google.com410e6e82013-09-13 19:52:27 +0000562 SkBench_AddPathTest(AddType type) : fType(type) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000563 fMatrix.setRotate(60 * SK_Scalar1);
564 }
565
566protected:
mtklein36352bf2015-03-25 18:17:31 -0700567 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000568 switch (fType) {
569 case kAdd_AddType:
570 return "path_add_path";
571 case kAddTrans_AddType:
572 return "path_add_path_trans";
573 case kAddMatrix_AddType:
574 return "path_add_path_matrix";
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000575 case kReverseAdd_AddType:
576 return "path_reverse_add_path";
577 case kReversePathTo_AddType:
578 return "path_reverse_path_to";
579 default:
580 SkDEBUGFAIL("Bad add type");
581 return "";
582 }
583 }
584
joshualitt8a6697a2015-09-30 12:11:07 -0700585 void onDelayedSetup() override {
commit-bot@chromium.orga1a097e2013-11-14 16:53:22 +0000586 // reversePathTo assumes a single contour path.
587 bool allowMoves = kReversePathTo_AddType != fType;
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000588 this->createData(10, 100, allowMoves);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000589 fPaths0.reset(kPathCnt);
590 fPaths1.reset(kPathCnt);
591 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000592 this->makePath(&fPaths0[i]);
593 this->makePath(&fPaths1[i]);
594 }
595 this->finishedMakingPaths();
596 }
597
mtkleina1ebeb22015-10-01 09:43:39 -0700598 void onDraw(int loops, SkCanvas*) override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000599 switch (fType) {
600 case kAdd_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000601 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000602 int idx = i & (kPathCnt - 1);
603 SkPath result = fPaths0[idx];
604 result.addPath(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000605 }
606 break;
607 case kAddTrans_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000608 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000609 int idx = i & (kPathCnt - 1);
610 SkPath result = fPaths0[idx];
611 result.addPath(fPaths1[idx], 2 * SK_Scalar1, 5 * SK_Scalar1);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000612 }
613 break;
614 case kAddMatrix_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000615 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000616 int idx = i & (kPathCnt - 1);
617 SkPath result = fPaths0[idx];
618 result.addPath(fPaths1[idx], fMatrix);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000619 }
620 break;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000621 case kReverseAdd_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000622 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000623 int idx = i & (kPathCnt - 1);
624 SkPath result = fPaths0[idx];
625 result.reverseAddPath(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000626 }
627 break;
628 case kReversePathTo_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000629 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000630 int idx = i & (kPathCnt - 1);
631 SkPath result = fPaths0[idx];
632 result.reversePathTo(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000633 }
634 break;
635 }
636 }
637
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000638private:
639 AddType fType; // or reverseAddPath
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000640 enum {
641 // must be a pow 2
642 kPathCnt = 1 << 5,
643 };
644 SkAutoTArray<SkPath> fPaths0;
645 SkAutoTArray<SkPath> fPaths1;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000646 SkMatrix fMatrix;
647 typedef RandomPathBench INHERITED;
648};
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000649
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000650
tfarinaf168b862014-06-19 12:32:29 -0700651class CirclesBench : public Benchmark {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000652protected:
653 SkString fName;
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000654 Flags fFlags;
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000655
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000656public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000657 CirclesBench(Flags flags) : fFlags(flags) {
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000658 fName.printf("circles_%s", fFlags & kStroke_Flag ? "stroke" : "fill");
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000659 }
660
661protected:
mtklein36352bf2015-03-25 18:17:31 -0700662 const char* onGetName() override {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000663 return fName.c_str();
664 }
665
mtkleina1ebeb22015-10-01 09:43:39 -0700666 void onDraw(int loops, SkCanvas* canvas) override {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000667 SkPaint paint;
668
669 paint.setColor(SK_ColorBLACK);
670 paint.setAntiAlias(true);
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000671 if (fFlags & kStroke_Flag) {
672 paint.setStyle(SkPaint::kStroke_Style);
673 }
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000674
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000675 SkRandom rand;
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000676
677 SkRect r;
678
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000679 for (int i = 0; i < loops; ++i) {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000680 SkScalar radius = rand.nextUScalar1() * 3;
681 r.fLeft = rand.nextUScalar1() * 300;
682 r.fTop = rand.nextUScalar1() * 300;
683 r.fRight = r.fLeft + 2 * radius;
684 r.fBottom = r.fTop + 2 * radius;
685
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000686 if (fFlags & kStroke_Flag) {
687 paint.setStrokeWidth(rand.nextUScalar1() * 5.0f);
688 }
689
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000690 SkPath temp;
691
692 // mimic how Chrome does circles
693 temp.arcTo(r, 0, 0, false);
694 temp.addOval(r, SkPath::kCCW_Direction);
695 temp.arcTo(r, 360, 0, true);
696 temp.close();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000697
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000698 canvas->drawPath(temp, paint);
699 }
700 }
701
702private:
tfarinaf168b862014-06-19 12:32:29 -0700703 typedef Benchmark INHERITED;
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000704};
705
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000706
robertphillips@google.com158618e2012-10-23 16:56:56 +0000707// Chrome creates its own round rects with each corner possibly being different.
708// In its "zero radius" incarnation it creates degenerate round rects.
skia.committer@gmail.com1e34ff72012-10-24 02:01:24 +0000709// Note: PathTest::test_arb_round_rect_is_convex and
robertphillips@google.com158618e2012-10-23 16:56:56 +0000710// test_arb_zero_rad_round_rect_is_rect perform almost exactly
robertphillips@google.comb95eaa82012-10-18 15:26:12 +0000711// the same test (but with no drawing)
tfarinaf168b862014-06-19 12:32:29 -0700712class ArbRoundRectBench : public Benchmark {
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000713protected:
714 SkString fName;
715
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000716public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000717 ArbRoundRectBench(bool zeroRad) : fZeroRad(zeroRad) {
robertphillips@google.com158618e2012-10-23 16:56:56 +0000718 if (zeroRad) {
719 fName.printf("zeroradroundrect");
720 } else {
721 fName.printf("arbroundrect");
722 }
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000723 }
724
725protected:
mtklein36352bf2015-03-25 18:17:31 -0700726 const char* onGetName() override {
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000727 return fName.c_str();
728 }
729
skia.committer@gmail.com989a95e2012-10-18 02:01:23 +0000730 static void add_corner_arc(SkPath* path, const SkRect& rect,
731 SkScalar xIn, SkScalar yIn,
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000732 int startAngle)
733 {
734
735 SkScalar rx = SkMinScalar(rect.width(), xIn);
736 SkScalar ry = SkMinScalar(rect.height(), yIn);
737
738 SkRect arcRect;
739 arcRect.set(-rx, -ry, rx, ry);
740 switch (startAngle) {
741 case 0:
742 arcRect.offset(rect.fRight - arcRect.fRight, rect.fBottom - arcRect.fBottom);
743 break;
744 case 90:
745 arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fBottom - arcRect.fBottom);
746 break;
747 case 180:
748 arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fTop - arcRect.fTop);
749 break;
750 case 270:
751 arcRect.offset(rect.fRight - arcRect.fRight, rect.fTop - arcRect.fTop);
752 break;
753 default:
754 break;
755 }
756
757 path->arcTo(arcRect, SkIntToScalar(startAngle), SkIntToScalar(90), false);
758 }
759
skia.committer@gmail.com989a95e2012-10-18 02:01:23 +0000760 static void make_arb_round_rect(SkPath* path, const SkRect& r,
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000761 SkScalar xCorner, SkScalar yCorner) {
762 // we are lazy here and use the same x & y for each corner
763 add_corner_arc(path, r, xCorner, yCorner, 270);
764 add_corner_arc(path, r, xCorner, yCorner, 0);
765 add_corner_arc(path, r, xCorner, yCorner, 90);
766 add_corner_arc(path, r, xCorner, yCorner, 180);
robertphillips@google.com158618e2012-10-23 16:56:56 +0000767 path->close();
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000768
robertphillips@google.comb95eaa82012-10-18 15:26:12 +0000769 SkASSERT(path->isConvex());
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000770 }
771
mtkleina1ebeb22015-10-01 09:43:39 -0700772 void onDraw(int loops, SkCanvas* canvas) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000773 SkRandom rand;
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000774 SkRect r;
775
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000776 for (int i = 0; i < loops; ++i) {
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000777 SkPaint paint;
778 paint.setColor(0xff000000 | rand.nextU());
779 paint.setAntiAlias(true);
780
robertphillips@google.com158618e2012-10-23 16:56:56 +0000781 SkScalar size = rand.nextUScalar1() * 30;
782 if (size < SK_Scalar1) {
robertphillips@google.comb95eaa82012-10-18 15:26:12 +0000783 continue;
784 }
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000785 r.fLeft = rand.nextUScalar1() * 300;
786 r.fTop = rand.nextUScalar1() * 300;
robertphillips@google.com158618e2012-10-23 16:56:56 +0000787 r.fRight = r.fLeft + 2 * size;
788 r.fBottom = r.fTop + 2 * size;
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000789
790 SkPath temp;
791
robertphillips@google.com158618e2012-10-23 16:56:56 +0000792 if (fZeroRad) {
793 make_arb_round_rect(&temp, r, 0, 0);
794
halcanary96fcdcc2015-08-27 07:41:13 -0700795 SkASSERT(temp.isRect(nullptr));
robertphillips@google.com158618e2012-10-23 16:56:56 +0000796 } else {
797 make_arb_round_rect(&temp, r, r.width() / 10, r.height() / 15);
798 }
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000799
800 canvas->drawPath(temp, paint);
801 }
802 }
803
804private:
robertphillips@google.com158618e2012-10-23 16:56:56 +0000805 bool fZeroRad; // should 0 radius rounds rects be tested?
806
tfarinaf168b862014-06-19 12:32:29 -0700807 typedef Benchmark INHERITED;
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000808};
809
tfarinaf168b862014-06-19 12:32:29 -0700810class ConservativelyContainsBench : public Benchmark {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000811public:
812 enum Type {
813 kRect_Type,
814 kRoundRect_Type,
815 kOval_Type,
816 };
817
mtklein@google.com410e6e82013-09-13 19:52:27 +0000818 ConservativelyContainsBench(Type type) {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000819 fParity = false;
820 fName = "conservatively_contains_";
821 switch (type) {
822 case kRect_Type:
823 fName.append("rect");
824 fPath.addRect(kBaseRect);
825 break;
826 case kRoundRect_Type:
827 fName.append("round_rect");
828 fPath.addRoundRect(kBaseRect, kRRRadii[0], kRRRadii[1]);
829 break;
830 case kOval_Type:
831 fName.append("oval");
832 fPath.addOval(kBaseRect);
833 break;
834 }
835 }
836
mtklein36352bf2015-03-25 18:17:31 -0700837 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000838 return backend == kNonRendering_Backend;
839 }
840
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000841private:
mtklein36352bf2015-03-25 18:17:31 -0700842 const char* onGetName() override {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000843 return fName.c_str();
844 }
845
mtkleina1ebeb22015-10-01 09:43:39 -0700846 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000847 for (int i = 0; i < loops; ++i) {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000848 const SkRect& rect = fQueryRects[i % kQueryRectCnt];
849 fParity = fParity != fPath.conservativelyContainsRect(rect);
850 }
851 }
852
joshualitt8a6697a2015-09-30 12:11:07 -0700853 void onDelayedSetup() override {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000854 fQueryRects.setCount(kQueryRectCnt);
855
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000856 SkRandom rand;
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000857 for (int i = 0; i < kQueryRectCnt; ++i) {
858 SkSize size;
859 SkPoint xy;
860 size.fWidth = rand.nextRangeScalar(kQueryMin.fWidth, kQueryMax.fWidth);
861 size.fHeight = rand.nextRangeScalar(kQueryMin.fHeight, kQueryMax.fHeight);
862 xy.fX = rand.nextRangeScalar(kBounds.fLeft, kBounds.fRight - size.fWidth);
863 xy.fY = rand.nextRangeScalar(kBounds.fTop, kBounds.fBottom - size.fHeight);
864
865 fQueryRects[i] = SkRect::MakeXYWH(xy.fX, xy.fY, size.fWidth, size.fHeight);
866 }
867 }
868
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000869 enum {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000870 kQueryRectCnt = 400,
871 };
872 static const SkRect kBounds; // bounds for all random query rects
873 static const SkSize kQueryMin; // minimum query rect size, should be <= kQueryMax
874 static const SkSize kQueryMax; // max query rect size, should < kBounds
875 static const SkRect kBaseRect; // rect that is used to construct the path
876 static const SkScalar kRRRadii[2]; // x and y radii for round rect
877
878 SkString fName;
879 SkPath fPath;
880 bool fParity;
881 SkTDArray<SkRect> fQueryRects;
882
tfarinaf168b862014-06-19 12:32:29 -0700883 typedef Benchmark INHERITED;
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000884};
885
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000886///////////////////////////////////////////////////////////////////////////////
887
888#include "SkGeometry.h"
889
reed55011032015-03-26 09:10:22 -0700890class ConicBench_Chop : public Benchmark {
reedb6402032015-03-20 13:23:43 -0700891protected:
892 SkConic fRQ, fDst[2];
893 SkString fName;
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000894public:
reed55011032015-03-26 09:10:22 -0700895 ConicBench_Chop() : fName("conic-chop") {
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000896 fRQ.fPts[0].set(0, 0);
897 fRQ.fPts[1].set(100, 0);
898 fRQ.fPts[2].set(100, 100);
899 fRQ.fW = SkScalarCos(SK_ScalarPI/4);
reedb6402032015-03-20 13:23:43 -0700900 }
901
mtklein36352bf2015-03-25 18:17:31 -0700902 bool isSuitableFor(Backend backend) override {
reedb6402032015-03-20 13:23:43 -0700903 return backend == kNonRendering_Backend;
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000904 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000905
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000906private:
mtklein36352bf2015-03-25 18:17:31 -0700907 const char* onGetName() override { return fName.c_str(); }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000908
mtkleina1ebeb22015-10-01 09:43:39 -0700909 void onDraw(int loops, SkCanvas*) override {
reed55011032015-03-26 09:10:22 -0700910 for (int i = 0; i < loops; ++i) {
911 fRQ.chop(fDst);
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000912 }
913 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000914
tfarinaf168b862014-06-19 12:32:29 -0700915 typedef Benchmark INHERITED;
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000916};
reed55011032015-03-26 09:10:22 -0700917DEF_BENCH( return new ConicBench_Chop; )
reedb6402032015-03-20 13:23:43 -0700918
reed55011032015-03-26 09:10:22 -0700919class ConicBench_EvalPos : public ConicBench_Chop {
920 const bool fUseV2;
reedb6402032015-03-20 13:23:43 -0700921public:
reed55011032015-03-26 09:10:22 -0700922 ConicBench_EvalPos(bool useV2) : fUseV2(useV2) {
reedb6402032015-03-20 13:23:43 -0700923 fName.printf("conic-eval-pos%d", useV2);
924 }
mtkleina1ebeb22015-10-01 09:43:39 -0700925 void onDraw(int loops, SkCanvas*) override {
reedb6402032015-03-20 13:23:43 -0700926 if (fUseV2) {
927 for (int i = 0; i < loops; ++i) {
928 for (int j = 0; j < 1000; ++j) {
929 fDst[0].fPts[0] = fRQ.evalAt(0.4f);
930 }
931 }
932 } else {
933 for (int i = 0; i < loops; ++i) {
934 for (int j = 0; j < 1000; ++j) {
halcanary96fcdcc2015-08-27 07:41:13 -0700935 fRQ.evalAt(0.4f, &fDst[0].fPts[0], nullptr);
reedb6402032015-03-20 13:23:43 -0700936 }
937 }
938 }
939 }
940};
941DEF_BENCH( return new ConicBench_EvalPos(false); )
942DEF_BENCH( return new ConicBench_EvalPos(true); )
943
reed55011032015-03-26 09:10:22 -0700944class ConicBench_EvalTan : public ConicBench_Chop {
945 const bool fUseV2;
reedb6402032015-03-20 13:23:43 -0700946public:
reed55011032015-03-26 09:10:22 -0700947 ConicBench_EvalTan(bool useV2) : fUseV2(useV2) {
reedb6402032015-03-20 13:23:43 -0700948 fName.printf("conic-eval-tan%d", useV2);
949 }
mtkleina1ebeb22015-10-01 09:43:39 -0700950 void onDraw(int loops, SkCanvas*) override {
reedb6402032015-03-20 13:23:43 -0700951 if (fUseV2) {
952 for (int i = 0; i < loops; ++i) {
953 for (int j = 0; j < 1000; ++j) {
954 fDst[0].fPts[0] = fRQ.evalTangentAt(0.4f);
955 }
956 }
957 } else {
958 for (int i = 0; i < loops; ++i) {
959 for (int j = 0; j < 1000; ++j) {
halcanary96fcdcc2015-08-27 07:41:13 -0700960 fRQ.evalAt(0.4f, nullptr, &fDst[0].fPts[0]);
reedb6402032015-03-20 13:23:43 -0700961 }
962 }
963 }
964 }
965};
966DEF_BENCH( return new ConicBench_EvalTan(false); )
967DEF_BENCH( return new ConicBench_EvalTan(true); )
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000968
969///////////////////////////////////////////////////////////////////////////////
970
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000971static void rand_conic(SkConic* conic, SkRandom& rand) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000972 for (int i = 0; i < 3; ++i) {
973 conic->fPts[i].set(rand.nextUScalar1() * 100, rand.nextUScalar1() * 100);
974 }
975 if (rand.nextUScalar1() > 0.5f) {
976 conic->fW = rand.nextUScalar1();
977 } else {
978 conic->fW = 1 + rand.nextUScalar1() * 4;
979 }
980}
981
tfarinaf168b862014-06-19 12:32:29 -0700982class ConicBench : public Benchmark {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000983public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000984 ConicBench() {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000985 SkRandom rand;
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000986 for (int i = 0; i < CONICS; ++i) {
987 rand_conic(&fConics[i], rand);
988 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000989 }
990
mtklein36352bf2015-03-25 18:17:31 -0700991 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000992 return backend == kNonRendering_Backend;
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000993 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000994
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000995protected:
996 enum {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000997 CONICS = 100
998 };
999 SkConic fConics[CONICS];
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001000
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001001private:
tfarinaf168b862014-06-19 12:32:29 -07001002 typedef Benchmark INHERITED;
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001003};
1004
1005class ConicBench_ComputeError : public ConicBench {
1006public:
mtklein@google.com410e6e82013-09-13 19:52:27 +00001007 ConicBench_ComputeError() {}
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001008
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001009protected:
mtklein36352bf2015-03-25 18:17:31 -07001010 const char* onGetName() override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001011 return "conic-compute-error";
1012 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001013
mtkleina1ebeb22015-10-01 09:43:39 -07001014 void onDraw(int loops, SkCanvas*) override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001015 SkVector err;
commit-bot@chromium.org33614712013-12-03 18:17:16 +00001016 for (int i = 0; i < loops; ++i) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001017 for (int j = 0; j < CONICS; ++j) {
1018 fConics[j].computeAsQuadError(&err);
1019 }
1020 }
1021 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001022
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001023private:
1024 typedef ConicBench INHERITED;
1025};
1026
1027class ConicBench_asQuadTol : public ConicBench {
1028public:
mtklein@google.com410e6e82013-09-13 19:52:27 +00001029 ConicBench_asQuadTol() {}
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001030
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001031protected:
mtklein36352bf2015-03-25 18:17:31 -07001032 const char* onGetName() override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001033 return "conic-asQuadTol";
1034 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001035
mtkleina1ebeb22015-10-01 09:43:39 -07001036 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +00001037 for (int i = 0; i < loops; ++i) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001038 for (int j = 0; j < CONICS; ++j) {
1039 fConics[j].asQuadTol(SK_ScalarHalf);
1040 }
1041 }
1042 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001043
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001044private:
1045 typedef ConicBench INHERITED;
1046};
1047
1048class ConicBench_quadPow2 : public ConicBench {
1049public:
mtklein@google.com410e6e82013-09-13 19:52:27 +00001050 ConicBench_quadPow2() {}
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001051
1052protected:
mtklein36352bf2015-03-25 18:17:31 -07001053 const char* onGetName() override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001054 return "conic-quadPow2";
1055 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001056
mtkleina1ebeb22015-10-01 09:43:39 -07001057 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +00001058 for (int i = 0; i < loops; ++i) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001059 for (int j = 0; j < CONICS; ++j) {
1060 fConics[j].computeQuadPOW2(SK_ScalarHalf);
1061 }
1062 }
1063 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001064
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001065private:
1066 typedef ConicBench INHERITED;
1067};
1068
1069///////////////////////////////////////////////////////////////////////////////
1070
Mike Reed0d7dac82017-02-02 17:45:56 -08001071class TightBoundsBench : public Benchmark {
1072 SkPath fPath;
1073 SkString fName;
Mike Reed8d3196b2017-02-03 11:34:13 -05001074 SkRect (*fProc)(const SkPath&);
Mike Reed0d7dac82017-02-02 17:45:56 -08001075
1076public:
Mike Reed8d3196b2017-02-03 11:34:13 -05001077 TightBoundsBench(SkRect (*proc)(const SkPath&), const char suffix[]) : fProc(proc) {
Mike Reed0d7dac82017-02-02 17:45:56 -08001078 fName.printf("tight_bounds_%s", suffix);
Yuqian Li9d5dcda2017-06-23 16:44:34 -04001079
Mike Reed0d7dac82017-02-02 17:45:56 -08001080 const int N = 100;
1081 SkRandom rand;
1082 for (int i = 0; i < N; ++i) {
1083 fPath.moveTo(rand.nextF()*100, rand.nextF()*100);
1084 fPath.lineTo(rand.nextF()*100, rand.nextF()*100);
1085 fPath.quadTo(rand.nextF()*100, rand.nextF()*100, rand.nextF()*100, rand.nextF()*100);
1086 fPath.conicTo(rand.nextF()*100, rand.nextF()*100, rand.nextF()*100, rand.nextF()*100,
1087 rand.nextF()*10);
1088 fPath.cubicTo(rand.nextF()*100, rand.nextF()*100, rand.nextF()*100, rand.nextF()*100,
1089 rand.nextF()*100, rand.nextF()*100);
1090 }
1091 }
1092
1093protected:
1094 bool isSuitableFor(Backend backend) override {
1095 return backend == kNonRendering_Backend;
1096 }
1097
1098 const char* onGetName() override { return fName.c_str(); }
Yuqian Li9d5dcda2017-06-23 16:44:34 -04001099
Mike Reed0d7dac82017-02-02 17:45:56 -08001100 void onDraw(int loops, SkCanvas* canvas) override {
Mike Reed0d7dac82017-02-02 17:45:56 -08001101 for (int i = 0; i < loops*100; ++i) {
Mike Reed8d3196b2017-02-03 11:34:13 -05001102 fProc(fPath);
Mike Reed0d7dac82017-02-02 17:45:56 -08001103 }
1104 }
Yuqian Li9d5dcda2017-06-23 16:44:34 -04001105
Mike Reed0d7dac82017-02-02 17:45:56 -08001106private:
1107 typedef Benchmark INHERITED;
1108};
1109
1110
bsalomon@google.com9bee33a2012-11-13 21:51:38 +00001111const SkRect ConservativelyContainsBench::kBounds = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
Hal Canaryfafe1352017-04-11 12:12:02 -04001112const SkSize ConservativelyContainsBench::kQueryMin = {SkIntToScalar(1), SkIntToScalar(1)};
1113const SkSize ConservativelyContainsBench::kQueryMax = {SkIntToScalar(40), SkIntToScalar(40)};
bsalomon@google.com9bee33a2012-11-13 21:51:38 +00001114const SkRect ConservativelyContainsBench::kBaseRect = SkRect::MakeXYWH(SkIntToScalar(25), SkIntToScalar(25), SkIntToScalar(50), SkIntToScalar(50));
1115const SkScalar ConservativelyContainsBench::kRRRadii[2] = {SkIntToScalar(5), SkIntToScalar(10)};
1116
mtklein@google.com410e6e82013-09-13 19:52:27 +00001117DEF_BENCH( return new TrianglePathBench(FLAGS00); )
1118DEF_BENCH( return new TrianglePathBench(FLAGS01); )
1119DEF_BENCH( return new TrianglePathBench(FLAGS10); )
1120DEF_BENCH( return new TrianglePathBench(FLAGS11); )
reed@google.comd34658a2011-04-11 13:12:51 +00001121
mtklein@google.com410e6e82013-09-13 19:52:27 +00001122DEF_BENCH( return new RectPathBench(FLAGS00); )
1123DEF_BENCH( return new RectPathBench(FLAGS01); )
1124DEF_BENCH( return new RectPathBench(FLAGS10); )
1125DEF_BENCH( return new RectPathBench(FLAGS11); )
reed@google.comd34658a2011-04-11 13:12:51 +00001126
liyuqiana27f6692016-06-20 14:05:27 -07001127DEF_BENCH( return new RotatedRectBench(FLAGS00, false, 45));
1128DEF_BENCH( return new RotatedRectBench(FLAGS10, false, 45));
1129DEF_BENCH( return new RotatedRectBench(FLAGS00, true, 45));
1130DEF_BENCH( return new RotatedRectBench(FLAGS10, true, 45));
1131
mtklein@google.com410e6e82013-09-13 19:52:27 +00001132DEF_BENCH( return new OvalPathBench(FLAGS00); )
1133DEF_BENCH( return new OvalPathBench(FLAGS01); )
1134DEF_BENCH( return new OvalPathBench(FLAGS10); )
1135DEF_BENCH( return new OvalPathBench(FLAGS11); )
reed@google.comd34658a2011-04-11 13:12:51 +00001136
mtklein@google.com410e6e82013-09-13 19:52:27 +00001137DEF_BENCH( return new CirclePathBench(FLAGS00); )
1138DEF_BENCH( return new CirclePathBench(FLAGS01); )
1139DEF_BENCH( return new CirclePathBench(FLAGS10); )
1140DEF_BENCH( return new CirclePathBench(FLAGS11); )
bsalomon@google.com1647a192012-04-11 15:34:46 +00001141
Yuqian Li8eedbfc2017-01-11 13:55:49 +00001142DEF_BENCH( return new NonAACirclePathBench(FLAGS00); )
1143DEF_BENCH( return new NonAACirclePathBench(FLAGS10); )
1144
Yuqian Li131c1fb2016-12-12 16:24:47 -05001145DEF_BENCH( return new AAAConcavePathBench(FLAGS00); )
1146DEF_BENCH( return new AAAConcavePathBench(FLAGS10); )
1147DEF_BENCH( return new AAAConvexPathBench(FLAGS00); )
1148DEF_BENCH( return new AAAConvexPathBench(FLAGS10); )
1149
mtklein@google.com410e6e82013-09-13 19:52:27 +00001150DEF_BENCH( return new SawToothPathBench(FLAGS00); )
1151DEF_BENCH( return new SawToothPathBench(FLAGS01); )
reed@google.comd34658a2011-04-11 13:12:51 +00001152
mtklein@google.com410e6e82013-09-13 19:52:27 +00001153DEF_BENCH( return new LongCurvedPathBench(FLAGS00); )
1154DEF_BENCH( return new LongCurvedPathBench(FLAGS01); )
1155DEF_BENCH( return new LongLinePathBench(FLAGS00); )
1156DEF_BENCH( return new LongLinePathBench(FLAGS01); )
tomhudson@google.com6e8d3352011-06-22 17:16:35 +00001157
mtklein@google.com410e6e82013-09-13 19:52:27 +00001158DEF_BENCH( return new PathCreateBench(); )
1159DEF_BENCH( return new PathCopyBench(); )
1160DEF_BENCH( return new PathTransformBench(true); )
1161DEF_BENCH( return new PathTransformBench(false); )
1162DEF_BENCH( return new PathEqualityBench(); )
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +00001163
mtklein@google.com410e6e82013-09-13 19:52:27 +00001164DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAdd_AddType); )
1165DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAddTrans_AddType); )
1166DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAddMatrix_AddType); )
mtklein@google.com410e6e82013-09-13 19:52:27 +00001167DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kReverseAdd_AddType); )
1168DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kReversePathTo_AddType); )
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +00001169
mtklein@google.com410e6e82013-09-13 19:52:27 +00001170DEF_BENCH( return new CirclesBench(FLAGS00); )
1171DEF_BENCH( return new CirclesBench(FLAGS01); )
1172DEF_BENCH( return new ArbRoundRectBench(false); )
1173DEF_BENCH( return new ArbRoundRectBench(true); )
1174DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kRect_Type); )
1175DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kRoundRect_Type); )
1176DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kOval_Type); )
mike@reedtribe.org8d551012013-04-14 02:40:50 +00001177
Mike Reed0d7dac82017-02-02 17:45:56 -08001178#include "SkPathOps.h"
1179#include "SkPathPriv.h"
Mike Reed8d3196b2017-02-03 11:34:13 -05001180DEF_BENCH( return new TightBoundsBench([](const SkPath& path){ return path.computeTightBounds();},
1181 "priv"); )
1182DEF_BENCH( return new TightBoundsBench([](const SkPath& path) {
1183 SkRect bounds; TightBounds(path, &bounds); return bounds;
1184 }, "pathops"); )
reedb6402032015-03-20 13:23:43 -07001185
Mike Klein3f376a52014-07-16 20:23:43 -04001186// These seem to be optimized away, which is troublesome for timing.
1187/*
mtklein@google.com410e6e82013-09-13 19:52:27 +00001188DEF_BENCH( return new ConicBench_Chop5() )
mtklein@google.com410e6e82013-09-13 19:52:27 +00001189DEF_BENCH( return new ConicBench_ComputeError() )
1190DEF_BENCH( return new ConicBench_asQuadTol() )
1191DEF_BENCH( return new ConicBench_quadPow2() )
Mike Klein3f376a52014-07-16 20:23:43 -04001192*/