blob: dd5041d94b0d102cde24d5e2f0cbb78d43a25714 [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) {
robertphillips@google.com83187a22012-09-13 16:39:08 +0000226 fIsRendering = false;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000227 }
228
229protected:
230 void createData(int minVerbs,
231 int maxVerbs,
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000232 bool allowMoves = true,
233 SkRect* bounds = NULL) {
234 SkRect tempBounds;
235 if (NULL == bounds) {
236 tempBounds.setXYWH(0, 0, SK_Scalar1, SK_Scalar1);
237 bounds = &tempBounds;
238 }
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000239 fVerbCnts.reset(kNumVerbCnts);
240 for (int i = 0; i < kNumVerbCnts; ++i) {
241 fVerbCnts[i] = fRandom.nextRangeU(minVerbs, maxVerbs + 1);
242 }
243 fVerbs.reset(kNumVerbs);
244 for (int i = 0; i < kNumVerbs; ++i) {
245 do {
246 fVerbs[i] = static_cast<SkPath::Verb>(fRandom.nextULessThan(SkPath::kDone_Verb));
247 } while (!allowMoves && SkPath::kMove_Verb == fVerbs[i]);
248 }
249 fPoints.reset(kNumPoints);
250 for (int i = 0; i < kNumPoints; ++i) {
251 fPoints[i].set(fRandom.nextRangeScalar(bounds->fLeft, bounds->fRight),
252 fRandom.nextRangeScalar(bounds->fTop, bounds->fBottom));
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000253 }
254 this->restartMakingPaths();
255 }
256
257 void restartMakingPaths() {
258 fCurrPath = 0;
259 fCurrVerb = 0;
260 fCurrPoint = 0;
261 }
262
263 void makePath(SkPath* path) {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000264 int vCount = fVerbCnts[(fCurrPath++) & (kNumVerbCnts - 1)];
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000265 for (int v = 0; v < vCount; ++v) {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000266 int verb = fVerbs[(fCurrVerb++) & (kNumVerbs - 1)];
267 switch (verb) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000268 case SkPath::kMove_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000269 path->moveTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000270 break;
271 case SkPath::kLine_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000272 path->lineTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000273 break;
274 case SkPath::kQuad_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000275 path->quadTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)],
276 fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000277 break;
278 case SkPath::kCubic_Verb:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000279 path->cubicTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)],
280 fPoints[(fCurrPoint++) & (kNumPoints - 1)],
281 fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000282 break;
283 case SkPath::kClose_Verb:
284 path->close();
285 break;
286 default:
287 SkDEBUGFAIL("Unexpected path verb");
288 break;
289 }
290 }
291 }
292
293 void finishedMakingPaths() {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000294 fVerbCnts.reset(0);
295 fVerbs.reset(0);
296 fPoints.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000297 }
298
299private:
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000300 enum {
301 // these should all be pow 2
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000302 kNumVerbCnts = 1 << 5,
303 kNumVerbs = 1 << 5,
304 kNumPoints = 1 << 5,
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000305 };
306 SkAutoTArray<int> fVerbCnts;
307 SkAutoTArray<SkPath::Verb> fVerbs;
308 SkAutoTArray<SkPoint> fPoints;
309 int fCurrPath;
310 int fCurrVerb;
311 int fCurrPoint;
312 SkRandom fRandom;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000313 typedef SkBenchmark INHERITED;
314};
315
316class PathCreateBench : public RandomPathBench {
317public:
318 PathCreateBench(void* param) : INHERITED(param) {
319 }
320
321protected:
322 enum { N = SkBENCHLOOP(5000) };
323
324 virtual const char* onGetName() SK_OVERRIDE {
325 return "path_create";
326 }
327
328 virtual void onPreDraw() SK_OVERRIDE {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000329 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000330 fPaths.reset(kPathCnt);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000331 }
332
333 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
334 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000335 this->makePath(&fPaths[i & (kPathCnt - 1)]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000336 }
337 this->restartMakingPaths();
338 }
339
340 virtual void onPostDraw() SK_OVERRIDE {
341 this->finishedMakingPaths();
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000342 fPaths.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000343 }
344
345private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000346 enum {
347 // must be a pow 2
348 kPathCnt = 1 << 5,
349 };
350 SkAutoTArray<SkPath> fPaths;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000351
352 typedef RandomPathBench INHERITED;
353};
354
355class PathCopyBench : public RandomPathBench {
356public:
357 PathCopyBench(void* param) : INHERITED(param) {
358 }
359
360protected:
bsalomon@google.com62e41902012-08-13 16:59:21 +0000361 enum { N = SkBENCHLOOP(30000) };
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000362
363 virtual const char* onGetName() SK_OVERRIDE {
364 return "path_copy";
365 }
366 virtual void onPreDraw() SK_OVERRIDE {
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000367 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000368 fPaths.reset(kPathCnt);
369 fCopies.reset(kPathCnt);
370 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000371 this->makePath(&fPaths[i]);
372 }
373 this->finishedMakingPaths();
374 }
375 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
376 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000377 int idx = i & (kPathCnt - 1);
378 fCopies[idx] = fPaths[idx];
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000379 }
380 }
381 virtual void onPostDraw() SK_OVERRIDE {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000382 fPaths.reset(0);
383 fCopies.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000384 }
385
386private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000387 enum {
388 // must be a pow 2
389 kPathCnt = 1 << 5,
390 };
391 SkAutoTArray<SkPath> fPaths;
392 SkAutoTArray<SkPath> fCopies;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000393
394 typedef RandomPathBench INHERITED;
395};
396
397class PathTransformBench : public RandomPathBench {
398public:
399 PathTransformBench(bool inPlace, void* param)
400 : INHERITED(param)
401 , fInPlace(inPlace) {
402 }
403
404protected:
405 enum { N = SkBENCHLOOP(30000) };
406
407 virtual const char* onGetName() SK_OVERRIDE {
408 return fInPlace ? "path_transform_in_place" : "path_transform_copy";
409 }
410
411 virtual void onPreDraw() SK_OVERRIDE {
412 fMatrix.setScale(5 * SK_Scalar1, 6 * SK_Scalar1);
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000413 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000414 fPaths.reset(kPathCnt);
415 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000416 this->makePath(&fPaths[i]);
417 }
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000418 this->finishedMakingPaths();
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000419 if (!fInPlace) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000420 fTransformed.reset(kPathCnt);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000421 }
422 }
423
424 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
425 if (fInPlace) {
426 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000427 fPaths[i & (kPathCnt - 1)].transform(fMatrix);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000428 }
429 } else {
430 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000431 int idx = i & (kPathCnt - 1);
432 fPaths[idx].transform(fMatrix, &fTransformed[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000433 }
434 }
435 }
436
437 virtual void onPostDraw() SK_OVERRIDE {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000438 fPaths.reset(0);
439 fTransformed.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000440 }
441
442private:
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000443 enum {
444 // must be a pow 2
445 kPathCnt = 1 << 5,
446 };
447 SkAutoTArray<SkPath> fPaths;
448 SkAutoTArray<SkPath> fTransformed;
449
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000450 SkMatrix fMatrix;
451 bool fInPlace;
452 typedef RandomPathBench INHERITED;
453};
454
455class PathEqualityBench : public RandomPathBench {
456public:
457 PathEqualityBench(void* param)
458 : INHERITED(param) {
459 }
460
461protected:
462 enum { N = SkBENCHLOOP(40000) };
463
464 virtual const char* onGetName() SK_OVERRIDE {
465 return "path_equality_50%";
466 }
467
468 virtual void onPreDraw() SK_OVERRIDE {
469 fParity = 0;
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000470 this->createData(10, 100);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000471 fPaths.reset(kPathCnt);
472 fCopies.reset(kPathCnt);
473 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000474 this->makePath(&fPaths[i]);
475 fCopies[i] = fPaths[i];
476 }
477 this->finishedMakingPaths();
478 }
479
480 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
481 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000482 int idx = i & (kPathCnt - 1);
483 fParity ^= (fPaths[idx] == fCopies[idx & ~0x1]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000484 }
485 }
486
487 virtual void onPostDraw() SK_OVERRIDE {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000488 fPaths.reset(0);
489 fCopies.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000490 }
491
492private:
493 bool fParity; // attempt to keep compiler from optimizing out the ==
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000494 enum {
495 // must be a pow 2
496 kPathCnt = 1 << 5,
497 };
498 SkAutoTArray<SkPath> fPaths;
499 SkAutoTArray<SkPath> fCopies;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000500 typedef RandomPathBench INHERITED;
501};
502
503class SkBench_AddPathTest : public RandomPathBench {
504public:
505 enum AddType {
506 kAdd_AddType,
507 kAddTrans_AddType,
508 kAddMatrix_AddType,
509 kPathTo_AddType,
510 kReverseAdd_AddType,
511 kReversePathTo_AddType,
512 };
513
514 SkBench_AddPathTest(AddType type, void* param)
515 : INHERITED(param)
516 , fType(type) {
517 fMatrix.setRotate(60 * SK_Scalar1);
518 }
519
520protected:
521 enum { N = SkBENCHLOOP(15000) };
522
523 virtual const char* onGetName() SK_OVERRIDE {
524 switch (fType) {
525 case kAdd_AddType:
526 return "path_add_path";
527 case kAddTrans_AddType:
528 return "path_add_path_trans";
529 case kAddMatrix_AddType:
530 return "path_add_path_matrix";
531 case kPathTo_AddType:
532 return "path_path_to";
533 case kReverseAdd_AddType:
534 return "path_reverse_add_path";
535 case kReversePathTo_AddType:
536 return "path_reverse_path_to";
537 default:
538 SkDEBUGFAIL("Bad add type");
539 return "";
540 }
541 }
542
543 virtual void onPreDraw() SK_OVERRIDE {
544 // pathTo and reversePathTo assume a single contour path.
545 bool allowMoves = kPathTo_AddType != fType &&
546 kReversePathTo_AddType != fType;
bsalomon@google.com6d552ee2012-08-14 15:10:09 +0000547 this->createData(10, 100, allowMoves);
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000548 fPaths0.reset(kPathCnt);
549 fPaths1.reset(kPathCnt);
550 for (int i = 0; i < kPathCnt; ++i) {
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000551 this->makePath(&fPaths0[i]);
552 this->makePath(&fPaths1[i]);
553 }
554 this->finishedMakingPaths();
555 }
556
557 virtual void onDraw(SkCanvas*) SK_OVERRIDE {
558 switch (fType) {
559 case kAdd_AddType:
560 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000561 int idx = i & (kPathCnt - 1);
562 SkPath result = fPaths0[idx];
563 result.addPath(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000564 }
565 break;
566 case kAddTrans_AddType:
567 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000568 int idx = i & (kPathCnt - 1);
569 SkPath result = fPaths0[idx];
570 result.addPath(fPaths1[idx], 2 * SK_Scalar1, 5 * SK_Scalar1);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000571 }
572 break;
573 case kAddMatrix_AddType:
574 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000575 int idx = i & (kPathCnt - 1);
576 SkPath result = fPaths0[idx];
577 result.addPath(fPaths1[idx], fMatrix);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000578 }
579 break;
580 case kPathTo_AddType:
581 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000582 int idx = i & (kPathCnt - 1);
583 SkPath result = fPaths0[idx];
584 result.pathTo(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000585 }
586 break;
587 case kReverseAdd_AddType:
588 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000589 int idx = i & (kPathCnt - 1);
590 SkPath result = fPaths0[idx];
591 result.reverseAddPath(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000592 }
593 break;
594 case kReversePathTo_AddType:
595 for (int i = 0; i < N; ++i) {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000596 int idx = i & (kPathCnt - 1);
597 SkPath result = fPaths0[idx];
598 result.reversePathTo(fPaths1[idx]);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000599 }
600 break;
601 }
602 }
603
604 virtual void onPostDraw() SK_OVERRIDE {
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000605 fPaths0.reset(0);
606 fPaths1.reset(0);
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000607 }
608
609private:
610 AddType fType; // or reverseAddPath
bsalomon@google.comb5e47032012-08-14 17:49:46 +0000611 enum {
612 // must be a pow 2
613 kPathCnt = 1 << 5,
614 };
615 SkAutoTArray<SkPath> fPaths0;
616 SkAutoTArray<SkPath> fPaths1;
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000617 SkMatrix fMatrix;
618 typedef RandomPathBench INHERITED;
619};
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000620
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000621
622class CirclesBench : public SkBenchmark {
623protected:
624 SkString fName;
625
626 enum {
627 N = SkBENCHLOOP(100)
628 };
629public:
630 CirclesBench(void* param) : INHERITED(param) {
631 fName.printf("circles");
632 }
633
634protected:
635 virtual const char* onGetName() SK_OVERRIDE {
636 return fName.c_str();
637 }
638
639 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
640 SkPaint paint;
641
642 paint.setColor(SK_ColorBLACK);
643 paint.setAntiAlias(true);
644
645 SkRandom rand;
646
647 SkRect r;
648
649 for (int i = 0; i < 5000; ++i) {
650 SkScalar radius = rand.nextUScalar1() * 3;
651 r.fLeft = rand.nextUScalar1() * 300;
652 r.fTop = rand.nextUScalar1() * 300;
653 r.fRight = r.fLeft + 2 * radius;
654 r.fBottom = r.fTop + 2 * radius;
655
656 SkPath temp;
657
658 // mimic how Chrome does circles
659 temp.arcTo(r, 0, 0, false);
660 temp.addOval(r, SkPath::kCCW_Direction);
661 temp.arcTo(r, 360, 0, true);
662 temp.close();
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000663
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000664 canvas->drawPath(temp, paint);
665 }
666 }
667
668private:
669 typedef SkBenchmark INHERITED;
670};
671
reed@google.comd34658a2011-04-11 13:12:51 +0000672static SkBenchmark* FactT00(void* p) { return new TrianglePathBench(p, FLAGS00); }
673static SkBenchmark* FactT01(void* p) { return new TrianglePathBench(p, FLAGS01); }
674static SkBenchmark* FactT10(void* p) { return new TrianglePathBench(p, FLAGS10); }
675static SkBenchmark* FactT11(void* p) { return new TrianglePathBench(p, FLAGS11); }
676
677static SkBenchmark* FactR00(void* p) { return new RectPathBench(p, FLAGS00); }
678static SkBenchmark* FactR01(void* p) { return new RectPathBench(p, FLAGS01); }
679static SkBenchmark* FactR10(void* p) { return new RectPathBench(p, FLAGS10); }
680static SkBenchmark* FactR11(void* p) { return new RectPathBench(p, FLAGS11); }
681
682static SkBenchmark* FactO00(void* p) { return new OvalPathBench(p, FLAGS00); }
683static SkBenchmark* FactO01(void* p) { return new OvalPathBench(p, FLAGS01); }
684static SkBenchmark* FactO10(void* p) { return new OvalPathBench(p, FLAGS10); }
685static SkBenchmark* FactO11(void* p) { return new OvalPathBench(p, FLAGS11); }
686
bsalomon@google.com1647a192012-04-11 15:34:46 +0000687static SkBenchmark* FactC00(void* p) { return new CirclePathBench(p, FLAGS00); }
688static SkBenchmark* FactC01(void* p) { return new CirclePathBench(p, FLAGS01); }
689static SkBenchmark* FactC10(void* p) { return new CirclePathBench(p, FLAGS10); }
690static SkBenchmark* FactC11(void* p) { return new CirclePathBench(p, FLAGS11); }
691
reed@google.comd34658a2011-04-11 13:12:51 +0000692static SkBenchmark* FactS00(void* p) { return new SawToothPathBench(p, FLAGS00); }
693static SkBenchmark* FactS01(void* p) { return new SawToothPathBench(p, FLAGS01); }
694
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000695static SkBenchmark* FactLC00(void* p) {
696 return new LongCurvedPathBench(p, FLAGS00);
697}
698static SkBenchmark* FactLC01(void* p) {
699 return new LongCurvedPathBench(p, FLAGS01);
700}
701
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000702static SkBenchmark* FactLL00(void* p) {
703 return new LongLinePathBench(p, FLAGS00);
704}
705
706static SkBenchmark* FactLL01(void* p) {
707 return new LongLinePathBench(p, FLAGS01);
708}
709
reed@google.comd34658a2011-04-11 13:12:51 +0000710static BenchRegistry gRegT00(FactT00);
711static BenchRegistry gRegT01(FactT01);
712static BenchRegistry gRegT10(FactT10);
713static BenchRegistry gRegT11(FactT11);
714
715static BenchRegistry gRegR00(FactR00);
716static BenchRegistry gRegR01(FactR01);
717static BenchRegistry gRegR10(FactR10);
718static BenchRegistry gRegR11(FactR11);
719
720static BenchRegistry gRegO00(FactO00);
721static BenchRegistry gRegO01(FactO01);
722static BenchRegistry gRegO10(FactO10);
723static BenchRegistry gRegO11(FactO11);
724
bsalomon@google.com1647a192012-04-11 15:34:46 +0000725static BenchRegistry gRegC00(FactC00);
726static BenchRegistry gRegC01(FactC01);
727static BenchRegistry gRegC10(FactC10);
728static BenchRegistry gRegC11(FactC11);
729
reed@google.comd34658a2011-04-11 13:12:51 +0000730static BenchRegistry gRegS00(FactS00);
731static BenchRegistry gRegS01(FactS01);
732
tomhudson@google.com6e8d3352011-06-22 17:16:35 +0000733static BenchRegistry gRegLC00(FactLC00);
734static BenchRegistry gRegLC01(FactLC01);
735
senorblanco@chromium.orge50f7362012-01-12 19:10:35 +0000736static BenchRegistry gRegLL00(FactLL00);
737static BenchRegistry gRegLL01(FactLL01);
738
bsalomon@google.com30e6d2c2012-08-13 14:03:31 +0000739static SkBenchmark* FactCreate(void* p) { return new PathCreateBench(p); }
740static BenchRegistry gRegCreate(FactCreate);
741
742static SkBenchmark* FactCopy(void* p) { return new PathCopyBench(p); }
743static BenchRegistry gRegCopy(FactCopy);
744
745static SkBenchmark* FactPathTransformInPlace(void* p) { return new PathTransformBench(true, p); }
746static BenchRegistry gRegPathTransformInPlace(FactPathTransformInPlace);
747
748static SkBenchmark* FactPathTransformCopy(void* p) { return new PathTransformBench(false, p); }
749static BenchRegistry gRegPathTransformCopy(FactPathTransformCopy);
750
751static SkBenchmark* FactEquality(void* p) { return new PathEqualityBench(p); }
752static BenchRegistry gRegEquality(FactEquality);
753
754static SkBenchmark* FactAdd(void* p) { return new SkBench_AddPathTest(SkBench_AddPathTest::kAdd_AddType, p); }
755static SkBenchmark* FactAddTrans(void* p) { return new SkBench_AddPathTest(SkBench_AddPathTest::kAddTrans_AddType, p); }
756static SkBenchmark* FactAddMatrix(void* p) { return new SkBench_AddPathTest(SkBench_AddPathTest::kAddMatrix_AddType, p); }
757static SkBenchmark* FactPathTo(void* p) { return new SkBench_AddPathTest(SkBench_AddPathTest::kPathTo_AddType, p); }
758static SkBenchmark* FactReverseAdd(void* p) { return new SkBench_AddPathTest(SkBench_AddPathTest::kReverseAdd_AddType, p); }
759static SkBenchmark* FactReverseTo(void* p) { return new SkBench_AddPathTest(SkBench_AddPathTest::kReversePathTo_AddType, p); }
760
761static BenchRegistry gRegAdd(FactAdd);
762static BenchRegistry gRegAddTrans(FactAddTrans);
763static BenchRegistry gRegAddMatrix(FactAddMatrix);
764static BenchRegistry gRegPathTo(FactPathTo);
765static BenchRegistry gRegReverseAdd(FactReverseAdd);
766static BenchRegistry gRegReverseTo(FactReverseTo);
robertphillips@google.com17bb4582012-08-20 17:24:16 +0000767
768static SkBenchmark* CirclesTest(void* p) { return new CirclesBench(p); }
769static BenchRegistry gRegCirclesTest(CirclesTest);
770