blob: 4ca44011634620e210afdba81b6071489c6cc354 [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 Li131c1fb2016-12-12 16:24:47 -0500176// Test max speedup of Analytic AA for concave paths
177class AAAConcavePathBench : public PathBench {
178public:
179 AAAConcavePathBench(Flags flags) : INHERITED(flags) {}
180
181 void appendName(SkString* name) override {
182 name->append("concave_aaa");
183 }
184
185 void makePath(SkPath* path) override {
186 path->moveTo(10, 10);
187 path->lineTo(15, 10);
188 path->lineTo(15, 5);
189 path->lineTo(40, 40);
190 path->close();
191 }
192
193private:
194 typedef PathBench INHERITED;
195};
196
197// Test max speedup of Analytic AA for convex paths
198class AAAConvexPathBench : public PathBench {
199public:
200 AAAConvexPathBench(Flags flags) : INHERITED(flags) {}
201
202 void appendName(SkString* name) override {
203 name->append("convex_aaa");
204 }
205
206 void makePath(SkPath* path) override {
207 path->moveTo(10, 10);
208 path->lineTo(15, 10);
209 path->lineTo(40, 50);
210 path->close();
211 }
212
213private:
214 typedef PathBench INHERITED;
215};
216
reed@google.comd34658a2011-04-11 13:12:51 +0000217class SawToothPathBench : public PathBench {
218public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000219 SawToothPathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000220
mtklein36352bf2015-03-25 18:17:31 -0700221 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000222 name->append("sawtooth");
223 }
mtkleinf0599002015-07-13 06:18:39 -0700224 void makePath(SkPath* path) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000225 SkScalar x = SkIntToScalar(20);
226 SkScalar y = SkIntToScalar(20);
227 const SkScalar x0 = x;
228 const SkScalar dx = SK_Scalar1 * 5;
229 const SkScalar dy = SK_Scalar1 * 10;
230
231 path->moveTo(x, y);
232 for (int i = 0; i < 32; i++) {
233 x += dx;
234 path->lineTo(x, y - dy);
235 x += dx;
236 path->lineTo(x, y + dy);
237 }
238 path->lineTo(x, y + 2 * dy);
239 path->lineTo(x0, y + 2 * dy);
240 path->close();
241 }
mtklein36352bf2015-03-25 18:17:31 -0700242 int complexity() override { return 1; }
reed@google.comd34658a2011-04-11 13:12:51 +0000243private:
244 typedef PathBench INHERITED;
245};
246
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000247class LongCurvedPathBench : public PathBench {
248public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000249 LongCurvedPathBench(Flags flags) : INHERITED(flags) {}
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000250
mtklein36352bf2015-03-25 18:17:31 -0700251 void appendName(SkString* name) override {
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000252 name->append("long_curved");
253 }
mtklein36352bf2015-03-25 18:17:31 -0700254 void makePath(SkPath* path) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000255 SkRandom rand (12);
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000256 int i;
257 for (i = 0; i < 100; i++) {
258 path->quadTo(SkScalarMul(rand.nextUScalar1(), SkIntToScalar(640)),
259 SkScalarMul(rand.nextUScalar1(), SkIntToScalar(480)),
260 SkScalarMul(rand.nextUScalar1(), SkIntToScalar(640)),
261 SkScalarMul(rand.nextUScalar1(), SkIntToScalar(480)));
262 }
263 path->close();
264 }
mtklein36352bf2015-03-25 18:17:31 -0700265 int complexity() override { return 2; }
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000266private:
267 typedef PathBench INHERITED;
268};
269
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000270class LongLinePathBench : public PathBench {
271public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000272 LongLinePathBench(Flags flags) : INHERITED(flags) {}
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000273
mtklein36352bf2015-03-25 18:17:31 -0700274 void appendName(SkString* name) override {
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000275 name->append("long_line");
276 }
mtklein36352bf2015-03-25 18:17:31 -0700277 void makePath(SkPath* path) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000278 SkRandom rand;
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000279 path->moveTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
280 for (size_t i = 1; i < 100; i++) {
281 path->lineTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
282 }
283 }
mtklein36352bf2015-03-25 18:17:31 -0700284 int complexity() override { return 2; }
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000285private:
286 typedef PathBench INHERITED;
287};
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000288
tfarinaf168b862014-06-19 12:32:29 -0700289class RandomPathBench : public Benchmark {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000290public:
mtklein36352bf2015-03-25 18:17:31 -0700291 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000292 return backend == kNonRendering_Backend;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000293 }
294
295protected:
296 void createData(int minVerbs,
297 int maxVerbs,
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000298 bool allowMoves = true,
halcanary96fcdcc2015-08-27 07:41:13 -0700299 SkRect* bounds = nullptr) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000300 SkRect tempBounds;
halcanary96fcdcc2015-08-27 07:41:13 -0700301 if (nullptr == bounds) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000302 tempBounds.setXYWH(0, 0, SK_Scalar1, SK_Scalar1);
303 bounds = &tempBounds;
304 }
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000305 fVerbCnts.reset(kNumVerbCnts);
306 for (int i = 0; i < kNumVerbCnts; ++i) {
307 fVerbCnts[i] = fRandom.nextRangeU(minVerbs, maxVerbs + 1);
308 }
309 fVerbs.reset(kNumVerbs);
310 for (int i = 0; i < kNumVerbs; ++i) {
311 do {
312 fVerbs[i] = static_cast<SkPath::Verb>(fRandom.nextULessThan(SkPath::kDone_Verb));
313 } while (!allowMoves && SkPath::kMove_Verb == fVerbs[i]);
314 }
315 fPoints.reset(kNumPoints);
316 for (int i = 0; i < kNumPoints; ++i) {
317 fPoints[i].set(fRandom.nextRangeScalar(bounds->fLeft, bounds->fRight),
318 fRandom.nextRangeScalar(bounds->fTop, bounds->fBottom));
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000319 }
320 this->restartMakingPaths();
321 }
322
323 void restartMakingPaths() {
324 fCurrPath = 0;
325 fCurrVerb = 0;
326 fCurrPoint = 0;
327 }
328
329 void makePath(SkPath* path) {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000330 int vCount = fVerbCnts[(fCurrPath++) & (kNumVerbCnts - 1)];
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000331 for (int v = 0; v < vCount; ++v) {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000332 int verb = fVerbs[(fCurrVerb++) & (kNumVerbs - 1)];
333 switch (verb) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000334 case SkPath::kMove_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000335 path->moveTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000336 break;
337 case SkPath::kLine_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000338 path->lineTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000339 break;
340 case SkPath::kQuad_Verb:
bsalomon@google.com373ebc62012-09-26 13:08:56 +0000341 path->quadTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
342 fPoints[(fCurrPoint + 1) & (kNumPoints - 1)]);
343 fCurrPoint += 2;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000344 break;
reed@google.com277c3f82013-05-31 15:17:50 +0000345 case SkPath::kConic_Verb:
346 path->conicTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
347 fPoints[(fCurrPoint + 1) & (kNumPoints - 1)],
348 SK_ScalarHalf);
349 fCurrPoint += 2;
350 break;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000351 case SkPath::kCubic_Verb:
bsalomon@google.com373ebc62012-09-26 13:08:56 +0000352 path->cubicTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
353 fPoints[(fCurrPoint + 1) & (kNumPoints - 1)],
354 fPoints[(fCurrPoint + 2) & (kNumPoints - 1)]);
355 fCurrPoint += 3;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000356 break;
357 case SkPath::kClose_Verb:
358 path->close();
359 break;
360 default:
361 SkDEBUGFAIL("Unexpected path verb");
362 break;
363 }
364 }
365 }
366
367 void finishedMakingPaths() {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000368 fVerbCnts.reset(0);
369 fVerbs.reset(0);
370 fPoints.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000371 }
372
373private:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000374 enum {
375 // these should all be pow 2
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000376 kNumVerbCnts = 1 << 5,
377 kNumVerbs = 1 << 5,
378 kNumPoints = 1 << 5,
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000379 };
380 SkAutoTArray<int> fVerbCnts;
381 SkAutoTArray<SkPath::Verb> fVerbs;
382 SkAutoTArray<SkPoint> fPoints;
383 int fCurrPath;
384 int fCurrVerb;
385 int fCurrPoint;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000386 SkRandom fRandom;
tfarinaf168b862014-06-19 12:32:29 -0700387 typedef Benchmark INHERITED;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000388};
389
390class PathCreateBench : public RandomPathBench {
391public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000392 PathCreateBench() {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000393 }
394
395protected:
mtklein36352bf2015-03-25 18:17:31 -0700396 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000397 return "path_create";
398 }
399
joshualitt8a6697a2015-09-30 12:11:07 -0700400 void onDelayedSetup() override {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000401 this->createData(10, 100);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000402 }
403
mtkleina1ebeb22015-10-01 09:43:39 -0700404 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000405 for (int i = 0; i < loops; ++i) {
commit-bot@chromium.org8f881172014-01-06 20:19:14 +0000406 if (i % 1000 == 0) {
407 fPath.reset(); // PathRef memory can grow without bound otherwise.
408 }
409 this->makePath(&fPath);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000410 }
411 this->restartMakingPaths();
412 }
413
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000414private:
commit-bot@chromium.org8f881172014-01-06 20:19:14 +0000415 SkPath fPath;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000416
417 typedef RandomPathBench INHERITED;
418};
419
420class PathCopyBench : public RandomPathBench {
421public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000422 PathCopyBench() {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000423 }
424
425protected:
mtklein36352bf2015-03-25 18:17:31 -0700426 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000427 return "path_copy";
428 }
joshualitt8a6697a2015-09-30 12:11:07 -0700429 void onDelayedSetup() override {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000430 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000431 fPaths.reset(kPathCnt);
432 fCopies.reset(kPathCnt);
433 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000434 this->makePath(&fPaths[i]);
435 }
436 this->finishedMakingPaths();
437 }
mtkleina1ebeb22015-10-01 09:43:39 -0700438 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000439 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000440 int idx = i & (kPathCnt - 1);
441 fCopies[idx] = fPaths[idx];
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000442 }
443 }
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000444
445private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000446 enum {
447 // must be a pow 2
448 kPathCnt = 1 << 5,
449 };
450 SkAutoTArray<SkPath> fPaths;
451 SkAutoTArray<SkPath> fCopies;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000452
453 typedef RandomPathBench INHERITED;
454};
455
456class PathTransformBench : public RandomPathBench {
457public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000458 PathTransformBench(bool inPlace) : fInPlace(inPlace) {}
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000459
460protected:
mtklein36352bf2015-03-25 18:17:31 -0700461 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000462 return fInPlace ? "path_transform_in_place" : "path_transform_copy";
463 }
464
joshualitt8a6697a2015-09-30 12:11:07 -0700465 void onDelayedSetup() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000466 fMatrix.setScale(5 * SK_Scalar1, 6 * SK_Scalar1);
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000467 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000468 fPaths.reset(kPathCnt);
469 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000470 this->makePath(&fPaths[i]);
471 }
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000472 this->finishedMakingPaths();
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000473 if (!fInPlace) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000474 fTransformed.reset(kPathCnt);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000475 }
476 }
477
mtkleina1ebeb22015-10-01 09:43:39 -0700478 void onDraw(int loops, SkCanvas*) override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000479 if (fInPlace) {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000480 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000481 fPaths[i & (kPathCnt - 1)].transform(fMatrix);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000482 }
483 } else {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000484 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000485 int idx = i & (kPathCnt - 1);
486 fPaths[idx].transform(fMatrix, &fTransformed[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000487 }
488 }
489 }
490
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000491private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000492 enum {
493 // must be a pow 2
494 kPathCnt = 1 << 5,
495 };
496 SkAutoTArray<SkPath> fPaths;
497 SkAutoTArray<SkPath> fTransformed;
498
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000499 SkMatrix fMatrix;
500 bool fInPlace;
501 typedef RandomPathBench INHERITED;
502};
503
504class PathEqualityBench : public RandomPathBench {
505public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000506 PathEqualityBench() { }
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000507
508protected:
mtklein36352bf2015-03-25 18:17:31 -0700509 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000510 return "path_equality_50%";
511 }
512
joshualitt8a6697a2015-09-30 12:11:07 -0700513 void onDelayedSetup() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000514 fParity = 0;
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000515 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000516 fPaths.reset(kPathCnt);
517 fCopies.reset(kPathCnt);
518 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000519 this->makePath(&fPaths[i]);
520 fCopies[i] = fPaths[i];
521 }
522 this->finishedMakingPaths();
523 }
524
mtkleina1ebeb22015-10-01 09:43:39 -0700525 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000526 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000527 int idx = i & (kPathCnt - 1);
528 fParity ^= (fPaths[idx] == fCopies[idx & ~0x1]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000529 }
530 }
531
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000532private:
533 bool fParity; // attempt to keep compiler from optimizing out the ==
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000534 enum {
535 // must be a pow 2
536 kPathCnt = 1 << 5,
537 };
538 SkAutoTArray<SkPath> fPaths;
539 SkAutoTArray<SkPath> fCopies;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000540 typedef RandomPathBench INHERITED;
541};
542
543class SkBench_AddPathTest : public RandomPathBench {
544public:
545 enum AddType {
546 kAdd_AddType,
547 kAddTrans_AddType,
548 kAddMatrix_AddType,
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000549 kReverseAdd_AddType,
550 kReversePathTo_AddType,
551 };
552
mtklein@google.com410e6e82013-09-13 19:52:27 +0000553 SkBench_AddPathTest(AddType type) : fType(type) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000554 fMatrix.setRotate(60 * SK_Scalar1);
555 }
556
557protected:
mtklein36352bf2015-03-25 18:17:31 -0700558 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000559 switch (fType) {
560 case kAdd_AddType:
561 return "path_add_path";
562 case kAddTrans_AddType:
563 return "path_add_path_trans";
564 case kAddMatrix_AddType:
565 return "path_add_path_matrix";
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000566 case kReverseAdd_AddType:
567 return "path_reverse_add_path";
568 case kReversePathTo_AddType:
569 return "path_reverse_path_to";
570 default:
571 SkDEBUGFAIL("Bad add type");
572 return "";
573 }
574 }
575
joshualitt8a6697a2015-09-30 12:11:07 -0700576 void onDelayedSetup() override {
commit-bot@chromium.orga1a097e2013-11-14 16:53:22 +0000577 // reversePathTo assumes a single contour path.
578 bool allowMoves = kReversePathTo_AddType != fType;
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000579 this->createData(10, 100, allowMoves);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000580 fPaths0.reset(kPathCnt);
581 fPaths1.reset(kPathCnt);
582 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000583 this->makePath(&fPaths0[i]);
584 this->makePath(&fPaths1[i]);
585 }
586 this->finishedMakingPaths();
587 }
588
mtkleina1ebeb22015-10-01 09:43:39 -0700589 void onDraw(int loops, SkCanvas*) override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000590 switch (fType) {
591 case kAdd_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000592 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000593 int idx = i & (kPathCnt - 1);
594 SkPath result = fPaths0[idx];
595 result.addPath(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000596 }
597 break;
598 case kAddTrans_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000599 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000600 int idx = i & (kPathCnt - 1);
601 SkPath result = fPaths0[idx];
602 result.addPath(fPaths1[idx], 2 * SK_Scalar1, 5 * SK_Scalar1);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000603 }
604 break;
605 case kAddMatrix_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000606 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000607 int idx = i & (kPathCnt - 1);
608 SkPath result = fPaths0[idx];
609 result.addPath(fPaths1[idx], fMatrix);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000610 }
611 break;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000612 case kReverseAdd_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000613 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000614 int idx = i & (kPathCnt - 1);
615 SkPath result = fPaths0[idx];
616 result.reverseAddPath(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000617 }
618 break;
619 case kReversePathTo_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000620 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000621 int idx = i & (kPathCnt - 1);
622 SkPath result = fPaths0[idx];
623 result.reversePathTo(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000624 }
625 break;
626 }
627 }
628
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000629private:
630 AddType fType; // or reverseAddPath
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000631 enum {
632 // must be a pow 2
633 kPathCnt = 1 << 5,
634 };
635 SkAutoTArray<SkPath> fPaths0;
636 SkAutoTArray<SkPath> fPaths1;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000637 SkMatrix fMatrix;
638 typedef RandomPathBench INHERITED;
639};
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000640
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000641
tfarinaf168b862014-06-19 12:32:29 -0700642class CirclesBench : public Benchmark {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000643protected:
644 SkString fName;
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000645 Flags fFlags;
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000646
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000647public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000648 CirclesBench(Flags flags) : fFlags(flags) {
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000649 fName.printf("circles_%s", fFlags & kStroke_Flag ? "stroke" : "fill");
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000650 }
651
652protected:
mtklein36352bf2015-03-25 18:17:31 -0700653 const char* onGetName() override {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000654 return fName.c_str();
655 }
656
mtkleina1ebeb22015-10-01 09:43:39 -0700657 void onDraw(int loops, SkCanvas* canvas) override {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000658 SkPaint paint;
659
660 paint.setColor(SK_ColorBLACK);
661 paint.setAntiAlias(true);
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000662 if (fFlags & kStroke_Flag) {
663 paint.setStyle(SkPaint::kStroke_Style);
664 }
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000665
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000666 SkRandom rand;
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000667
668 SkRect r;
669
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000670 for (int i = 0; i < loops; ++i) {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000671 SkScalar radius = rand.nextUScalar1() * 3;
672 r.fLeft = rand.nextUScalar1() * 300;
673 r.fTop = rand.nextUScalar1() * 300;
674 r.fRight = r.fLeft + 2 * radius;
675 r.fBottom = r.fTop + 2 * radius;
676
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000677 if (fFlags & kStroke_Flag) {
678 paint.setStrokeWidth(rand.nextUScalar1() * 5.0f);
679 }
680
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000681 SkPath temp;
682
683 // mimic how Chrome does circles
684 temp.arcTo(r, 0, 0, false);
685 temp.addOval(r, SkPath::kCCW_Direction);
686 temp.arcTo(r, 360, 0, true);
687 temp.close();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000688
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000689 canvas->drawPath(temp, paint);
690 }
691 }
692
693private:
tfarinaf168b862014-06-19 12:32:29 -0700694 typedef Benchmark INHERITED;
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000695};
696
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000697
robertphillips@google.com158618e2012-10-23 16:56:56 +0000698// Chrome creates its own round rects with each corner possibly being different.
699// In its "zero radius" incarnation it creates degenerate round rects.
skia.committer@gmail.com1e34ff72012-10-24 02:01:24 +0000700// Note: PathTest::test_arb_round_rect_is_convex and
robertphillips@google.com158618e2012-10-23 16:56:56 +0000701// test_arb_zero_rad_round_rect_is_rect perform almost exactly
robertphillips@google.comb95eaa82012-10-18 15:26:12 +0000702// the same test (but with no drawing)
tfarinaf168b862014-06-19 12:32:29 -0700703class ArbRoundRectBench : public Benchmark {
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000704protected:
705 SkString fName;
706
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000707public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000708 ArbRoundRectBench(bool zeroRad) : fZeroRad(zeroRad) {
robertphillips@google.com158618e2012-10-23 16:56:56 +0000709 if (zeroRad) {
710 fName.printf("zeroradroundrect");
711 } else {
712 fName.printf("arbroundrect");
713 }
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000714 }
715
716protected:
mtklein36352bf2015-03-25 18:17:31 -0700717 const char* onGetName() override {
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000718 return fName.c_str();
719 }
720
skia.committer@gmail.com989a95e2012-10-18 02:01:23 +0000721 static void add_corner_arc(SkPath* path, const SkRect& rect,
722 SkScalar xIn, SkScalar yIn,
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000723 int startAngle)
724 {
725
726 SkScalar rx = SkMinScalar(rect.width(), xIn);
727 SkScalar ry = SkMinScalar(rect.height(), yIn);
728
729 SkRect arcRect;
730 arcRect.set(-rx, -ry, rx, ry);
731 switch (startAngle) {
732 case 0:
733 arcRect.offset(rect.fRight - arcRect.fRight, rect.fBottom - arcRect.fBottom);
734 break;
735 case 90:
736 arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fBottom - arcRect.fBottom);
737 break;
738 case 180:
739 arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fTop - arcRect.fTop);
740 break;
741 case 270:
742 arcRect.offset(rect.fRight - arcRect.fRight, rect.fTop - arcRect.fTop);
743 break;
744 default:
745 break;
746 }
747
748 path->arcTo(arcRect, SkIntToScalar(startAngle), SkIntToScalar(90), false);
749 }
750
skia.committer@gmail.com989a95e2012-10-18 02:01:23 +0000751 static void make_arb_round_rect(SkPath* path, const SkRect& r,
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000752 SkScalar xCorner, SkScalar yCorner) {
753 // we are lazy here and use the same x & y for each corner
754 add_corner_arc(path, r, xCorner, yCorner, 270);
755 add_corner_arc(path, r, xCorner, yCorner, 0);
756 add_corner_arc(path, r, xCorner, yCorner, 90);
757 add_corner_arc(path, r, xCorner, yCorner, 180);
robertphillips@google.com158618e2012-10-23 16:56:56 +0000758 path->close();
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000759
robertphillips@google.comb95eaa82012-10-18 15:26:12 +0000760 SkASSERT(path->isConvex());
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000761 }
762
mtkleina1ebeb22015-10-01 09:43:39 -0700763 void onDraw(int loops, SkCanvas* canvas) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000764 SkRandom rand;
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000765 SkRect r;
766
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000767 for (int i = 0; i < loops; ++i) {
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000768 SkPaint paint;
769 paint.setColor(0xff000000 | rand.nextU());
770 paint.setAntiAlias(true);
771
robertphillips@google.com158618e2012-10-23 16:56:56 +0000772 SkScalar size = rand.nextUScalar1() * 30;
773 if (size < SK_Scalar1) {
robertphillips@google.comb95eaa82012-10-18 15:26:12 +0000774 continue;
775 }
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000776 r.fLeft = rand.nextUScalar1() * 300;
777 r.fTop = rand.nextUScalar1() * 300;
robertphillips@google.com158618e2012-10-23 16:56:56 +0000778 r.fRight = r.fLeft + 2 * size;
779 r.fBottom = r.fTop + 2 * size;
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000780
781 SkPath temp;
782
robertphillips@google.com158618e2012-10-23 16:56:56 +0000783 if (fZeroRad) {
784 make_arb_round_rect(&temp, r, 0, 0);
785
halcanary96fcdcc2015-08-27 07:41:13 -0700786 SkASSERT(temp.isRect(nullptr));
robertphillips@google.com158618e2012-10-23 16:56:56 +0000787 } else {
788 make_arb_round_rect(&temp, r, r.width() / 10, r.height() / 15);
789 }
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000790
791 canvas->drawPath(temp, paint);
792 }
793 }
794
795private:
robertphillips@google.com158618e2012-10-23 16:56:56 +0000796 bool fZeroRad; // should 0 radius rounds rects be tested?
797
tfarinaf168b862014-06-19 12:32:29 -0700798 typedef Benchmark INHERITED;
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000799};
800
tfarinaf168b862014-06-19 12:32:29 -0700801class ConservativelyContainsBench : public Benchmark {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000802public:
803 enum Type {
804 kRect_Type,
805 kRoundRect_Type,
806 kOval_Type,
807 };
808
mtklein@google.com410e6e82013-09-13 19:52:27 +0000809 ConservativelyContainsBench(Type type) {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000810 fParity = false;
811 fName = "conservatively_contains_";
812 switch (type) {
813 case kRect_Type:
814 fName.append("rect");
815 fPath.addRect(kBaseRect);
816 break;
817 case kRoundRect_Type:
818 fName.append("round_rect");
819 fPath.addRoundRect(kBaseRect, kRRRadii[0], kRRRadii[1]);
820 break;
821 case kOval_Type:
822 fName.append("oval");
823 fPath.addOval(kBaseRect);
824 break;
825 }
826 }
827
mtklein36352bf2015-03-25 18:17:31 -0700828 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000829 return backend == kNonRendering_Backend;
830 }
831
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000832private:
mtklein36352bf2015-03-25 18:17:31 -0700833 const char* onGetName() override {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000834 return fName.c_str();
835 }
836
mtkleina1ebeb22015-10-01 09:43:39 -0700837 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000838 for (int i = 0; i < loops; ++i) {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000839 const SkRect& rect = fQueryRects[i % kQueryRectCnt];
840 fParity = fParity != fPath.conservativelyContainsRect(rect);
841 }
842 }
843
joshualitt8a6697a2015-09-30 12:11:07 -0700844 void onDelayedSetup() override {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000845 fQueryRects.setCount(kQueryRectCnt);
846
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000847 SkRandom rand;
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000848 for (int i = 0; i < kQueryRectCnt; ++i) {
849 SkSize size;
850 SkPoint xy;
851 size.fWidth = rand.nextRangeScalar(kQueryMin.fWidth, kQueryMax.fWidth);
852 size.fHeight = rand.nextRangeScalar(kQueryMin.fHeight, kQueryMax.fHeight);
853 xy.fX = rand.nextRangeScalar(kBounds.fLeft, kBounds.fRight - size.fWidth);
854 xy.fY = rand.nextRangeScalar(kBounds.fTop, kBounds.fBottom - size.fHeight);
855
856 fQueryRects[i] = SkRect::MakeXYWH(xy.fX, xy.fY, size.fWidth, size.fHeight);
857 }
858 }
859
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000860 enum {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000861 kQueryRectCnt = 400,
862 };
863 static const SkRect kBounds; // bounds for all random query rects
864 static const SkSize kQueryMin; // minimum query rect size, should be <= kQueryMax
865 static const SkSize kQueryMax; // max query rect size, should < kBounds
866 static const SkRect kBaseRect; // rect that is used to construct the path
867 static const SkScalar kRRRadii[2]; // x and y radii for round rect
868
869 SkString fName;
870 SkPath fPath;
871 bool fParity;
872 SkTDArray<SkRect> fQueryRects;
873
tfarinaf168b862014-06-19 12:32:29 -0700874 typedef Benchmark INHERITED;
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000875};
876
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000877///////////////////////////////////////////////////////////////////////////////
878
879#include "SkGeometry.h"
880
reed55011032015-03-26 09:10:22 -0700881class ConicBench_Chop : public Benchmark {
reedb6402032015-03-20 13:23:43 -0700882protected:
883 SkConic fRQ, fDst[2];
884 SkString fName;
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000885public:
reed55011032015-03-26 09:10:22 -0700886 ConicBench_Chop() : fName("conic-chop") {
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000887 fRQ.fPts[0].set(0, 0);
888 fRQ.fPts[1].set(100, 0);
889 fRQ.fPts[2].set(100, 100);
890 fRQ.fW = SkScalarCos(SK_ScalarPI/4);
reedb6402032015-03-20 13:23:43 -0700891 }
892
mtklein36352bf2015-03-25 18:17:31 -0700893 bool isSuitableFor(Backend backend) override {
reedb6402032015-03-20 13:23:43 -0700894 return backend == kNonRendering_Backend;
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000895 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000896
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000897private:
mtklein36352bf2015-03-25 18:17:31 -0700898 const char* onGetName() override { return fName.c_str(); }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000899
mtkleina1ebeb22015-10-01 09:43:39 -0700900 void onDraw(int loops, SkCanvas*) override {
reed55011032015-03-26 09:10:22 -0700901 for (int i = 0; i < loops; ++i) {
902 fRQ.chop(fDst);
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000903 }
904 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000905
tfarinaf168b862014-06-19 12:32:29 -0700906 typedef Benchmark INHERITED;
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000907};
reed55011032015-03-26 09:10:22 -0700908DEF_BENCH( return new ConicBench_Chop; )
reedb6402032015-03-20 13:23:43 -0700909
reed55011032015-03-26 09:10:22 -0700910class ConicBench_EvalPos : public ConicBench_Chop {
911 const bool fUseV2;
reedb6402032015-03-20 13:23:43 -0700912public:
reed55011032015-03-26 09:10:22 -0700913 ConicBench_EvalPos(bool useV2) : fUseV2(useV2) {
reedb6402032015-03-20 13:23:43 -0700914 fName.printf("conic-eval-pos%d", useV2);
915 }
mtkleina1ebeb22015-10-01 09:43:39 -0700916 void onDraw(int loops, SkCanvas*) override {
reedb6402032015-03-20 13:23:43 -0700917 if (fUseV2) {
918 for (int i = 0; i < loops; ++i) {
919 for (int j = 0; j < 1000; ++j) {
920 fDst[0].fPts[0] = fRQ.evalAt(0.4f);
921 }
922 }
923 } else {
924 for (int i = 0; i < loops; ++i) {
925 for (int j = 0; j < 1000; ++j) {
halcanary96fcdcc2015-08-27 07:41:13 -0700926 fRQ.evalAt(0.4f, &fDst[0].fPts[0], nullptr);
reedb6402032015-03-20 13:23:43 -0700927 }
928 }
929 }
930 }
931};
932DEF_BENCH( return new ConicBench_EvalPos(false); )
933DEF_BENCH( return new ConicBench_EvalPos(true); )
934
reed55011032015-03-26 09:10:22 -0700935class ConicBench_EvalTan : public ConicBench_Chop {
936 const bool fUseV2;
reedb6402032015-03-20 13:23:43 -0700937public:
reed55011032015-03-26 09:10:22 -0700938 ConicBench_EvalTan(bool useV2) : fUseV2(useV2) {
reedb6402032015-03-20 13:23:43 -0700939 fName.printf("conic-eval-tan%d", useV2);
940 }
mtkleina1ebeb22015-10-01 09:43:39 -0700941 void onDraw(int loops, SkCanvas*) override {
reedb6402032015-03-20 13:23:43 -0700942 if (fUseV2) {
943 for (int i = 0; i < loops; ++i) {
944 for (int j = 0; j < 1000; ++j) {
945 fDst[0].fPts[0] = fRQ.evalTangentAt(0.4f);
946 }
947 }
948 } else {
949 for (int i = 0; i < loops; ++i) {
950 for (int j = 0; j < 1000; ++j) {
halcanary96fcdcc2015-08-27 07:41:13 -0700951 fRQ.evalAt(0.4f, nullptr, &fDst[0].fPts[0]);
reedb6402032015-03-20 13:23:43 -0700952 }
953 }
954 }
955 }
956};
957DEF_BENCH( return new ConicBench_EvalTan(false); )
958DEF_BENCH( return new ConicBench_EvalTan(true); )
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000959
960///////////////////////////////////////////////////////////////////////////////
961
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000962static void rand_conic(SkConic* conic, SkRandom& rand) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000963 for (int i = 0; i < 3; ++i) {
964 conic->fPts[i].set(rand.nextUScalar1() * 100, rand.nextUScalar1() * 100);
965 }
966 if (rand.nextUScalar1() > 0.5f) {
967 conic->fW = rand.nextUScalar1();
968 } else {
969 conic->fW = 1 + rand.nextUScalar1() * 4;
970 }
971}
972
tfarinaf168b862014-06-19 12:32:29 -0700973class ConicBench : public Benchmark {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000974public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000975 ConicBench() {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000976 SkRandom rand;
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000977 for (int i = 0; i < CONICS; ++i) {
978 rand_conic(&fConics[i], rand);
979 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000980 }
981
mtklein36352bf2015-03-25 18:17:31 -0700982 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000983 return backend == kNonRendering_Backend;
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000984 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000985
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000986protected:
987 enum {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000988 CONICS = 100
989 };
990 SkConic fConics[CONICS];
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000991
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000992private:
tfarinaf168b862014-06-19 12:32:29 -0700993 typedef Benchmark INHERITED;
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000994};
995
996class ConicBench_ComputeError : public ConicBench {
997public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000998 ConicBench_ComputeError() {}
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000999
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001000protected:
mtklein36352bf2015-03-25 18:17:31 -07001001 const char* onGetName() override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001002 return "conic-compute-error";
1003 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001004
mtkleina1ebeb22015-10-01 09:43:39 -07001005 void onDraw(int loops, SkCanvas*) override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001006 SkVector err;
commit-bot@chromium.org33614712013-12-03 18:17:16 +00001007 for (int i = 0; i < loops; ++i) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001008 for (int j = 0; j < CONICS; ++j) {
1009 fConics[j].computeAsQuadError(&err);
1010 }
1011 }
1012 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001013
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001014private:
1015 typedef ConicBench INHERITED;
1016};
1017
1018class ConicBench_asQuadTol : public ConicBench {
1019public:
mtklein@google.com410e6e82013-09-13 19:52:27 +00001020 ConicBench_asQuadTol() {}
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001021
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001022protected:
mtklein36352bf2015-03-25 18:17:31 -07001023 const char* onGetName() override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001024 return "conic-asQuadTol";
1025 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001026
mtkleina1ebeb22015-10-01 09:43:39 -07001027 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +00001028 for (int i = 0; i < loops; ++i) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001029 for (int j = 0; j < CONICS; ++j) {
1030 fConics[j].asQuadTol(SK_ScalarHalf);
1031 }
1032 }
1033 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001034
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001035private:
1036 typedef ConicBench INHERITED;
1037};
1038
1039class ConicBench_quadPow2 : public ConicBench {
1040public:
mtklein@google.com410e6e82013-09-13 19:52:27 +00001041 ConicBench_quadPow2() {}
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001042
1043protected:
mtklein36352bf2015-03-25 18:17:31 -07001044 const char* onGetName() override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001045 return "conic-quadPow2";
1046 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001047
mtkleina1ebeb22015-10-01 09:43:39 -07001048 void onDraw(int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +00001049 for (int i = 0; i < loops; ++i) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001050 for (int j = 0; j < CONICS; ++j) {
1051 fConics[j].computeQuadPOW2(SK_ScalarHalf);
1052 }
1053 }
1054 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +00001055
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +00001056private:
1057 typedef ConicBench INHERITED;
1058};
1059
1060///////////////////////////////////////////////////////////////////////////////
1061
bsalomon@google.com9bee33a2012-11-13 21:51:38 +00001062const SkRect ConservativelyContainsBench::kBounds = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
1063const SkSize ConservativelyContainsBench::kQueryMin = SkSize::Make(SkIntToScalar(1), SkIntToScalar(1));
1064const SkSize ConservativelyContainsBench::kQueryMax = SkSize::Make(SkIntToScalar(40), SkIntToScalar(40));
1065const SkRect ConservativelyContainsBench::kBaseRect = SkRect::MakeXYWH(SkIntToScalar(25), SkIntToScalar(25), SkIntToScalar(50), SkIntToScalar(50));
1066const SkScalar ConservativelyContainsBench::kRRRadii[2] = {SkIntToScalar(5), SkIntToScalar(10)};
1067
mtklein@google.com410e6e82013-09-13 19:52:27 +00001068DEF_BENCH( return new TrianglePathBench(FLAGS00); )
1069DEF_BENCH( return new TrianglePathBench(FLAGS01); )
1070DEF_BENCH( return new TrianglePathBench(FLAGS10); )
1071DEF_BENCH( return new TrianglePathBench(FLAGS11); )
reed@google.comd34658a2011-04-11 13:12:51 +00001072
mtklein@google.com410e6e82013-09-13 19:52:27 +00001073DEF_BENCH( return new RectPathBench(FLAGS00); )
1074DEF_BENCH( return new RectPathBench(FLAGS01); )
1075DEF_BENCH( return new RectPathBench(FLAGS10); )
1076DEF_BENCH( return new RectPathBench(FLAGS11); )
reed@google.comd34658a2011-04-11 13:12:51 +00001077
liyuqiana27f6692016-06-20 14:05:27 -07001078DEF_BENCH( return new RotatedRectBench(FLAGS00, false, 45));
1079DEF_BENCH( return new RotatedRectBench(FLAGS10, false, 45));
1080DEF_BENCH( return new RotatedRectBench(FLAGS00, true, 45));
1081DEF_BENCH( return new RotatedRectBench(FLAGS10, true, 45));
1082
mtklein@google.com410e6e82013-09-13 19:52:27 +00001083DEF_BENCH( return new OvalPathBench(FLAGS00); )
1084DEF_BENCH( return new OvalPathBench(FLAGS01); )
1085DEF_BENCH( return new OvalPathBench(FLAGS10); )
1086DEF_BENCH( return new OvalPathBench(FLAGS11); )
reed@google.comd34658a2011-04-11 13:12:51 +00001087
mtklein@google.com410e6e82013-09-13 19:52:27 +00001088DEF_BENCH( return new CirclePathBench(FLAGS00); )
1089DEF_BENCH( return new CirclePathBench(FLAGS01); )
1090DEF_BENCH( return new CirclePathBench(FLAGS10); )
1091DEF_BENCH( return new CirclePathBench(FLAGS11); )
bsalomon@google.com1647a192012-04-11 15:34:46 +00001092
Yuqian Li131c1fb2016-12-12 16:24:47 -05001093DEF_BENCH( return new AAAConcavePathBench(FLAGS00); )
1094DEF_BENCH( return new AAAConcavePathBench(FLAGS10); )
1095DEF_BENCH( return new AAAConvexPathBench(FLAGS00); )
1096DEF_BENCH( return new AAAConvexPathBench(FLAGS10); )
1097
mtklein@google.com410e6e82013-09-13 19:52:27 +00001098DEF_BENCH( return new SawToothPathBench(FLAGS00); )
1099DEF_BENCH( return new SawToothPathBench(FLAGS01); )
reed@google.comd34658a2011-04-11 13:12:51 +00001100
mtklein@google.com410e6e82013-09-13 19:52:27 +00001101DEF_BENCH( return new LongCurvedPathBench(FLAGS00); )
1102DEF_BENCH( return new LongCurvedPathBench(FLAGS01); )
1103DEF_BENCH( return new LongLinePathBench(FLAGS00); )
1104DEF_BENCH( return new LongLinePathBench(FLAGS01); )
tomhudson@google.com6e8d3352011-06-22 17:16:35 +00001105
mtklein@google.com410e6e82013-09-13 19:52:27 +00001106DEF_BENCH( return new PathCreateBench(); )
1107DEF_BENCH( return new PathCopyBench(); )
1108DEF_BENCH( return new PathTransformBench(true); )
1109DEF_BENCH( return new PathTransformBench(false); )
1110DEF_BENCH( return new PathEqualityBench(); )
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +00001111
mtklein@google.com410e6e82013-09-13 19:52:27 +00001112DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAdd_AddType); )
1113DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAddTrans_AddType); )
1114DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAddMatrix_AddType); )
mtklein@google.com410e6e82013-09-13 19:52:27 +00001115DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kReverseAdd_AddType); )
1116DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kReversePathTo_AddType); )
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +00001117
mtklein@google.com410e6e82013-09-13 19:52:27 +00001118DEF_BENCH( return new CirclesBench(FLAGS00); )
1119DEF_BENCH( return new CirclesBench(FLAGS01); )
1120DEF_BENCH( return new ArbRoundRectBench(false); )
1121DEF_BENCH( return new ArbRoundRectBench(true); )
1122DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kRect_Type); )
1123DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kRoundRect_Type); )
1124DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kOval_Type); )
mike@reedtribe.org8d551012013-04-14 02:40:50 +00001125
reedb6402032015-03-20 13:23:43 -07001126
Mike Klein3f376a52014-07-16 20:23:43 -04001127// These seem to be optimized away, which is troublesome for timing.
1128/*
mtklein@google.com410e6e82013-09-13 19:52:27 +00001129DEF_BENCH( return new ConicBench_Chop5() )
mtklein@google.com410e6e82013-09-13 19:52:27 +00001130DEF_BENCH( return new ConicBench_ComputeError() )
1131DEF_BENCH( return new ConicBench_asQuadTol() )
1132DEF_BENCH( return new ConicBench_quadPow2() )
Mike Klein3f376a52014-07-16 20:23:43 -04001133*/