blob: ffec90b1464c4c75dc8d46dd2825a4df2367d5a5 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
2/*
3 * Copyright 2011 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
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"
tomhudson@google.com6e8d3352011-06-22 17:16:35 +000013#include "SkRandom.h"
reed@google.comd34658a2011-04-11 13:12:51 +000014#include "SkShader.h"
15#include "SkString.h"
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +000016#include "SkTArray.h"
17
reed@google.comd34658a2011-04-11 13:12:51 +000018enum Flags {
19 kStroke_Flag = 1 << 0,
20 kBig_Flag = 1 << 1
21};
22
23#define FLAGS00 Flags(0)
24#define FLAGS01 Flags(kStroke_Flag)
25#define FLAGS10 Flags(kBig_Flag)
26#define FLAGS11 Flags(kStroke_Flag | kBig_Flag)
27
tfarinaf168b862014-06-19 12:32:29 -070028class PathBench : public Benchmark {
reed@google.comd34658a2011-04-11 13:12:51 +000029 SkPaint fPaint;
30 SkString fName;
31 Flags fFlags;
reed@google.comd34658a2011-04-11 13:12:51 +000032public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000033 PathBench(Flags flags) : fFlags(flags) {
reed@google.comd34658a2011-04-11 13:12:51 +000034 fPaint.setStyle(flags & kStroke_Flag ? SkPaint::kStroke_Style :
35 SkPaint::kFill_Style);
36 fPaint.setStrokeWidth(SkIntToScalar(5));
37 fPaint.setStrokeJoin(SkPaint::kBevel_Join);
38 }
39
40 virtual void appendName(SkString*) = 0;
41 virtual void makePath(SkPath*) = 0;
tomhudson@google.com6e8d3352011-06-22 17:16:35 +000042 virtual int complexity() { return 0; }
reed@google.comd34658a2011-04-11 13:12:51 +000043
44protected:
mtklein36352bf2015-03-25 18:17:31 -070045 const char* onGetName() override {
reed@google.comd34658a2011-04-11 13:12:51 +000046 fName.printf("path_%s_%s_",
47 fFlags & kStroke_Flag ? "stroke" : "fill",
48 fFlags & kBig_Flag ? "big" : "small");
49 this->appendName(&fName);
50 return fName.c_str();
51 }
52
mtklein36352bf2015-03-25 18:17:31 -070053 void onDraw(const int loops, SkCanvas* canvas) override {
reed@google.comd34658a2011-04-11 13:12:51 +000054 SkPaint paint(fPaint);
55 this->setupPaint(&paint);
56
57 SkPath path;
58 this->makePath(&path);
59 if (fFlags & kBig_Flag) {
robertphillips1d24b8d2015-03-26 19:57:08 -070060 const SkMatrix m = SkMatrix::MakeScale(SkIntToScalar(10), SkIntToScalar(10));
reed@google.comd34658a2011-04-11 13:12:51 +000061 path.transform(m);
62 }
63
commit-bot@chromium.org33614712013-12-03 18:17:16 +000064 int count = loops;
reed@google.comd34658a2011-04-11 13:12:51 +000065 if (fFlags & kBig_Flag) {
66 count >>= 2;
67 }
tomhudson@google.com6e8d3352011-06-22 17:16:35 +000068 count >>= (3 * complexity());
reed@google.comd34658a2011-04-11 13:12:51 +000069
70 for (int i = 0; i < count; i++) {
71 canvas->drawPath(path, paint);
72 }
73 }
74
75private:
tfarinaf168b862014-06-19 12:32:29 -070076 typedef Benchmark INHERITED;
reed@google.comd34658a2011-04-11 13:12:51 +000077};
78
79class TrianglePathBench : public PathBench {
80public:
mtklein@google.com410e6e82013-09-13 19:52:27 +000081 TrianglePathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +000082
mtklein36352bf2015-03-25 18:17:31 -070083 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +000084 name->append("triangle");
85 }
mtklein36352bf2015-03-25 18:17:31 -070086 void makePath(SkPath* path) override {
reed@google.comd34658a2011-04-11 13:12:51 +000087 static const int gCoord[] = {
88 10, 10, 15, 5, 20, 20
89 };
90 path->moveTo(SkIntToScalar(gCoord[0]), SkIntToScalar(gCoord[1]));
91 path->lineTo(SkIntToScalar(gCoord[2]), SkIntToScalar(gCoord[3]));
92 path->lineTo(SkIntToScalar(gCoord[4]), SkIntToScalar(gCoord[5]));
93 path->close();
94 }
95private:
96 typedef PathBench INHERITED;
97};
98
99class RectPathBench : public PathBench {
100public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000101 RectPathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000102
mtklein36352bf2015-03-25 18:17:31 -0700103 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000104 name->append("rect");
105 }
mtklein36352bf2015-03-25 18:17:31 -0700106 void makePath(SkPath* path) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000107 SkRect r = { 10, 10, 20, 20 };
108 path->addRect(r);
109 }
110private:
111 typedef PathBench INHERITED;
112};
113
114class OvalPathBench : public PathBench {
115public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000116 OvalPathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000117
mtklein36352bf2015-03-25 18:17:31 -0700118 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000119 name->append("oval");
120 }
mtklein36352bf2015-03-25 18:17:31 -0700121 void makePath(SkPath* path) override {
jvanverth@google.come2bfd8b2013-01-24 15:45:35 +0000122 SkRect r = { 10, 10, 23, 20 };
reed@google.comd34658a2011-04-11 13:12:51 +0000123 path->addOval(r);
124 }
125private:
126 typedef PathBench INHERITED;
127};
128
bsalomon@google.com1647a192012-04-11 15:34:46 +0000129class CirclePathBench: public PathBench {
130public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000131 CirclePathBench(Flags flags) : INHERITED(flags) {}
bsalomon@google.com1647a192012-04-11 15:34:46 +0000132
mtklein36352bf2015-03-25 18:17:31 -0700133 void appendName(SkString* name) override {
bsalomon@google.com1647a192012-04-11 15:34:46 +0000134 name->append("circle");
135 }
mtklein36352bf2015-03-25 18:17:31 -0700136 void makePath(SkPath* path) override {
bsalomon@google.com1647a192012-04-11 15:34:46 +0000137 path->addCircle(SkIntToScalar(20), SkIntToScalar(20),
138 SkIntToScalar(10));
139 }
140private:
141 typedef PathBench INHERITED;
142};
143
reed@google.comd34658a2011-04-11 13:12:51 +0000144class SawToothPathBench : public PathBench {
145public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000146 SawToothPathBench(Flags flags) : INHERITED(flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000147
mtklein36352bf2015-03-25 18:17:31 -0700148 void appendName(SkString* name) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000149 name->append("sawtooth");
150 }
mtkleinf0599002015-07-13 06:18:39 -0700151 void makePath(SkPath* path) override {
reed@google.comd34658a2011-04-11 13:12:51 +0000152 SkScalar x = SkIntToScalar(20);
153 SkScalar y = SkIntToScalar(20);
154 const SkScalar x0 = x;
155 const SkScalar dx = SK_Scalar1 * 5;
156 const SkScalar dy = SK_Scalar1 * 10;
157
158 path->moveTo(x, y);
159 for (int i = 0; i < 32; i++) {
160 x += dx;
161 path->lineTo(x, y - dy);
162 x += dx;
163 path->lineTo(x, y + dy);
164 }
165 path->lineTo(x, y + 2 * dy);
166 path->lineTo(x0, y + 2 * dy);
167 path->close();
168 }
mtklein36352bf2015-03-25 18:17:31 -0700169 int complexity() override { return 1; }
reed@google.comd34658a2011-04-11 13:12:51 +0000170private:
171 typedef PathBench INHERITED;
172};
173
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000174class LongCurvedPathBench : public PathBench {
175public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000176 LongCurvedPathBench(Flags flags) : INHERITED(flags) {}
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000177
mtklein36352bf2015-03-25 18:17:31 -0700178 void appendName(SkString* name) override {
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000179 name->append("long_curved");
180 }
mtklein36352bf2015-03-25 18:17:31 -0700181 void makePath(SkPath* path) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000182 SkRandom rand (12);
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000183 int i;
184 for (i = 0; i < 100; i++) {
185 path->quadTo(SkScalarMul(rand.nextUScalar1(), SkIntToScalar(640)),
186 SkScalarMul(rand.nextUScalar1(), SkIntToScalar(480)),
187 SkScalarMul(rand.nextUScalar1(), SkIntToScalar(640)),
188 SkScalarMul(rand.nextUScalar1(), SkIntToScalar(480)));
189 }
190 path->close();
191 }
mtklein36352bf2015-03-25 18:17:31 -0700192 int complexity() override { return 2; }
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000193private:
194 typedef PathBench INHERITED;
195};
196
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000197class LongLinePathBench : public PathBench {
198public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000199 LongLinePathBench(Flags flags) : INHERITED(flags) {}
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000200
mtklein36352bf2015-03-25 18:17:31 -0700201 void appendName(SkString* name) override {
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000202 name->append("long_line");
203 }
mtklein36352bf2015-03-25 18:17:31 -0700204 void makePath(SkPath* path) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000205 SkRandom rand;
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000206 path->moveTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
207 for (size_t i = 1; i < 100; i++) {
208 path->lineTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
209 }
210 }
mtklein36352bf2015-03-25 18:17:31 -0700211 int complexity() override { return 2; }
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000212private:
213 typedef PathBench INHERITED;
214};
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000215
tfarinaf168b862014-06-19 12:32:29 -0700216class RandomPathBench : public Benchmark {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000217public:
mtklein36352bf2015-03-25 18:17:31 -0700218 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000219 return backend == kNonRendering_Backend;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000220 }
221
222protected:
223 void createData(int minVerbs,
224 int maxVerbs,
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000225 bool allowMoves = true,
226 SkRect* bounds = NULL) {
227 SkRect tempBounds;
228 if (NULL == bounds) {
229 tempBounds.setXYWH(0, 0, SK_Scalar1, SK_Scalar1);
230 bounds = &tempBounds;
231 }
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000232 fVerbCnts.reset(kNumVerbCnts);
233 for (int i = 0; i < kNumVerbCnts; ++i) {
234 fVerbCnts[i] = fRandom.nextRangeU(minVerbs, maxVerbs + 1);
235 }
236 fVerbs.reset(kNumVerbs);
237 for (int i = 0; i < kNumVerbs; ++i) {
238 do {
239 fVerbs[i] = static_cast<SkPath::Verb>(fRandom.nextULessThan(SkPath::kDone_Verb));
240 } while (!allowMoves && SkPath::kMove_Verb == fVerbs[i]);
241 }
242 fPoints.reset(kNumPoints);
243 for (int i = 0; i < kNumPoints; ++i) {
244 fPoints[i].set(fRandom.nextRangeScalar(bounds->fLeft, bounds->fRight),
245 fRandom.nextRangeScalar(bounds->fTop, bounds->fBottom));
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000246 }
247 this->restartMakingPaths();
248 }
249
250 void restartMakingPaths() {
251 fCurrPath = 0;
252 fCurrVerb = 0;
253 fCurrPoint = 0;
254 }
255
256 void makePath(SkPath* path) {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000257 int vCount = fVerbCnts[(fCurrPath++) & (kNumVerbCnts - 1)];
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000258 for (int v = 0; v < vCount; ++v) {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000259 int verb = fVerbs[(fCurrVerb++) & (kNumVerbs - 1)];
260 switch (verb) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000261 case SkPath::kMove_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000262 path->moveTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000263 break;
264 case SkPath::kLine_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000265 path->lineTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000266 break;
267 case SkPath::kQuad_Verb:
bsalomon@google.com373ebc62012-09-26 13:08:56 +0000268 path->quadTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
269 fPoints[(fCurrPoint + 1) & (kNumPoints - 1)]);
270 fCurrPoint += 2;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000271 break;
reed@google.com277c3f82013-05-31 15:17:50 +0000272 case SkPath::kConic_Verb:
273 path->conicTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
274 fPoints[(fCurrPoint + 1) & (kNumPoints - 1)],
275 SK_ScalarHalf);
276 fCurrPoint += 2;
277 break;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000278 case SkPath::kCubic_Verb:
bsalomon@google.com373ebc62012-09-26 13:08:56 +0000279 path->cubicTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
280 fPoints[(fCurrPoint + 1) & (kNumPoints - 1)],
281 fPoints[(fCurrPoint + 2) & (kNumPoints - 1)]);
282 fCurrPoint += 3;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000283 break;
284 case SkPath::kClose_Verb:
285 path->close();
286 break;
287 default:
288 SkDEBUGFAIL("Unexpected path verb");
289 break;
290 }
291 }
292 }
293
294 void finishedMakingPaths() {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000295 fVerbCnts.reset(0);
296 fVerbs.reset(0);
297 fPoints.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000298 }
299
300private:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000301 enum {
302 // these should all be pow 2
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000303 kNumVerbCnts = 1 << 5,
304 kNumVerbs = 1 << 5,
305 kNumPoints = 1 << 5,
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000306 };
307 SkAutoTArray<int> fVerbCnts;
308 SkAutoTArray<SkPath::Verb> fVerbs;
309 SkAutoTArray<SkPoint> fPoints;
310 int fCurrPath;
311 int fCurrVerb;
312 int fCurrPoint;
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000313 SkRandom fRandom;
tfarinaf168b862014-06-19 12:32:29 -0700314 typedef Benchmark INHERITED;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000315};
316
317class PathCreateBench : public RandomPathBench {
318public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000319 PathCreateBench() {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000320 }
321
322protected:
mtklein36352bf2015-03-25 18:17:31 -0700323 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000324 return "path_create";
325 }
326
mtklein36352bf2015-03-25 18:17:31 -0700327 void onPreDraw() override {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000328 this->createData(10, 100);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000329 }
330
mtklein36352bf2015-03-25 18:17:31 -0700331 void onDraw(const int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000332 for (int i = 0; i < loops; ++i) {
commit-bot@chromium.org8f881172014-01-06 20:19:14 +0000333 if (i % 1000 == 0) {
334 fPath.reset(); // PathRef memory can grow without bound otherwise.
335 }
336 this->makePath(&fPath);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000337 }
338 this->restartMakingPaths();
339 }
340
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000341private:
commit-bot@chromium.org8f881172014-01-06 20:19:14 +0000342 SkPath fPath;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000343
344 typedef RandomPathBench INHERITED;
345};
346
347class PathCopyBench : public RandomPathBench {
348public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000349 PathCopyBench() {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000350 }
351
352protected:
mtklein36352bf2015-03-25 18:17:31 -0700353 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000354 return "path_copy";
355 }
mtklein36352bf2015-03-25 18:17:31 -0700356 void onPreDraw() override {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000357 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000358 fPaths.reset(kPathCnt);
359 fCopies.reset(kPathCnt);
360 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000361 this->makePath(&fPaths[i]);
362 }
363 this->finishedMakingPaths();
364 }
mtklein36352bf2015-03-25 18:17:31 -0700365 void onDraw(const int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000366 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000367 int idx = i & (kPathCnt - 1);
368 fCopies[idx] = fPaths[idx];
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000369 }
370 }
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000371
372private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000373 enum {
374 // must be a pow 2
375 kPathCnt = 1 << 5,
376 };
377 SkAutoTArray<SkPath> fPaths;
378 SkAutoTArray<SkPath> fCopies;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000379
380 typedef RandomPathBench INHERITED;
381};
382
383class PathTransformBench : public RandomPathBench {
384public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000385 PathTransformBench(bool inPlace) : fInPlace(inPlace) {}
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000386
387protected:
mtklein36352bf2015-03-25 18:17:31 -0700388 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000389 return fInPlace ? "path_transform_in_place" : "path_transform_copy";
390 }
391
mtklein36352bf2015-03-25 18:17:31 -0700392 void onPreDraw() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000393 fMatrix.setScale(5 * SK_Scalar1, 6 * SK_Scalar1);
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000394 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000395 fPaths.reset(kPathCnt);
396 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000397 this->makePath(&fPaths[i]);
398 }
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000399 this->finishedMakingPaths();
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000400 if (!fInPlace) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000401 fTransformed.reset(kPathCnt);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000402 }
403 }
404
mtklein36352bf2015-03-25 18:17:31 -0700405 void onDraw(const int loops, SkCanvas*) override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000406 if (fInPlace) {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000407 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000408 fPaths[i & (kPathCnt - 1)].transform(fMatrix);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000409 }
410 } else {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000411 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000412 int idx = i & (kPathCnt - 1);
413 fPaths[idx].transform(fMatrix, &fTransformed[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000414 }
415 }
416 }
417
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000418private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000419 enum {
420 // must be a pow 2
421 kPathCnt = 1 << 5,
422 };
423 SkAutoTArray<SkPath> fPaths;
424 SkAutoTArray<SkPath> fTransformed;
425
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000426 SkMatrix fMatrix;
427 bool fInPlace;
428 typedef RandomPathBench INHERITED;
429};
430
431class PathEqualityBench : public RandomPathBench {
432public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000433 PathEqualityBench() { }
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000434
435protected:
mtklein36352bf2015-03-25 18:17:31 -0700436 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000437 return "path_equality_50%";
438 }
439
mtklein36352bf2015-03-25 18:17:31 -0700440 void onPreDraw() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000441 fParity = 0;
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000442 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000443 fPaths.reset(kPathCnt);
444 fCopies.reset(kPathCnt);
445 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000446 this->makePath(&fPaths[i]);
447 fCopies[i] = fPaths[i];
448 }
449 this->finishedMakingPaths();
450 }
451
mtklein36352bf2015-03-25 18:17:31 -0700452 void onDraw(const int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000453 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000454 int idx = i & (kPathCnt - 1);
455 fParity ^= (fPaths[idx] == fCopies[idx & ~0x1]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000456 }
457 }
458
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000459private:
460 bool fParity; // attempt to keep compiler from optimizing out the ==
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000461 enum {
462 // must be a pow 2
463 kPathCnt = 1 << 5,
464 };
465 SkAutoTArray<SkPath> fPaths;
466 SkAutoTArray<SkPath> fCopies;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000467 typedef RandomPathBench INHERITED;
468};
469
470class SkBench_AddPathTest : public RandomPathBench {
471public:
472 enum AddType {
473 kAdd_AddType,
474 kAddTrans_AddType,
475 kAddMatrix_AddType,
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000476 kReverseAdd_AddType,
477 kReversePathTo_AddType,
478 };
479
mtklein@google.com410e6e82013-09-13 19:52:27 +0000480 SkBench_AddPathTest(AddType type) : fType(type) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000481 fMatrix.setRotate(60 * SK_Scalar1);
482 }
483
484protected:
mtklein36352bf2015-03-25 18:17:31 -0700485 const char* onGetName() override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000486 switch (fType) {
487 case kAdd_AddType:
488 return "path_add_path";
489 case kAddTrans_AddType:
490 return "path_add_path_trans";
491 case kAddMatrix_AddType:
492 return "path_add_path_matrix";
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000493 case kReverseAdd_AddType:
494 return "path_reverse_add_path";
495 case kReversePathTo_AddType:
496 return "path_reverse_path_to";
497 default:
498 SkDEBUGFAIL("Bad add type");
499 return "";
500 }
501 }
502
mtklein36352bf2015-03-25 18:17:31 -0700503 void onPreDraw() override {
commit-bot@chromium.orga1a097e2013-11-14 16:53:22 +0000504 // reversePathTo assumes a single contour path.
505 bool allowMoves = kReversePathTo_AddType != fType;
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000506 this->createData(10, 100, allowMoves);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000507 fPaths0.reset(kPathCnt);
508 fPaths1.reset(kPathCnt);
509 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000510 this->makePath(&fPaths0[i]);
511 this->makePath(&fPaths1[i]);
512 }
513 this->finishedMakingPaths();
514 }
515
mtklein36352bf2015-03-25 18:17:31 -0700516 void onDraw(const int loops, SkCanvas*) override {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000517 switch (fType) {
518 case kAdd_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000519 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000520 int idx = i & (kPathCnt - 1);
521 SkPath result = fPaths0[idx];
522 result.addPath(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000523 }
524 break;
525 case kAddTrans_AddType:
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 SkPath result = fPaths0[idx];
529 result.addPath(fPaths1[idx], 2 * SK_Scalar1, 5 * SK_Scalar1);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000530 }
531 break;
532 case kAddMatrix_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000533 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000534 int idx = i & (kPathCnt - 1);
535 SkPath result = fPaths0[idx];
536 result.addPath(fPaths1[idx], fMatrix);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000537 }
538 break;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000539 case kReverseAdd_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000540 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000541 int idx = i & (kPathCnt - 1);
542 SkPath result = fPaths0[idx];
543 result.reverseAddPath(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000544 }
545 break;
546 case kReversePathTo_AddType:
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000547 for (int i = 0; i < loops; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000548 int idx = i & (kPathCnt - 1);
549 SkPath result = fPaths0[idx];
550 result.reversePathTo(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000551 }
552 break;
553 }
554 }
555
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000556private:
557 AddType fType; // or reverseAddPath
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000558 enum {
559 // must be a pow 2
560 kPathCnt = 1 << 5,
561 };
562 SkAutoTArray<SkPath> fPaths0;
563 SkAutoTArray<SkPath> fPaths1;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000564 SkMatrix fMatrix;
565 typedef RandomPathBench INHERITED;
566};
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000567
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000568
tfarinaf168b862014-06-19 12:32:29 -0700569class CirclesBench : public Benchmark {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000570protected:
571 SkString fName;
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000572 Flags fFlags;
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000573
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000574public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000575 CirclesBench(Flags flags) : fFlags(flags) {
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000576 fName.printf("circles_%s", fFlags & kStroke_Flag ? "stroke" : "fill");
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000577 }
578
579protected:
mtklein36352bf2015-03-25 18:17:31 -0700580 const char* onGetName() override {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000581 return fName.c_str();
582 }
583
mtklein36352bf2015-03-25 18:17:31 -0700584 void onDraw(const int loops, SkCanvas* canvas) override {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000585 SkPaint paint;
586
587 paint.setColor(SK_ColorBLACK);
588 paint.setAntiAlias(true);
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000589 if (fFlags & kStroke_Flag) {
590 paint.setStyle(SkPaint::kStroke_Style);
591 }
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000592
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000593 SkRandom rand;
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000594
595 SkRect r;
596
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000597 for (int i = 0; i < loops; ++i) {
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000598 SkScalar radius = rand.nextUScalar1() * 3;
599 r.fLeft = rand.nextUScalar1() * 300;
600 r.fTop = rand.nextUScalar1() * 300;
601 r.fRight = r.fLeft + 2 * radius;
602 r.fBottom = r.fTop + 2 * radius;
603
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000604 if (fFlags & kStroke_Flag) {
605 paint.setStrokeWidth(rand.nextUScalar1() * 5.0f);
606 }
607
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000608 SkPath temp;
609
610 // mimic how Chrome does circles
611 temp.arcTo(r, 0, 0, false);
612 temp.addOval(r, SkPath::kCCW_Direction);
613 temp.arcTo(r, 360, 0, true);
614 temp.close();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000615
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000616 canvas->drawPath(temp, paint);
617 }
618 }
619
620private:
tfarinaf168b862014-06-19 12:32:29 -0700621 typedef Benchmark INHERITED;
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000622};
623
jvanverth@google.com46d3d392013-01-22 13:34:01 +0000624
robertphillips@google.com158618e2012-10-23 16:56:56 +0000625// Chrome creates its own round rects with each corner possibly being different.
626// In its "zero radius" incarnation it creates degenerate round rects.
skia.committer@gmail.com1e34ff72012-10-24 02:01:24 +0000627// Note: PathTest::test_arb_round_rect_is_convex and
robertphillips@google.com158618e2012-10-23 16:56:56 +0000628// test_arb_zero_rad_round_rect_is_rect perform almost exactly
robertphillips@google.comb95eaa82012-10-18 15:26:12 +0000629// the same test (but with no drawing)
tfarinaf168b862014-06-19 12:32:29 -0700630class ArbRoundRectBench : public Benchmark {
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000631protected:
632 SkString fName;
633
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000634public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000635 ArbRoundRectBench(bool zeroRad) : fZeroRad(zeroRad) {
robertphillips@google.com158618e2012-10-23 16:56:56 +0000636 if (zeroRad) {
637 fName.printf("zeroradroundrect");
638 } else {
639 fName.printf("arbroundrect");
640 }
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000641 }
642
643protected:
mtklein36352bf2015-03-25 18:17:31 -0700644 const char* onGetName() override {
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000645 return fName.c_str();
646 }
647
skia.committer@gmail.com989a95e2012-10-18 02:01:23 +0000648 static void add_corner_arc(SkPath* path, const SkRect& rect,
649 SkScalar xIn, SkScalar yIn,
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000650 int startAngle)
651 {
652
653 SkScalar rx = SkMinScalar(rect.width(), xIn);
654 SkScalar ry = SkMinScalar(rect.height(), yIn);
655
656 SkRect arcRect;
657 arcRect.set(-rx, -ry, rx, ry);
658 switch (startAngle) {
659 case 0:
660 arcRect.offset(rect.fRight - arcRect.fRight, rect.fBottom - arcRect.fBottom);
661 break;
662 case 90:
663 arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fBottom - arcRect.fBottom);
664 break;
665 case 180:
666 arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fTop - arcRect.fTop);
667 break;
668 case 270:
669 arcRect.offset(rect.fRight - arcRect.fRight, rect.fTop - arcRect.fTop);
670 break;
671 default:
672 break;
673 }
674
675 path->arcTo(arcRect, SkIntToScalar(startAngle), SkIntToScalar(90), false);
676 }
677
skia.committer@gmail.com989a95e2012-10-18 02:01:23 +0000678 static void make_arb_round_rect(SkPath* path, const SkRect& r,
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000679 SkScalar xCorner, SkScalar yCorner) {
680 // we are lazy here and use the same x & y for each corner
681 add_corner_arc(path, r, xCorner, yCorner, 270);
682 add_corner_arc(path, r, xCorner, yCorner, 0);
683 add_corner_arc(path, r, xCorner, yCorner, 90);
684 add_corner_arc(path, r, xCorner, yCorner, 180);
robertphillips@google.com158618e2012-10-23 16:56:56 +0000685 path->close();
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000686
robertphillips@google.comb95eaa82012-10-18 15:26:12 +0000687 SkASSERT(path->isConvex());
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000688 }
689
mtklein36352bf2015-03-25 18:17:31 -0700690 void onDraw(const int loops, SkCanvas* canvas) override {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000691 SkRandom rand;
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000692 SkRect r;
693
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000694 for (int i = 0; i < loops; ++i) {
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000695 SkPaint paint;
696 paint.setColor(0xff000000 | rand.nextU());
697 paint.setAntiAlias(true);
698
robertphillips@google.com158618e2012-10-23 16:56:56 +0000699 SkScalar size = rand.nextUScalar1() * 30;
700 if (size < SK_Scalar1) {
robertphillips@google.comb95eaa82012-10-18 15:26:12 +0000701 continue;
702 }
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000703 r.fLeft = rand.nextUScalar1() * 300;
704 r.fTop = rand.nextUScalar1() * 300;
robertphillips@google.com158618e2012-10-23 16:56:56 +0000705 r.fRight = r.fLeft + 2 * size;
706 r.fBottom = r.fTop + 2 * size;
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000707
708 SkPath temp;
709
robertphillips@google.com158618e2012-10-23 16:56:56 +0000710 if (fZeroRad) {
711 make_arb_round_rect(&temp, r, 0, 0);
712
713 SkASSERT(temp.isRect(NULL));
714 } else {
715 make_arb_round_rect(&temp, r, r.width() / 10, r.height() / 15);
716 }
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000717
718 canvas->drawPath(temp, paint);
719 }
720 }
721
722private:
robertphillips@google.com158618e2012-10-23 16:56:56 +0000723 bool fZeroRad; // should 0 radius rounds rects be tested?
724
tfarinaf168b862014-06-19 12:32:29 -0700725 typedef Benchmark INHERITED;
robertphillips@google.comf6fc3fc2012-10-17 15:23:21 +0000726};
727
tfarinaf168b862014-06-19 12:32:29 -0700728class ConservativelyContainsBench : public Benchmark {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000729public:
730 enum Type {
731 kRect_Type,
732 kRoundRect_Type,
733 kOval_Type,
734 };
735
mtklein@google.com410e6e82013-09-13 19:52:27 +0000736 ConservativelyContainsBench(Type type) {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000737 fParity = false;
738 fName = "conservatively_contains_";
739 switch (type) {
740 case kRect_Type:
741 fName.append("rect");
742 fPath.addRect(kBaseRect);
743 break;
744 case kRoundRect_Type:
745 fName.append("round_rect");
746 fPath.addRoundRect(kBaseRect, kRRRadii[0], kRRRadii[1]);
747 break;
748 case kOval_Type:
749 fName.append("oval");
750 fPath.addOval(kBaseRect);
751 break;
752 }
753 }
754
mtklein36352bf2015-03-25 18:17:31 -0700755 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000756 return backend == kNonRendering_Backend;
757 }
758
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000759private:
mtklein36352bf2015-03-25 18:17:31 -0700760 const char* onGetName() override {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000761 return fName.c_str();
762 }
763
mtklein36352bf2015-03-25 18:17:31 -0700764 void onDraw(const int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000765 for (int i = 0; i < loops; ++i) {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000766 const SkRect& rect = fQueryRects[i % kQueryRectCnt];
767 fParity = fParity != fPath.conservativelyContainsRect(rect);
768 }
769 }
770
mtklein36352bf2015-03-25 18:17:31 -0700771 void onPreDraw() override {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000772 fQueryRects.setCount(kQueryRectCnt);
773
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000774 SkRandom rand;
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000775 for (int i = 0; i < kQueryRectCnt; ++i) {
776 SkSize size;
777 SkPoint xy;
778 size.fWidth = rand.nextRangeScalar(kQueryMin.fWidth, kQueryMax.fWidth);
779 size.fHeight = rand.nextRangeScalar(kQueryMin.fHeight, kQueryMax.fHeight);
780 xy.fX = rand.nextRangeScalar(kBounds.fLeft, kBounds.fRight - size.fWidth);
781 xy.fY = rand.nextRangeScalar(kBounds.fTop, kBounds.fBottom - size.fHeight);
782
783 fQueryRects[i] = SkRect::MakeXYWH(xy.fX, xy.fY, size.fWidth, size.fHeight);
784 }
785 }
786
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000787 enum {
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000788 kQueryRectCnt = 400,
789 };
790 static const SkRect kBounds; // bounds for all random query rects
791 static const SkSize kQueryMin; // minimum query rect size, should be <= kQueryMax
792 static const SkSize kQueryMax; // max query rect size, should < kBounds
793 static const SkRect kBaseRect; // rect that is used to construct the path
794 static const SkScalar kRRRadii[2]; // x and y radii for round rect
795
796 SkString fName;
797 SkPath fPath;
798 bool fParity;
799 SkTDArray<SkRect> fQueryRects;
800
tfarinaf168b862014-06-19 12:32:29 -0700801 typedef Benchmark INHERITED;
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000802};
803
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000804///////////////////////////////////////////////////////////////////////////////
805
806#include "SkGeometry.h"
807
reed55011032015-03-26 09:10:22 -0700808class ConicBench_Chop : public Benchmark {
reedb6402032015-03-20 13:23:43 -0700809protected:
810 SkConic fRQ, fDst[2];
811 SkString fName;
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000812public:
reed55011032015-03-26 09:10:22 -0700813 ConicBench_Chop() : fName("conic-chop") {
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000814 fRQ.fPts[0].set(0, 0);
815 fRQ.fPts[1].set(100, 0);
816 fRQ.fPts[2].set(100, 100);
817 fRQ.fW = SkScalarCos(SK_ScalarPI/4);
reedb6402032015-03-20 13:23:43 -0700818 }
819
mtklein36352bf2015-03-25 18:17:31 -0700820 bool isSuitableFor(Backend backend) override {
reedb6402032015-03-20 13:23:43 -0700821 return backend == kNonRendering_Backend;
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000822 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000823
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000824private:
mtklein36352bf2015-03-25 18:17:31 -0700825 const char* onGetName() override { return fName.c_str(); }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000826
mtklein36352bf2015-03-25 18:17:31 -0700827 void onDraw(const int loops, SkCanvas*) override {
reed55011032015-03-26 09:10:22 -0700828 for (int i = 0; i < loops; ++i) {
829 fRQ.chop(fDst);
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000830 }
831 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000832
tfarinaf168b862014-06-19 12:32:29 -0700833 typedef Benchmark INHERITED;
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000834};
reed55011032015-03-26 09:10:22 -0700835DEF_BENCH( return new ConicBench_Chop; )
reedb6402032015-03-20 13:23:43 -0700836
reed55011032015-03-26 09:10:22 -0700837class ConicBench_EvalPos : public ConicBench_Chop {
838 const bool fUseV2;
reedb6402032015-03-20 13:23:43 -0700839public:
reed55011032015-03-26 09:10:22 -0700840 ConicBench_EvalPos(bool useV2) : fUseV2(useV2) {
reedb6402032015-03-20 13:23:43 -0700841 fName.printf("conic-eval-pos%d", useV2);
842 }
mtklein36352bf2015-03-25 18:17:31 -0700843 void onDraw(const int loops, SkCanvas*) override {
reedb6402032015-03-20 13:23:43 -0700844 if (fUseV2) {
845 for (int i = 0; i < loops; ++i) {
846 for (int j = 0; j < 1000; ++j) {
847 fDst[0].fPts[0] = fRQ.evalAt(0.4f);
848 }
849 }
850 } else {
851 for (int i = 0; i < loops; ++i) {
852 for (int j = 0; j < 1000; ++j) {
853 fRQ.evalAt(0.4f, &fDst[0].fPts[0], NULL);
854 }
855 }
856 }
857 }
858};
859DEF_BENCH( return new ConicBench_EvalPos(false); )
860DEF_BENCH( return new ConicBench_EvalPos(true); )
861
reed55011032015-03-26 09:10:22 -0700862class ConicBench_EvalTan : public ConicBench_Chop {
863 const bool fUseV2;
reedb6402032015-03-20 13:23:43 -0700864public:
reed55011032015-03-26 09:10:22 -0700865 ConicBench_EvalTan(bool useV2) : fUseV2(useV2) {
reedb6402032015-03-20 13:23:43 -0700866 fName.printf("conic-eval-tan%d", useV2);
867 }
mtklein36352bf2015-03-25 18:17:31 -0700868 void onDraw(const int loops, SkCanvas*) override {
reedb6402032015-03-20 13:23:43 -0700869 if (fUseV2) {
870 for (int i = 0; i < loops; ++i) {
871 for (int j = 0; j < 1000; ++j) {
872 fDst[0].fPts[0] = fRQ.evalTangentAt(0.4f);
873 }
874 }
875 } else {
876 for (int i = 0; i < loops; ++i) {
877 for (int j = 0; j < 1000; ++j) {
878 fRQ.evalAt(0.4f, NULL, &fDst[0].fPts[0]);
879 }
880 }
881 }
882 }
883};
884DEF_BENCH( return new ConicBench_EvalTan(false); )
885DEF_BENCH( return new ConicBench_EvalTan(true); )
mike@reedtribe.org8d551012013-04-14 02:40:50 +0000886
887///////////////////////////////////////////////////////////////////////////////
888
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000889static void rand_conic(SkConic* conic, SkRandom& rand) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000890 for (int i = 0; i < 3; ++i) {
891 conic->fPts[i].set(rand.nextUScalar1() * 100, rand.nextUScalar1() * 100);
892 }
893 if (rand.nextUScalar1() > 0.5f) {
894 conic->fW = rand.nextUScalar1();
895 } else {
896 conic->fW = 1 + rand.nextUScalar1() * 4;
897 }
898}
899
tfarinaf168b862014-06-19 12:32:29 -0700900class ConicBench : public Benchmark {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000901public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000902 ConicBench() {
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000903 SkRandom rand;
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000904 for (int i = 0; i < CONICS; ++i) {
905 rand_conic(&fConics[i], rand);
906 }
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000907 }
908
mtklein36352bf2015-03-25 18:17:31 -0700909 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.org644629c2013-11-21 06:21:58 +0000910 return backend == kNonRendering_Backend;
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000911 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000912
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000913protected:
914 enum {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000915 CONICS = 100
916 };
917 SkConic fConics[CONICS];
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000918
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000919private:
tfarinaf168b862014-06-19 12:32:29 -0700920 typedef Benchmark INHERITED;
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000921};
922
923class ConicBench_ComputeError : public ConicBench {
924public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000925 ConicBench_ComputeError() {}
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000926
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000927protected:
mtklein36352bf2015-03-25 18:17:31 -0700928 const char* onGetName() override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000929 return "conic-compute-error";
930 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000931
mtklein36352bf2015-03-25 18:17:31 -0700932 void onDraw(const int loops, SkCanvas*) override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000933 SkVector err;
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000934 for (int i = 0; i < loops; ++i) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000935 for (int j = 0; j < CONICS; ++j) {
936 fConics[j].computeAsQuadError(&err);
937 }
938 }
939 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000940
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000941private:
942 typedef ConicBench INHERITED;
943};
944
945class ConicBench_asQuadTol : public ConicBench {
946public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000947 ConicBench_asQuadTol() {}
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000948
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000949protected:
mtklein36352bf2015-03-25 18:17:31 -0700950 const char* onGetName() override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000951 return "conic-asQuadTol";
952 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000953
mtklein36352bf2015-03-25 18:17:31 -0700954 void onDraw(const int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000955 for (int i = 0; i < loops; ++i) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000956 for (int j = 0; j < CONICS; ++j) {
957 fConics[j].asQuadTol(SK_ScalarHalf);
958 }
959 }
960 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000961
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000962private:
963 typedef ConicBench INHERITED;
964};
965
966class ConicBench_quadPow2 : public ConicBench {
967public:
mtklein@google.com410e6e82013-09-13 19:52:27 +0000968 ConicBench_quadPow2() {}
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000969
970protected:
mtklein36352bf2015-03-25 18:17:31 -0700971 const char* onGetName() override {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000972 return "conic-quadPow2";
973 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000974
mtklein36352bf2015-03-25 18:17:31 -0700975 void onDraw(const int loops, SkCanvas*) override {
commit-bot@chromium.org33614712013-12-03 18:17:16 +0000976 for (int i = 0; i < loops; ++i) {
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000977 for (int j = 0; j < CONICS; ++j) {
978 fConics[j].computeQuadPOW2(SK_ScalarHalf);
979 }
980 }
981 }
skia.committer@gmail.com81521132013-04-30 07:01:03 +0000982
mike@reedtribe.orgaf5c5062013-04-30 02:14:58 +0000983private:
984 typedef ConicBench INHERITED;
985};
986
987///////////////////////////////////////////////////////////////////////////////
988
bsalomon@google.com9bee33a2012-11-13 21:51:38 +0000989const SkRect ConservativelyContainsBench::kBounds = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
990const SkSize ConservativelyContainsBench::kQueryMin = SkSize::Make(SkIntToScalar(1), SkIntToScalar(1));
991const SkSize ConservativelyContainsBench::kQueryMax = SkSize::Make(SkIntToScalar(40), SkIntToScalar(40));
992const SkRect ConservativelyContainsBench::kBaseRect = SkRect::MakeXYWH(SkIntToScalar(25), SkIntToScalar(25), SkIntToScalar(50), SkIntToScalar(50));
993const SkScalar ConservativelyContainsBench::kRRRadii[2] = {SkIntToScalar(5), SkIntToScalar(10)};
994
mtklein@google.com410e6e82013-09-13 19:52:27 +0000995DEF_BENCH( return new TrianglePathBench(FLAGS00); )
996DEF_BENCH( return new TrianglePathBench(FLAGS01); )
997DEF_BENCH( return new TrianglePathBench(FLAGS10); )
998DEF_BENCH( return new TrianglePathBench(FLAGS11); )
reed@google.comd34658a2011-04-11 13:12:51 +0000999
mtklein@google.com410e6e82013-09-13 19:52:27 +00001000DEF_BENCH( return new RectPathBench(FLAGS00); )
1001DEF_BENCH( return new RectPathBench(FLAGS01); )
1002DEF_BENCH( return new RectPathBench(FLAGS10); )
1003DEF_BENCH( return new RectPathBench(FLAGS11); )
reed@google.comd34658a2011-04-11 13:12:51 +00001004
mtklein@google.com410e6e82013-09-13 19:52:27 +00001005DEF_BENCH( return new OvalPathBench(FLAGS00); )
1006DEF_BENCH( return new OvalPathBench(FLAGS01); )
1007DEF_BENCH( return new OvalPathBench(FLAGS10); )
1008DEF_BENCH( return new OvalPathBench(FLAGS11); )
reed@google.comd34658a2011-04-11 13:12:51 +00001009
mtklein@google.com410e6e82013-09-13 19:52:27 +00001010DEF_BENCH( return new CirclePathBench(FLAGS00); )
1011DEF_BENCH( return new CirclePathBench(FLAGS01); )
1012DEF_BENCH( return new CirclePathBench(FLAGS10); )
1013DEF_BENCH( return new CirclePathBench(FLAGS11); )
bsalomon@google.com1647a192012-04-11 15:34:46 +00001014
mtklein@google.com410e6e82013-09-13 19:52:27 +00001015DEF_BENCH( return new SawToothPathBench(FLAGS00); )
1016DEF_BENCH( return new SawToothPathBench(FLAGS01); )
reed@google.comd34658a2011-04-11 13:12:51 +00001017
mtklein@google.com410e6e82013-09-13 19:52:27 +00001018DEF_BENCH( return new LongCurvedPathBench(FLAGS00); )
1019DEF_BENCH( return new LongCurvedPathBench(FLAGS01); )
1020DEF_BENCH( return new LongLinePathBench(FLAGS00); )
1021DEF_BENCH( return new LongLinePathBench(FLAGS01); )
tomhudson@google.com6e8d3352011-06-22 17:16:35 +00001022
mtklein@google.com410e6e82013-09-13 19:52:27 +00001023DEF_BENCH( return new PathCreateBench(); )
1024DEF_BENCH( return new PathCopyBench(); )
1025DEF_BENCH( return new PathTransformBench(true); )
1026DEF_BENCH( return new PathTransformBench(false); )
1027DEF_BENCH( return new PathEqualityBench(); )
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +00001028
mtklein@google.com410e6e82013-09-13 19:52:27 +00001029DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAdd_AddType); )
1030DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAddTrans_AddType); )
1031DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAddMatrix_AddType); )
mtklein@google.com410e6e82013-09-13 19:52:27 +00001032DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kReverseAdd_AddType); )
1033DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kReversePathTo_AddType); )
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +00001034
mtklein@google.com410e6e82013-09-13 19:52:27 +00001035DEF_BENCH( return new CirclesBench(FLAGS00); )
1036DEF_BENCH( return new CirclesBench(FLAGS01); )
1037DEF_BENCH( return new ArbRoundRectBench(false); )
1038DEF_BENCH( return new ArbRoundRectBench(true); )
1039DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kRect_Type); )
1040DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kRoundRect_Type); )
1041DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kOval_Type); )
mike@reedtribe.org8d551012013-04-14 02:40:50 +00001042
reedb6402032015-03-20 13:23:43 -07001043
Mike Klein3f376a52014-07-16 20:23:43 -04001044// These seem to be optimized away, which is troublesome for timing.
1045/*
mtklein@google.com410e6e82013-09-13 19:52:27 +00001046DEF_BENCH( return new ConicBench_Chop5() )
mtklein@google.com410e6e82013-09-13 19:52:27 +00001047DEF_BENCH( return new ConicBench_ComputeError() )
1048DEF_BENCH( return new ConicBench_asQuadTol() )
1049DEF_BENCH( return new ConicBench_quadPow2() )
Mike Klein3f376a52014-07-16 20:23:43 -04001050*/