blob: 2e07f677bea9f84d198b084a96480c25e23d334b [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 */
reed@google.comd34658a2011-04-11 13:12:51 +00008#include "SkBenchmark.h"
9#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 +000018
19enum 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
29class PathBench : public SkBenchmark {
30 SkPaint fPaint;
31 SkString fName;
32 Flags fFlags;
tomhudson@google.comca529d32011-10-28 15:34:49 +000033 enum { N = SkBENCHLOOP(1000) };
reed@google.comd34658a2011-04-11 13:12:51 +000034public:
35 PathBench(void* param, Flags flags) : INHERITED(param), fFlags(flags) {
36 fPaint.setStyle(flags & kStroke_Flag ? SkPaint::kStroke_Style :
37 SkPaint::kFill_Style);
38 fPaint.setStrokeWidth(SkIntToScalar(5));
39 fPaint.setStrokeJoin(SkPaint::kBevel_Join);
40 }
41
42 virtual void appendName(SkString*) = 0;
43 virtual void makePath(SkPath*) = 0;
tomhudson@google.com6e8d3352011-06-22 17:16:35 +000044 virtual int complexity() { return 0; }
reed@google.comd34658a2011-04-11 13:12:51 +000045
46protected:
bsalomon@google.com1647a192012-04-11 15:34:46 +000047 virtual const char* onGetName() SK_OVERRIDE {
reed@google.comd34658a2011-04-11 13:12:51 +000048 fName.printf("path_%s_%s_",
49 fFlags & kStroke_Flag ? "stroke" : "fill",
50 fFlags & kBig_Flag ? "big" : "small");
51 this->appendName(&fName);
52 return fName.c_str();
53 }
54
bsalomon@google.com1647a192012-04-11 15:34:46 +000055 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
reed@google.comd34658a2011-04-11 13:12:51 +000056 SkPaint paint(fPaint);
57 this->setupPaint(&paint);
58
59 SkPath path;
60 this->makePath(&path);
61 if (fFlags & kBig_Flag) {
62 SkMatrix m;
63 m.setScale(SkIntToScalar(10), SkIntToScalar(10));
64 path.transform(m);
65 }
66
67 int count = N;
68 if (fFlags & kBig_Flag) {
69 count >>= 2;
70 }
tomhudson@google.com6e8d3352011-06-22 17:16:35 +000071 count >>= (3 * complexity());
reed@google.comd34658a2011-04-11 13:12:51 +000072
73 for (int i = 0; i < count; i++) {
74 canvas->drawPath(path, paint);
75 }
76 }
77
78private:
79 typedef SkBenchmark INHERITED;
80};
81
82class TrianglePathBench : public PathBench {
83public:
84 TrianglePathBench(void* param, Flags flags) : INHERITED(param, flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +000085
bsalomon@google.com1647a192012-04-11 15:34:46 +000086 virtual void appendName(SkString* name) SK_OVERRIDE {
reed@google.comd34658a2011-04-11 13:12:51 +000087 name->append("triangle");
88 }
bsalomon@google.com1647a192012-04-11 15:34:46 +000089 virtual void makePath(SkPath* path) SK_OVERRIDE {
reed@google.comd34658a2011-04-11 13:12:51 +000090 static const int gCoord[] = {
91 10, 10, 15, 5, 20, 20
92 };
93 path->moveTo(SkIntToScalar(gCoord[0]), SkIntToScalar(gCoord[1]));
94 path->lineTo(SkIntToScalar(gCoord[2]), SkIntToScalar(gCoord[3]));
95 path->lineTo(SkIntToScalar(gCoord[4]), SkIntToScalar(gCoord[5]));
96 path->close();
97 }
98private:
99 typedef PathBench INHERITED;
100};
101
102class RectPathBench : public PathBench {
103public:
104 RectPathBench(void* param, Flags flags) : INHERITED(param, flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000105
bsalomon@google.com1647a192012-04-11 15:34:46 +0000106 virtual void appendName(SkString* name) SK_OVERRIDE {
reed@google.comd34658a2011-04-11 13:12:51 +0000107 name->append("rect");
108 }
bsalomon@google.com1647a192012-04-11 15:34:46 +0000109 virtual void makePath(SkPath* path) SK_OVERRIDE {
reed@google.comd34658a2011-04-11 13:12:51 +0000110 SkRect r = { 10, 10, 20, 20 };
111 path->addRect(r);
112 }
113private:
114 typedef PathBench INHERITED;
115};
116
117class OvalPathBench : public PathBench {
118public:
119 OvalPathBench(void* param, Flags flags) : INHERITED(param, flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000120
bsalomon@google.com1647a192012-04-11 15:34:46 +0000121 virtual void appendName(SkString* name) SK_OVERRIDE {
reed@google.comd34658a2011-04-11 13:12:51 +0000122 name->append("oval");
123 }
bsalomon@google.com1647a192012-04-11 15:34:46 +0000124 virtual void makePath(SkPath* path) SK_OVERRIDE {
reed@google.comd34658a2011-04-11 13:12:51 +0000125 SkRect r = { 10, 10, 20, 20 };
126 path->addOval(r);
127 }
128private:
129 typedef PathBench INHERITED;
130};
131
bsalomon@google.com1647a192012-04-11 15:34:46 +0000132class CirclePathBench: public PathBench {
133public:
134 CirclePathBench(void* param, Flags flags) : INHERITED(param, flags) {}
135
136 virtual void appendName(SkString* name) SK_OVERRIDE {
137 name->append("circle");
138 }
139 virtual void makePath(SkPath* path) SK_OVERRIDE {
140 path->addCircle(SkIntToScalar(20), SkIntToScalar(20),
141 SkIntToScalar(10));
142 }
143private:
144 typedef PathBench INHERITED;
145};
146
reed@google.comd34658a2011-04-11 13:12:51 +0000147class SawToothPathBench : public PathBench {
148public:
149 SawToothPathBench(void* param, Flags flags) : INHERITED(param, flags) {}
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000150
bsalomon@google.com1647a192012-04-11 15:34:46 +0000151 virtual void appendName(SkString* name) SK_OVERRIDE {
reed@google.comd34658a2011-04-11 13:12:51 +0000152 name->append("sawtooth");
153 }
154 virtual void makePath(SkPath* path) {
155 SkScalar x = SkIntToScalar(20);
156 SkScalar y = SkIntToScalar(20);
157 const SkScalar x0 = x;
158 const SkScalar dx = SK_Scalar1 * 5;
159 const SkScalar dy = SK_Scalar1 * 10;
160
161 path->moveTo(x, y);
162 for (int i = 0; i < 32; i++) {
163 x += dx;
164 path->lineTo(x, y - dy);
165 x += dx;
166 path->lineTo(x, y + dy);
167 }
168 path->lineTo(x, y + 2 * dy);
169 path->lineTo(x0, y + 2 * dy);
170 path->close();
171 }
bsalomon@google.com1647a192012-04-11 15:34:46 +0000172 virtual int complexity() SK_OVERRIDE { return 1; }
reed@google.comd34658a2011-04-11 13:12:51 +0000173private:
174 typedef PathBench INHERITED;
175};
176
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000177class LongCurvedPathBench : public PathBench {
178public:
179 LongCurvedPathBench(void * param, Flags flags)
180 : INHERITED(param, flags) {
181 }
182
bsalomon@google.com1647a192012-04-11 15:34:46 +0000183 virtual void appendName(SkString* name) SK_OVERRIDE {
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000184 name->append("long_curved");
185 }
bsalomon@google.com1647a192012-04-11 15:34:46 +0000186 virtual void makePath(SkPath* path) SK_OVERRIDE {
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000187 SkRandom rand (12);
188 int i;
189 for (i = 0; i < 100; i++) {
190 path->quadTo(SkScalarMul(rand.nextUScalar1(), SkIntToScalar(640)),
191 SkScalarMul(rand.nextUScalar1(), SkIntToScalar(480)),
192 SkScalarMul(rand.nextUScalar1(), SkIntToScalar(640)),
193 SkScalarMul(rand.nextUScalar1(), SkIntToScalar(480)));
194 }
195 path->close();
196 }
bsalomon@google.com1647a192012-04-11 15:34:46 +0000197 virtual int complexity() SK_OVERRIDE { return 2; }
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000198private:
199 typedef PathBench INHERITED;
200};
201
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000202class LongLinePathBench : public PathBench {
203public:
204 LongLinePathBench(void * param, Flags flags)
205 : INHERITED(param, flags) {
206 }
207
bsalomon@google.com1647a192012-04-11 15:34:46 +0000208 virtual void appendName(SkString* name) SK_OVERRIDE {
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000209 name->append("long_line");
210 }
bsalomon@google.com1647a192012-04-11 15:34:46 +0000211 virtual void makePath(SkPath* path) SK_OVERRIDE {
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000212 SkRandom rand;
213 path->moveTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
214 for (size_t i = 1; i < 100; i++) {
215 path->lineTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
216 }
217 }
bsalomon@google.com1647a192012-04-11 15:34:46 +0000218 virtual int complexity() SK_OVERRIDE { return 2; }
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000219private:
220 typedef PathBench INHERITED;
221};
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000222
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000223class RandomPathBench : public SkBenchmark {
224public:
225 RandomPathBench(void* param) : INHERITED(param) {
226 }
227
228protected:
229 void createData(int minVerbs,
230 int maxVerbs,
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000231 bool allowMoves = true,
232 SkRect* bounds = NULL) {
233 SkRect tempBounds;
234 if (NULL == bounds) {
235 tempBounds.setXYWH(0, 0, SK_Scalar1, SK_Scalar1);
236 bounds = &tempBounds;
237 }
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000238 fVerbCnts.reset(kNumVerbCnts);
239 for (int i = 0; i < kNumVerbCnts; ++i) {
240 fVerbCnts[i] = fRandom.nextRangeU(minVerbs, maxVerbs + 1);
241 }
242 fVerbs.reset(kNumVerbs);
243 for (int i = 0; i < kNumVerbs; ++i) {
244 do {
245 fVerbs[i] = static_cast<SkPath::Verb>(fRandom.nextULessThan(SkPath::kDone_Verb));
246 } while (!allowMoves && SkPath::kMove_Verb == fVerbs[i]);
247 }
248 fPoints.reset(kNumPoints);
249 for (int i = 0; i < kNumPoints; ++i) {
250 fPoints[i].set(fRandom.nextRangeScalar(bounds->fLeft, bounds->fRight),
251 fRandom.nextRangeScalar(bounds->fTop, bounds->fBottom));
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000252 }
253 this->restartMakingPaths();
254 }
255
256 void restartMakingPaths() {
257 fCurrPath = 0;
258 fCurrVerb = 0;
259 fCurrPoint = 0;
260 }
261
262 void makePath(SkPath* path) {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000263 int vCount = fVerbCnts[(fCurrPath++) & (kNumVerbCnts - 1)];
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000264 for (int v = 0; v < vCount; ++v) {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000265 int verb = fVerbs[(fCurrVerb++) & (kNumVerbs - 1)];
266 switch (verb) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000267 case SkPath::kMove_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000268 path->moveTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000269 break;
270 case SkPath::kLine_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000271 path->lineTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000272 break;
273 case SkPath::kQuad_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000274 path->quadTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)],
275 fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000276 break;
277 case SkPath::kCubic_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000278 path->cubicTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)],
279 fPoints[(fCurrPoint++) & (kNumPoints - 1)],
280 fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000281 break;
282 case SkPath::kClose_Verb:
283 path->close();
284 break;
285 default:
286 SkDEBUGFAIL("Unexpected path verb");
287 break;
288 }
289 }
290 }
291
292 void finishedMakingPaths() {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000293 fVerbCnts.reset(0);
294 fVerbs.reset(0);
295 fPoints.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000296 }
297
298private:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000299 enum {
300 // these should all be pow 2
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000301 kNumVerbCnts = 1 << 5,
302 kNumVerbs = 1 << 5,
303 kNumPoints = 1 << 5,
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000304 };
305 SkAutoTArray<int> fVerbCnts;
306 SkAutoTArray<SkPath::Verb> fVerbs;
307 SkAutoTArray<SkPoint> fPoints;
308 int fCurrPath;
309 int fCurrVerb;
310 int fCurrPoint;
311 SkRandom fRandom;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000312 typedef SkBenchmark INHERITED;
313};
314
315class PathCreateBench : public RandomPathBench {
316public:
317 PathCreateBench(void* param) : INHERITED(param) {
318 }
319
320protected:
321 enum { N = SkBENCHLOOP(5000) };
322
323 virtual const char* onGetName() SK_OVERRIDE {
324 return "path_create";
325 }
326
327 virtual void onPreDraw() SK_OVERRIDE {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000328 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000329 fPaths.reset(kPathCnt);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000330 }
331
332 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
333 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000334 this->makePath(&fPaths[i & (kPathCnt - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000335 }
336 this->restartMakingPaths();
337 }
338
339 virtual void onPostDraw() SK_OVERRIDE {
340 this->finishedMakingPaths();
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000341 fPaths.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000342 }
343
344private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000345 enum {
346 // must be a pow 2
347 kPathCnt = 1 << 5,
348 };
349 SkAutoTArray<SkPath> fPaths;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000350
351 typedef RandomPathBench INHERITED;
352};
353
354class PathCopyBench : public RandomPathBench {
355public:
356 PathCopyBench(void* param) : INHERITED(param) {
357 }
358
359protected:
bsalomon@google.com62e41902012-08-13 16:59:21 +0000360 enum { N = SkBENCHLOOP(30000) };
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000361
362 virtual const char* onGetName() SK_OVERRIDE {
363 return "path_copy";
364 }
365 virtual void onPreDraw() SK_OVERRIDE {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000366 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000367 fPaths.reset(kPathCnt);
368 fCopies.reset(kPathCnt);
369 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000370 this->makePath(&fPaths[i]);
371 }
372 this->finishedMakingPaths();
373 }
374 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
375 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000376 int idx = i & (kPathCnt - 1);
377 fCopies[idx] = fPaths[idx];
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000378 }
379 }
380 virtual void onPostDraw() SK_OVERRIDE {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000381 fPaths.reset(0);
382 fCopies.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000383 }
384
385private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000386 enum {
387 // must be a pow 2
388 kPathCnt = 1 << 5,
389 };
390 SkAutoTArray<SkPath> fPaths;
391 SkAutoTArray<SkPath> fCopies;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000392
393 typedef RandomPathBench INHERITED;
394};
395
396class PathTransformBench : public RandomPathBench {
397public:
398 PathTransformBench(bool inPlace, void* param)
399 : INHERITED(param)
400 , fInPlace(inPlace) {
401 }
402
403protected:
404 enum { N = SkBENCHLOOP(30000) };
405
406 virtual const char* onGetName() SK_OVERRIDE {
407 return fInPlace ? "path_transform_in_place" : "path_transform_copy";
408 }
409
410 virtual void onPreDraw() SK_OVERRIDE {
411 fMatrix.setScale(5 * SK_Scalar1, 6 * SK_Scalar1);
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000412 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000413 fPaths.reset(kPathCnt);
414 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000415 this->makePath(&fPaths[i]);
416 }
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000417 this->finishedMakingPaths();
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000418 if (!fInPlace) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000419 fTransformed.reset(kPathCnt);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000420 }
421 }
422
423 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
424 if (fInPlace) {
425 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000426 fPaths[i & (kPathCnt - 1)].transform(fMatrix);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000427 }
428 } else {
429 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000430 int idx = i & (kPathCnt - 1);
431 fPaths[idx].transform(fMatrix, &fTransformed[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000432 }
433 }
434 }
435
436 virtual void onPostDraw() SK_OVERRIDE {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000437 fPaths.reset(0);
438 fTransformed.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000439 }
440
441private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000442 enum {
443 // must be a pow 2
444 kPathCnt = 1 << 5,
445 };
446 SkAutoTArray<SkPath> fPaths;
447 SkAutoTArray<SkPath> fTransformed;
448
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000449 SkMatrix fMatrix;
450 bool fInPlace;
451 typedef RandomPathBench INHERITED;
452};
453
454class PathEqualityBench : public RandomPathBench {
455public:
456 PathEqualityBench(void* param)
457 : INHERITED(param) {
458 }
459
460protected:
461 enum { N = SkBENCHLOOP(40000) };
462
463 virtual const char* onGetName() SK_OVERRIDE {
464 return "path_equality_50%";
465 }
466
467 virtual void onPreDraw() SK_OVERRIDE {
468 fParity = 0;
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000469 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000470 fPaths.reset(kPathCnt);
471 fCopies.reset(kPathCnt);
472 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000473 this->makePath(&fPaths[i]);
474 fCopies[i] = fPaths[i];
475 }
476 this->finishedMakingPaths();
477 }
478
479 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
480 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000481 int idx = i & (kPathCnt - 1);
482 fParity ^= (fPaths[idx] == fCopies[idx & ~0x1]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000483 }
484 }
485
486 virtual void onPostDraw() SK_OVERRIDE {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000487 fPaths.reset(0);
488 fCopies.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000489 }
490
491private:
492 bool fParity; // attempt to keep compiler from optimizing out the ==
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000493 enum {
494 // must be a pow 2
495 kPathCnt = 1 << 5,
496 };
497 SkAutoTArray<SkPath> fPaths;
498 SkAutoTArray<SkPath> fCopies;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000499 typedef RandomPathBench INHERITED;
500};
501
502class SkBench_AddPathTest : public RandomPathBench {
503public:
504 enum AddType {
505 kAdd_AddType,
506 kAddTrans_AddType,
507 kAddMatrix_AddType,
508 kPathTo_AddType,
509 kReverseAdd_AddType,
510 kReversePathTo_AddType,
511 };
512
513 SkBench_AddPathTest(AddType type, void* param)
514 : INHERITED(param)
515 , fType(type) {
516 fMatrix.setRotate(60 * SK_Scalar1);
517 }
518
519protected:
520 enum { N = SkBENCHLOOP(15000) };
521
522 virtual const char* onGetName() SK_OVERRIDE {
523 switch (fType) {
524 case kAdd_AddType:
525 return "path_add_path";
526 case kAddTrans_AddType:
527 return "path_add_path_trans";
528 case kAddMatrix_AddType:
529 return "path_add_path_matrix";
530 case kPathTo_AddType:
531 return "path_path_to";
532 case kReverseAdd_AddType:
533 return "path_reverse_add_path";
534 case kReversePathTo_AddType:
535 return "path_reverse_path_to";
536 default:
537 SkDEBUGFAIL("Bad add type");
538 return "";
539 }
540 }
541
542 virtual void onPreDraw() SK_OVERRIDE {
543 // pathTo and reversePathTo assume a single contour path.
544 bool allowMoves = kPathTo_AddType != fType &&
545 kReversePathTo_AddType != fType;
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000546 this->createData(10, 100, allowMoves);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000547 fPaths0.reset(kPathCnt);
548 fPaths1.reset(kPathCnt);
549 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000550 this->makePath(&fPaths0[i]);
551 this->makePath(&fPaths1[i]);
552 }
553 this->finishedMakingPaths();
554 }
555
556 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
557 switch (fType) {
558 case kAdd_AddType:
559 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000560 int idx = i & (kPathCnt - 1);
561 SkPath result = fPaths0[idx];
562 result.addPath(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000563 }
564 break;
565 case kAddTrans_AddType:
566 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000567 int idx = i & (kPathCnt - 1);
568 SkPath result = fPaths0[idx];
569 result.addPath(fPaths1[idx], 2 * SK_Scalar1, 5 * SK_Scalar1);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000570 }
571 break;
572 case kAddMatrix_AddType:
573 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000574 int idx = i & (kPathCnt - 1);
575 SkPath result = fPaths0[idx];
576 result.addPath(fPaths1[idx], fMatrix);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000577 }
578 break;
579 case kPathTo_AddType:
580 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000581 int idx = i & (kPathCnt - 1);
582 SkPath result = fPaths0[idx];
583 result.pathTo(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000584 }
585 break;
586 case kReverseAdd_AddType:
587 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000588 int idx = i & (kPathCnt - 1);
589 SkPath result = fPaths0[idx];
590 result.reverseAddPath(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000591 }
592 break;
593 case kReversePathTo_AddType:
594 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000595 int idx = i & (kPathCnt - 1);
596 SkPath result = fPaths0[idx];
597 result.reversePathTo(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000598 }
599 break;
600 }
601 }
602
603 virtual void onPostDraw() SK_OVERRIDE {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000604 fPaths0.reset(0);
605 fPaths1.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000606 }
607
608private:
609 AddType fType; // or reverseAddPath
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000610 enum {
611 // must be a pow 2
612 kPathCnt = 1 << 5,
613 };
614 SkAutoTArray<SkPath> fPaths0;
615 SkAutoTArray<SkPath> fPaths1;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000616 SkMatrix fMatrix;
617 typedef RandomPathBench INHERITED;
618};
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000619
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000620
621class CirclesBench : public SkBenchmark {
622protected:
623 SkString fName;
624
625 enum {
626 N = SkBENCHLOOP(100)
627 };
628public:
629 CirclesBench(void* param) : INHERITED(param) {
630 fName.printf("circles");
631 }
632
633protected:
634 virtual const char* onGetName() SK_OVERRIDE {
635 return fName.c_str();
636 }
637
638 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
639 SkPaint paint;
640
641 paint.setColor(SK_ColorBLACK);
642 paint.setAntiAlias(true);
643
644 SkRandom rand;
645
646 SkRect r;
647
648 for (int i = 0; i < 5000; ++i) {
649 SkScalar radius = rand.nextUScalar1() * 3;
650 r.fLeft = rand.nextUScalar1() * 300;
651 r.fTop = rand.nextUScalar1() * 300;
652 r.fRight = r.fLeft + 2 * radius;
653 r.fBottom = r.fTop + 2 * radius;
654
655 SkPath temp;
656
657 // mimic how Chrome does circles
658 temp.arcTo(r, 0, 0, false);
659 temp.addOval(r, SkPath::kCCW_Direction);
660 temp.arcTo(r, 360, 0, true);
661 temp.close();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000662
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000663 canvas->drawPath(temp, paint);
664 }
665 }
666
667private:
668 typedef SkBenchmark INHERITED;
669};
670
reed@google.comd34658a2011-04-11 13:12:51 +0000671static SkBenchmark* FactT00(void* p) { return new TrianglePathBench(p, FLAGS00); }
672static SkBenchmark* FactT01(void* p) { return new TrianglePathBench(p, FLAGS01); }
673static SkBenchmark* FactT10(void* p) { return new TrianglePathBench(p, FLAGS10); }
674static SkBenchmark* FactT11(void* p) { return new TrianglePathBench(p, FLAGS11); }
675
676static SkBenchmark* FactR00(void* p) { return new RectPathBench(p, FLAGS00); }
677static SkBenchmark* FactR01(void* p) { return new RectPathBench(p, FLAGS01); }
678static SkBenchmark* FactR10(void* p) { return new RectPathBench(p, FLAGS10); }
679static SkBenchmark* FactR11(void* p) { return new RectPathBench(p, FLAGS11); }
680
681static SkBenchmark* FactO00(void* p) { return new OvalPathBench(p, FLAGS00); }
682static SkBenchmark* FactO01(void* p) { return new OvalPathBench(p, FLAGS01); }
683static SkBenchmark* FactO10(void* p) { return new OvalPathBench(p, FLAGS10); }
684static SkBenchmark* FactO11(void* p) { return new OvalPathBench(p, FLAGS11); }
685
bsalomon@google.com1647a192012-04-11 15:34:46 +0000686static SkBenchmark* FactC00(void* p) { return new CirclePathBench(p, FLAGS00); }
687static SkBenchmark* FactC01(void* p) { return new CirclePathBench(p, FLAGS01); }
688static SkBenchmark* FactC10(void* p) { return new CirclePathBench(p, FLAGS10); }
689static SkBenchmark* FactC11(void* p) { return new CirclePathBench(p, FLAGS11); }
690
reed@google.comd34658a2011-04-11 13:12:51 +0000691static SkBenchmark* FactS00(void* p) { return new SawToothPathBench(p, FLAGS00); }
692static SkBenchmark* FactS01(void* p) { return new SawToothPathBench(p, FLAGS01); }
693
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000694static SkBenchmark* FactLC00(void* p) {
695 return new LongCurvedPathBench(p, FLAGS00);
696}
697static SkBenchmark* FactLC01(void* p) {
698 return new LongCurvedPathBench(p, FLAGS01);
699}
700
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000701static SkBenchmark* FactLL00(void* p) {
702 return new LongLinePathBench(p, FLAGS00);
703}
704
705static SkBenchmark* FactLL01(void* p) {
706 return new LongLinePathBench(p, FLAGS01);
707}
708
reed@google.comd34658a2011-04-11 13:12:51 +0000709static BenchRegistry gRegT00(FactT00);
710static BenchRegistry gRegT01(FactT01);
711static BenchRegistry gRegT10(FactT10);
712static BenchRegistry gRegT11(FactT11);
713
714static BenchRegistry gRegR00(FactR00);
715static BenchRegistry gRegR01(FactR01);
716static BenchRegistry gRegR10(FactR10);
717static BenchRegistry gRegR11(FactR11);
718
719static BenchRegistry gRegO00(FactO00);
720static BenchRegistry gRegO01(FactO01);
721static BenchRegistry gRegO10(FactO10);
722static BenchRegistry gRegO11(FactO11);
723
bsalomon@google.com1647a192012-04-11 15:34:46 +0000724static BenchRegistry gRegC00(FactC00);
725static BenchRegistry gRegC01(FactC01);
726static BenchRegistry gRegC10(FactC10);
727static BenchRegistry gRegC11(FactC11);
728
reed@google.comd34658a2011-04-11 13:12:51 +0000729static BenchRegistry gRegS00(FactS00);
730static BenchRegistry gRegS01(FactS01);
731
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000732static BenchRegistry gRegLC00(FactLC00);
733static BenchRegistry gRegLC01(FactLC01);
734
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000735static BenchRegistry gRegLL00(FactLL00);
736static BenchRegistry gRegLL01(FactLL01);
737
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000738static SkBenchmark* FactCreate(void* p) { return new PathCreateBench(p); }
739static BenchRegistry gRegCreate(FactCreate);
740
741static SkBenchmark* FactCopy(void* p) { return new PathCopyBench(p); }
742static BenchRegistry gRegCopy(FactCopy);
743
744static SkBenchmark* FactPathTransformInPlace(void* p) { return new PathTransformBench(true, p); }
745static BenchRegistry gRegPathTransformInPlace(FactPathTransformInPlace);
746
747static SkBenchmark* FactPathTransformCopy(void* p) { return new PathTransformBench(false, p); }
748static BenchRegistry gRegPathTransformCopy(FactPathTransformCopy);
749
750static SkBenchmark* FactEquality(void* p) { return new PathEqualityBench(p); }
751static BenchRegistry gRegEquality(FactEquality);
752
753static SkBenchmark* FactAdd(void* p) { return new SkBench_AddPathTest(SkBench_AddPathTest::kAdd_AddType, p); }
754static SkBenchmark* FactAddTrans(void* p) { return new SkBench_AddPathTest(SkBench_AddPathTest::kAddTrans_AddType, p); }
755static SkBenchmark* FactAddMatrix(void* p) { return new SkBench_AddPathTest(SkBench_AddPathTest::kAddMatrix_AddType, p); }
756static SkBenchmark* FactPathTo(void* p) { return new SkBench_AddPathTest(SkBench_AddPathTest::kPathTo_AddType, p); }
757static SkBenchmark* FactReverseAdd(void* p) { return new SkBench_AddPathTest(SkBench_AddPathTest::kReverseAdd_AddType, p); }
758static SkBenchmark* FactReverseTo(void* p) { return new SkBench_AddPathTest(SkBench_AddPathTest::kReversePathTo_AddType, p); }
759
760static BenchRegistry gRegAdd(FactAdd);
761static BenchRegistry gRegAddTrans(FactAddTrans);
762static BenchRegistry gRegAddMatrix(FactAddMatrix);
763static BenchRegistry gRegPathTo(FactPathTo);
764static BenchRegistry gRegReverseAdd(FactReverseAdd);
765static BenchRegistry gRegReverseTo(FactReverseTo);
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000766
767static SkBenchmark* CirclesTest(void* p) { return new CirclesBench(p); }
768static BenchRegistry gRegCirclesTest(CirclesTest);
769