1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2011 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "bench/Benchmark.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorPriv.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathUtils.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRRect.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkShader.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTArray.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTDArray.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h"
21*c8dee2aaSAndroid Build Coastguard Worker
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkDraw.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkMatrixPriv.h"
24*c8dee2aaSAndroid Build Coastguard Worker
25*c8dee2aaSAndroid Build Coastguard Worker using namespace skia_private;
26*c8dee2aaSAndroid Build Coastguard Worker
27*c8dee2aaSAndroid Build Coastguard Worker enum Flags {
28*c8dee2aaSAndroid Build Coastguard Worker kStroke_Flag = 1 << 0,
29*c8dee2aaSAndroid Build Coastguard Worker kBig_Flag = 1 << 1
30*c8dee2aaSAndroid Build Coastguard Worker };
31*c8dee2aaSAndroid Build Coastguard Worker
32*c8dee2aaSAndroid Build Coastguard Worker #define FLAGS00 Flags(0)
33*c8dee2aaSAndroid Build Coastguard Worker #define FLAGS01 Flags(kStroke_Flag)
34*c8dee2aaSAndroid Build Coastguard Worker #define FLAGS10 Flags(kBig_Flag)
35*c8dee2aaSAndroid Build Coastguard Worker #define FLAGS11 Flags(kStroke_Flag | kBig_Flag)
36*c8dee2aaSAndroid Build Coastguard Worker
37*c8dee2aaSAndroid Build Coastguard Worker class PathBench : public Benchmark {
38*c8dee2aaSAndroid Build Coastguard Worker SkPaint fPaint;
39*c8dee2aaSAndroid Build Coastguard Worker SkString fName;
40*c8dee2aaSAndroid Build Coastguard Worker Flags fFlags;
41*c8dee2aaSAndroid Build Coastguard Worker public:
PathBench(Flags flags)42*c8dee2aaSAndroid Build Coastguard Worker PathBench(Flags flags) : fFlags(flags) {
43*c8dee2aaSAndroid Build Coastguard Worker fPaint.setStyle(flags & kStroke_Flag ? SkPaint::kStroke_Style :
44*c8dee2aaSAndroid Build Coastguard Worker SkPaint::kFill_Style);
45*c8dee2aaSAndroid Build Coastguard Worker fPaint.setStrokeWidth(SkIntToScalar(5));
46*c8dee2aaSAndroid Build Coastguard Worker fPaint.setStrokeJoin(SkPaint::kBevel_Join);
47*c8dee2aaSAndroid Build Coastguard Worker }
48*c8dee2aaSAndroid Build Coastguard Worker
49*c8dee2aaSAndroid Build Coastguard Worker virtual void appendName(SkString*) = 0;
50*c8dee2aaSAndroid Build Coastguard Worker virtual void makePath(SkPath*) = 0;
complexity()51*c8dee2aaSAndroid Build Coastguard Worker virtual int complexity() { return 0; }
52*c8dee2aaSAndroid Build Coastguard Worker
53*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()54*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
55*c8dee2aaSAndroid Build Coastguard Worker fName.printf("path_%s_%s_",
56*c8dee2aaSAndroid Build Coastguard Worker fFlags & kStroke_Flag ? "stroke" : "fill",
57*c8dee2aaSAndroid Build Coastguard Worker fFlags & kBig_Flag ? "big" : "small");
58*c8dee2aaSAndroid Build Coastguard Worker this->appendName(&fName);
59*c8dee2aaSAndroid Build Coastguard Worker return fName.c_str();
60*c8dee2aaSAndroid Build Coastguard Worker }
61*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas * canvas)62*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas* canvas) override {
63*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint(fPaint);
64*c8dee2aaSAndroid Build Coastguard Worker this->setupPaint(&paint);
65*c8dee2aaSAndroid Build Coastguard Worker
66*c8dee2aaSAndroid Build Coastguard Worker SkPath path;
67*c8dee2aaSAndroid Build Coastguard Worker this->makePath(&path);
68*c8dee2aaSAndroid Build Coastguard Worker if (fFlags & kBig_Flag) {
69*c8dee2aaSAndroid Build Coastguard Worker const SkMatrix m = SkMatrix::Scale(10, 10);
70*c8dee2aaSAndroid Build Coastguard Worker path.transform(m);
71*c8dee2aaSAndroid Build Coastguard Worker }
72*c8dee2aaSAndroid Build Coastguard Worker
73*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; i++) {
74*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(path, paint);
75*c8dee2aaSAndroid Build Coastguard Worker }
76*c8dee2aaSAndroid Build Coastguard Worker }
77*c8dee2aaSAndroid Build Coastguard Worker
78*c8dee2aaSAndroid Build Coastguard Worker private:
79*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark;
80*c8dee2aaSAndroid Build Coastguard Worker };
81*c8dee2aaSAndroid Build Coastguard Worker
82*c8dee2aaSAndroid Build Coastguard Worker class TrianglePathBench : public PathBench {
83*c8dee2aaSAndroid Build Coastguard Worker public:
TrianglePathBench(Flags flags)84*c8dee2aaSAndroid Build Coastguard Worker TrianglePathBench(Flags flags) : INHERITED(flags) {}
85*c8dee2aaSAndroid Build Coastguard Worker
appendName(SkString * name)86*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override {
87*c8dee2aaSAndroid Build Coastguard Worker name->append("triangle");
88*c8dee2aaSAndroid Build Coastguard Worker }
makePath(SkPath * path)89*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override {
90*c8dee2aaSAndroid Build Coastguard Worker static const int gCoord[] = {
91*c8dee2aaSAndroid Build Coastguard Worker 10, 10, 15, 5, 20, 20
92*c8dee2aaSAndroid Build Coastguard Worker };
93*c8dee2aaSAndroid Build Coastguard Worker path->moveTo(SkIntToScalar(gCoord[0]), SkIntToScalar(gCoord[1]));
94*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(SkIntToScalar(gCoord[2]), SkIntToScalar(gCoord[3]));
95*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(SkIntToScalar(gCoord[4]), SkIntToScalar(gCoord[5]));
96*c8dee2aaSAndroid Build Coastguard Worker path->close();
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker private:
99*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = PathBench;
100*c8dee2aaSAndroid Build Coastguard Worker };
101*c8dee2aaSAndroid Build Coastguard Worker
102*c8dee2aaSAndroid Build Coastguard Worker class RectPathBench : public PathBench {
103*c8dee2aaSAndroid Build Coastguard Worker public:
RectPathBench(Flags flags)104*c8dee2aaSAndroid Build Coastguard Worker RectPathBench(Flags flags) : INHERITED(flags) {}
105*c8dee2aaSAndroid Build Coastguard Worker
appendName(SkString * name)106*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override {
107*c8dee2aaSAndroid Build Coastguard Worker name->append("rect");
108*c8dee2aaSAndroid Build Coastguard Worker }
makePath(SkPath * path)109*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override {
110*c8dee2aaSAndroid Build Coastguard Worker SkRect r = { 10, 10, 20, 20 };
111*c8dee2aaSAndroid Build Coastguard Worker path->addRect(r);
112*c8dee2aaSAndroid Build Coastguard Worker }
113*c8dee2aaSAndroid Build Coastguard Worker private:
114*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = PathBench;
115*c8dee2aaSAndroid Build Coastguard Worker };
116*c8dee2aaSAndroid Build Coastguard Worker
117*c8dee2aaSAndroid Build Coastguard Worker class RotatedRectBench : public PathBench {
118*c8dee2aaSAndroid Build Coastguard Worker public:
RotatedRectBench(Flags flags,bool aa,int degrees)119*c8dee2aaSAndroid Build Coastguard Worker RotatedRectBench(Flags flags, bool aa, int degrees) : INHERITED(flags) {
120*c8dee2aaSAndroid Build Coastguard Worker fAA = aa;
121*c8dee2aaSAndroid Build Coastguard Worker fDegrees = degrees;
122*c8dee2aaSAndroid Build Coastguard Worker }
123*c8dee2aaSAndroid Build Coastguard Worker
appendName(SkString * name)124*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override {
125*c8dee2aaSAndroid Build Coastguard Worker SkString suffix;
126*c8dee2aaSAndroid Build Coastguard Worker suffix.printf("rotated_rect_%s_%d", fAA ? "aa" : "noaa", fDegrees);
127*c8dee2aaSAndroid Build Coastguard Worker name->append(suffix);
128*c8dee2aaSAndroid Build Coastguard Worker }
129*c8dee2aaSAndroid Build Coastguard Worker
makePath(SkPath * path)130*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override {
131*c8dee2aaSAndroid Build Coastguard Worker SkRect r = { 10, 10, 20, 20 };
132*c8dee2aaSAndroid Build Coastguard Worker path->addRect(r);
133*c8dee2aaSAndroid Build Coastguard Worker SkMatrix rotateMatrix;
134*c8dee2aaSAndroid Build Coastguard Worker rotateMatrix.setRotate((SkScalar)fDegrees);
135*c8dee2aaSAndroid Build Coastguard Worker path->transform(rotateMatrix);
136*c8dee2aaSAndroid Build Coastguard Worker }
137*c8dee2aaSAndroid Build Coastguard Worker
setupPaint(SkPaint * paint)138*c8dee2aaSAndroid Build Coastguard Worker void setupPaint(SkPaint* paint) override {
139*c8dee2aaSAndroid Build Coastguard Worker PathBench::setupPaint(paint);
140*c8dee2aaSAndroid Build Coastguard Worker paint->setAntiAlias(fAA);
141*c8dee2aaSAndroid Build Coastguard Worker }
142*c8dee2aaSAndroid Build Coastguard Worker private:
143*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = PathBench;
144*c8dee2aaSAndroid Build Coastguard Worker int fDegrees;
145*c8dee2aaSAndroid Build Coastguard Worker bool fAA;
146*c8dee2aaSAndroid Build Coastguard Worker };
147*c8dee2aaSAndroid Build Coastguard Worker
148*c8dee2aaSAndroid Build Coastguard Worker class OvalPathBench : public PathBench {
149*c8dee2aaSAndroid Build Coastguard Worker public:
OvalPathBench(Flags flags)150*c8dee2aaSAndroid Build Coastguard Worker OvalPathBench(Flags flags) : INHERITED(flags) {}
151*c8dee2aaSAndroid Build Coastguard Worker
appendName(SkString * name)152*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override {
153*c8dee2aaSAndroid Build Coastguard Worker name->append("oval");
154*c8dee2aaSAndroid Build Coastguard Worker }
makePath(SkPath * path)155*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override {
156*c8dee2aaSAndroid Build Coastguard Worker SkRect r = { 10, 10, 23, 20 };
157*c8dee2aaSAndroid Build Coastguard Worker path->addOval(r);
158*c8dee2aaSAndroid Build Coastguard Worker }
159*c8dee2aaSAndroid Build Coastguard Worker private:
160*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = PathBench;
161*c8dee2aaSAndroid Build Coastguard Worker };
162*c8dee2aaSAndroid Build Coastguard Worker
163*c8dee2aaSAndroid Build Coastguard Worker class CirclePathBench: public PathBench {
164*c8dee2aaSAndroid Build Coastguard Worker public:
CirclePathBench(Flags flags)165*c8dee2aaSAndroid Build Coastguard Worker CirclePathBench(Flags flags) : INHERITED(flags) {}
166*c8dee2aaSAndroid Build Coastguard Worker
appendName(SkString * name)167*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override {
168*c8dee2aaSAndroid Build Coastguard Worker name->append("circle");
169*c8dee2aaSAndroid Build Coastguard Worker }
makePath(SkPath * path)170*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override {
171*c8dee2aaSAndroid Build Coastguard Worker path->addCircle(SkIntToScalar(20), SkIntToScalar(20),
172*c8dee2aaSAndroid Build Coastguard Worker SkIntToScalar(10));
173*c8dee2aaSAndroid Build Coastguard Worker }
174*c8dee2aaSAndroid Build Coastguard Worker private:
175*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = PathBench;
176*c8dee2aaSAndroid Build Coastguard Worker };
177*c8dee2aaSAndroid Build Coastguard Worker
178*c8dee2aaSAndroid Build Coastguard Worker class NonAACirclePathBench: public CirclePathBench {
179*c8dee2aaSAndroid Build Coastguard Worker public:
NonAACirclePathBench(Flags flags)180*c8dee2aaSAndroid Build Coastguard Worker NonAACirclePathBench(Flags flags) : INHERITED(flags) {}
181*c8dee2aaSAndroid Build Coastguard Worker
appendName(SkString * name)182*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override {
183*c8dee2aaSAndroid Build Coastguard Worker name->append("nonaacircle");
184*c8dee2aaSAndroid Build Coastguard Worker }
185*c8dee2aaSAndroid Build Coastguard Worker
setupPaint(SkPaint * paint)186*c8dee2aaSAndroid Build Coastguard Worker void setupPaint(SkPaint* paint) override {
187*c8dee2aaSAndroid Build Coastguard Worker CirclePathBench::setupPaint(paint);
188*c8dee2aaSAndroid Build Coastguard Worker paint->setAntiAlias(false);
189*c8dee2aaSAndroid Build Coastguard Worker }
190*c8dee2aaSAndroid Build Coastguard Worker
191*c8dee2aaSAndroid Build Coastguard Worker private:
192*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = CirclePathBench;
193*c8dee2aaSAndroid Build Coastguard Worker };
194*c8dee2aaSAndroid Build Coastguard Worker
195*c8dee2aaSAndroid Build Coastguard Worker // Test max speedup of Analytic AA for concave paths
196*c8dee2aaSAndroid Build Coastguard Worker class AAAConcavePathBench : public PathBench {
197*c8dee2aaSAndroid Build Coastguard Worker public:
AAAConcavePathBench(Flags flags)198*c8dee2aaSAndroid Build Coastguard Worker AAAConcavePathBench(Flags flags) : INHERITED(flags) {}
199*c8dee2aaSAndroid Build Coastguard Worker
appendName(SkString * name)200*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override {
201*c8dee2aaSAndroid Build Coastguard Worker name->append("concave_aaa");
202*c8dee2aaSAndroid Build Coastguard Worker }
203*c8dee2aaSAndroid Build Coastguard Worker
makePath(SkPath * path)204*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override {
205*c8dee2aaSAndroid Build Coastguard Worker path->moveTo(10, 10);
206*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(15, 10);
207*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(15, 5);
208*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(40, 40);
209*c8dee2aaSAndroid Build Coastguard Worker path->close();
210*c8dee2aaSAndroid Build Coastguard Worker }
211*c8dee2aaSAndroid Build Coastguard Worker
212*c8dee2aaSAndroid Build Coastguard Worker private:
213*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = PathBench;
214*c8dee2aaSAndroid Build Coastguard Worker };
215*c8dee2aaSAndroid Build Coastguard Worker
216*c8dee2aaSAndroid Build Coastguard Worker // Test max speedup of Analytic AA for convex paths
217*c8dee2aaSAndroid Build Coastguard Worker class AAAConvexPathBench : public PathBench {
218*c8dee2aaSAndroid Build Coastguard Worker public:
AAAConvexPathBench(Flags flags)219*c8dee2aaSAndroid Build Coastguard Worker AAAConvexPathBench(Flags flags) : INHERITED(flags) {}
220*c8dee2aaSAndroid Build Coastguard Worker
appendName(SkString * name)221*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override {
222*c8dee2aaSAndroid Build Coastguard Worker name->append("convex_aaa");
223*c8dee2aaSAndroid Build Coastguard Worker }
224*c8dee2aaSAndroid Build Coastguard Worker
makePath(SkPath * path)225*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override {
226*c8dee2aaSAndroid Build Coastguard Worker path->moveTo(10, 10);
227*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(15, 10);
228*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(40, 50);
229*c8dee2aaSAndroid Build Coastguard Worker path->close();
230*c8dee2aaSAndroid Build Coastguard Worker }
231*c8dee2aaSAndroid Build Coastguard Worker
232*c8dee2aaSAndroid Build Coastguard Worker private:
233*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = PathBench;
234*c8dee2aaSAndroid Build Coastguard Worker };
235*c8dee2aaSAndroid Build Coastguard Worker
236*c8dee2aaSAndroid Build Coastguard Worker class SawToothPathBench : public PathBench {
237*c8dee2aaSAndroid Build Coastguard Worker public:
SawToothPathBench(Flags flags)238*c8dee2aaSAndroid Build Coastguard Worker SawToothPathBench(Flags flags) : INHERITED(flags) {}
239*c8dee2aaSAndroid Build Coastguard Worker
appendName(SkString * name)240*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override {
241*c8dee2aaSAndroid Build Coastguard Worker name->append("sawtooth");
242*c8dee2aaSAndroid Build Coastguard Worker }
makePath(SkPath * path)243*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override {
244*c8dee2aaSAndroid Build Coastguard Worker SkScalar x = SkIntToScalar(20);
245*c8dee2aaSAndroid Build Coastguard Worker SkScalar y = SkIntToScalar(20);
246*c8dee2aaSAndroid Build Coastguard Worker const SkScalar x0 = x;
247*c8dee2aaSAndroid Build Coastguard Worker const SkScalar dx = SK_Scalar1 * 5;
248*c8dee2aaSAndroid Build Coastguard Worker const SkScalar dy = SK_Scalar1 * 10;
249*c8dee2aaSAndroid Build Coastguard Worker
250*c8dee2aaSAndroid Build Coastguard Worker path->moveTo(x, y);
251*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < 32; i++) {
252*c8dee2aaSAndroid Build Coastguard Worker x += dx;
253*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(x, y - dy);
254*c8dee2aaSAndroid Build Coastguard Worker x += dx;
255*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(x, y + dy);
256*c8dee2aaSAndroid Build Coastguard Worker }
257*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(x, y + 2 * dy);
258*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(x0, y + 2 * dy);
259*c8dee2aaSAndroid Build Coastguard Worker path->close();
260*c8dee2aaSAndroid Build Coastguard Worker }
complexity()261*c8dee2aaSAndroid Build Coastguard Worker int complexity() override { return 1; }
262*c8dee2aaSAndroid Build Coastguard Worker private:
263*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = PathBench;
264*c8dee2aaSAndroid Build Coastguard Worker };
265*c8dee2aaSAndroid Build Coastguard Worker
266*c8dee2aaSAndroid Build Coastguard Worker class LongCurvedPathBench : public PathBench {
267*c8dee2aaSAndroid Build Coastguard Worker public:
LongCurvedPathBench(Flags flags)268*c8dee2aaSAndroid Build Coastguard Worker LongCurvedPathBench(Flags flags) : INHERITED(flags) {}
269*c8dee2aaSAndroid Build Coastguard Worker
appendName(SkString * name)270*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override {
271*c8dee2aaSAndroid Build Coastguard Worker name->append("long_curved");
272*c8dee2aaSAndroid Build Coastguard Worker }
makePath(SkPath * path)273*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override {
274*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand (12);
275*c8dee2aaSAndroid Build Coastguard Worker int i;
276*c8dee2aaSAndroid Build Coastguard Worker for (i = 0; i < 100; i++) {
277*c8dee2aaSAndroid Build Coastguard Worker path->quadTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480,
278*c8dee2aaSAndroid Build Coastguard Worker rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
279*c8dee2aaSAndroid Build Coastguard Worker }
280*c8dee2aaSAndroid Build Coastguard Worker path->close();
281*c8dee2aaSAndroid Build Coastguard Worker }
complexity()282*c8dee2aaSAndroid Build Coastguard Worker int complexity() override { return 2; }
283*c8dee2aaSAndroid Build Coastguard Worker private:
284*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = PathBench;
285*c8dee2aaSAndroid Build Coastguard Worker };
286*c8dee2aaSAndroid Build Coastguard Worker
287*c8dee2aaSAndroid Build Coastguard Worker class LongLinePathBench : public PathBench {
288*c8dee2aaSAndroid Build Coastguard Worker public:
LongLinePathBench(Flags flags)289*c8dee2aaSAndroid Build Coastguard Worker LongLinePathBench(Flags flags) : INHERITED(flags) {}
290*c8dee2aaSAndroid Build Coastguard Worker
appendName(SkString * name)291*c8dee2aaSAndroid Build Coastguard Worker void appendName(SkString* name) override {
292*c8dee2aaSAndroid Build Coastguard Worker name->append("long_line");
293*c8dee2aaSAndroid Build Coastguard Worker }
makePath(SkPath * path)294*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) override {
295*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand;
296*c8dee2aaSAndroid Build Coastguard Worker path->moveTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
297*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 1; i < 100; i++) {
298*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(rand.nextUScalar1() * 640, rand.nextUScalar1() * 480);
299*c8dee2aaSAndroid Build Coastguard Worker }
300*c8dee2aaSAndroid Build Coastguard Worker }
complexity()301*c8dee2aaSAndroid Build Coastguard Worker int complexity() override { return 2; }
302*c8dee2aaSAndroid Build Coastguard Worker private:
303*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = PathBench;
304*c8dee2aaSAndroid Build Coastguard Worker };
305*c8dee2aaSAndroid Build Coastguard Worker
306*c8dee2aaSAndroid Build Coastguard Worker class RandomPathBench : public Benchmark {
307*c8dee2aaSAndroid Build Coastguard Worker public:
isSuitableFor(Backend backend)308*c8dee2aaSAndroid Build Coastguard Worker bool isSuitableFor(Backend backend) override {
309*c8dee2aaSAndroid Build Coastguard Worker return backend == Backend::kNonRendering;
310*c8dee2aaSAndroid Build Coastguard Worker }
311*c8dee2aaSAndroid Build Coastguard Worker
312*c8dee2aaSAndroid Build Coastguard Worker protected:
createData(int minVerbs,int maxVerbs,bool allowMoves=true,SkRect * bounds=nullptr)313*c8dee2aaSAndroid Build Coastguard Worker void createData(int minVerbs,
314*c8dee2aaSAndroid Build Coastguard Worker int maxVerbs,
315*c8dee2aaSAndroid Build Coastguard Worker bool allowMoves = true,
316*c8dee2aaSAndroid Build Coastguard Worker SkRect* bounds = nullptr) {
317*c8dee2aaSAndroid Build Coastguard Worker SkRect tempBounds;
318*c8dee2aaSAndroid Build Coastguard Worker if (nullptr == bounds) {
319*c8dee2aaSAndroid Build Coastguard Worker tempBounds.setXYWH(0, 0, SK_Scalar1, SK_Scalar1);
320*c8dee2aaSAndroid Build Coastguard Worker bounds = &tempBounds;
321*c8dee2aaSAndroid Build Coastguard Worker }
322*c8dee2aaSAndroid Build Coastguard Worker fVerbCnts.reset(kNumVerbCnts);
323*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kNumVerbCnts; ++i) {
324*c8dee2aaSAndroid Build Coastguard Worker fVerbCnts[i] = fRandom.nextRangeU(minVerbs, maxVerbs + 1);
325*c8dee2aaSAndroid Build Coastguard Worker }
326*c8dee2aaSAndroid Build Coastguard Worker fVerbs.reset(kNumVerbs);
327*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kNumVerbs; ++i) {
328*c8dee2aaSAndroid Build Coastguard Worker do {
329*c8dee2aaSAndroid Build Coastguard Worker fVerbs[i] = static_cast<SkPath::Verb>(fRandom.nextULessThan(SkPath::kDone_Verb));
330*c8dee2aaSAndroid Build Coastguard Worker } while (!allowMoves && SkPath::kMove_Verb == fVerbs[i]);
331*c8dee2aaSAndroid Build Coastguard Worker }
332*c8dee2aaSAndroid Build Coastguard Worker fPoints.reset(kNumPoints);
333*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kNumPoints; ++i) {
334*c8dee2aaSAndroid Build Coastguard Worker fPoints[i].set(fRandom.nextRangeScalar(bounds->fLeft, bounds->fRight),
335*c8dee2aaSAndroid Build Coastguard Worker fRandom.nextRangeScalar(bounds->fTop, bounds->fBottom));
336*c8dee2aaSAndroid Build Coastguard Worker }
337*c8dee2aaSAndroid Build Coastguard Worker this->restartMakingPaths();
338*c8dee2aaSAndroid Build Coastguard Worker }
339*c8dee2aaSAndroid Build Coastguard Worker
restartMakingPaths()340*c8dee2aaSAndroid Build Coastguard Worker void restartMakingPaths() {
341*c8dee2aaSAndroid Build Coastguard Worker fCurrPath = 0;
342*c8dee2aaSAndroid Build Coastguard Worker fCurrVerb = 0;
343*c8dee2aaSAndroid Build Coastguard Worker fCurrPoint = 0;
344*c8dee2aaSAndroid Build Coastguard Worker }
345*c8dee2aaSAndroid Build Coastguard Worker
makePath(SkPath * path)346*c8dee2aaSAndroid Build Coastguard Worker void makePath(SkPath* path) {
347*c8dee2aaSAndroid Build Coastguard Worker int vCount = fVerbCnts[(fCurrPath++) & (kNumVerbCnts - 1)];
348*c8dee2aaSAndroid Build Coastguard Worker for (int v = 0; v < vCount; ++v) {
349*c8dee2aaSAndroid Build Coastguard Worker int verb = fVerbs[(fCurrVerb++) & (kNumVerbs - 1)];
350*c8dee2aaSAndroid Build Coastguard Worker switch (verb) {
351*c8dee2aaSAndroid Build Coastguard Worker case SkPath::kMove_Verb:
352*c8dee2aaSAndroid Build Coastguard Worker path->moveTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
353*c8dee2aaSAndroid Build Coastguard Worker break;
354*c8dee2aaSAndroid Build Coastguard Worker case SkPath::kLine_Verb:
355*c8dee2aaSAndroid Build Coastguard Worker path->lineTo(fPoints[(fCurrPoint++) & (kNumPoints - 1)]);
356*c8dee2aaSAndroid Build Coastguard Worker break;
357*c8dee2aaSAndroid Build Coastguard Worker case SkPath::kQuad_Verb:
358*c8dee2aaSAndroid Build Coastguard Worker path->quadTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
359*c8dee2aaSAndroid Build Coastguard Worker fPoints[(fCurrPoint + 1) & (kNumPoints - 1)]);
360*c8dee2aaSAndroid Build Coastguard Worker fCurrPoint += 2;
361*c8dee2aaSAndroid Build Coastguard Worker break;
362*c8dee2aaSAndroid Build Coastguard Worker case SkPath::kConic_Verb:
363*c8dee2aaSAndroid Build Coastguard Worker path->conicTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
364*c8dee2aaSAndroid Build Coastguard Worker fPoints[(fCurrPoint + 1) & (kNumPoints - 1)],
365*c8dee2aaSAndroid Build Coastguard Worker SK_ScalarHalf);
366*c8dee2aaSAndroid Build Coastguard Worker fCurrPoint += 2;
367*c8dee2aaSAndroid Build Coastguard Worker break;
368*c8dee2aaSAndroid Build Coastguard Worker case SkPath::kCubic_Verb:
369*c8dee2aaSAndroid Build Coastguard Worker path->cubicTo(fPoints[(fCurrPoint + 0) & (kNumPoints - 1)],
370*c8dee2aaSAndroid Build Coastguard Worker fPoints[(fCurrPoint + 1) & (kNumPoints - 1)],
371*c8dee2aaSAndroid Build Coastguard Worker fPoints[(fCurrPoint + 2) & (kNumPoints - 1)]);
372*c8dee2aaSAndroid Build Coastguard Worker fCurrPoint += 3;
373*c8dee2aaSAndroid Build Coastguard Worker break;
374*c8dee2aaSAndroid Build Coastguard Worker case SkPath::kClose_Verb:
375*c8dee2aaSAndroid Build Coastguard Worker path->close();
376*c8dee2aaSAndroid Build Coastguard Worker break;
377*c8dee2aaSAndroid Build Coastguard Worker default:
378*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGFAIL("Unexpected path verb");
379*c8dee2aaSAndroid Build Coastguard Worker break;
380*c8dee2aaSAndroid Build Coastguard Worker }
381*c8dee2aaSAndroid Build Coastguard Worker }
382*c8dee2aaSAndroid Build Coastguard Worker }
383*c8dee2aaSAndroid Build Coastguard Worker
finishedMakingPaths()384*c8dee2aaSAndroid Build Coastguard Worker void finishedMakingPaths() {
385*c8dee2aaSAndroid Build Coastguard Worker fVerbCnts.reset(0);
386*c8dee2aaSAndroid Build Coastguard Worker fVerbs.reset(0);
387*c8dee2aaSAndroid Build Coastguard Worker fPoints.reset(0);
388*c8dee2aaSAndroid Build Coastguard Worker }
389*c8dee2aaSAndroid Build Coastguard Worker
390*c8dee2aaSAndroid Build Coastguard Worker private:
391*c8dee2aaSAndroid Build Coastguard Worker enum {
392*c8dee2aaSAndroid Build Coastguard Worker // these should all be pow 2
393*c8dee2aaSAndroid Build Coastguard Worker kNumVerbCnts = 1 << 5,
394*c8dee2aaSAndroid Build Coastguard Worker kNumVerbs = 1 << 5,
395*c8dee2aaSAndroid Build Coastguard Worker kNumPoints = 1 << 5,
396*c8dee2aaSAndroid Build Coastguard Worker };
397*c8dee2aaSAndroid Build Coastguard Worker AutoTArray<int> fVerbCnts;
398*c8dee2aaSAndroid Build Coastguard Worker AutoTArray<SkPath::Verb> fVerbs;
399*c8dee2aaSAndroid Build Coastguard Worker AutoTArray<SkPoint> fPoints;
400*c8dee2aaSAndroid Build Coastguard Worker int fCurrPath;
401*c8dee2aaSAndroid Build Coastguard Worker int fCurrVerb;
402*c8dee2aaSAndroid Build Coastguard Worker int fCurrPoint;
403*c8dee2aaSAndroid Build Coastguard Worker SkRandom fRandom;
404*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark;
405*c8dee2aaSAndroid Build Coastguard Worker };
406*c8dee2aaSAndroid Build Coastguard Worker
407*c8dee2aaSAndroid Build Coastguard Worker class PathCreateBench : public RandomPathBench {
408*c8dee2aaSAndroid Build Coastguard Worker public:
PathCreateBench()409*c8dee2aaSAndroid Build Coastguard Worker PathCreateBench() {
410*c8dee2aaSAndroid Build Coastguard Worker }
411*c8dee2aaSAndroid Build Coastguard Worker
412*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()413*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
414*c8dee2aaSAndroid Build Coastguard Worker return "path_create";
415*c8dee2aaSAndroid Build Coastguard Worker }
416*c8dee2aaSAndroid Build Coastguard Worker
onDelayedSetup()417*c8dee2aaSAndroid Build Coastguard Worker void onDelayedSetup() override {
418*c8dee2aaSAndroid Build Coastguard Worker this->createData(10, 100);
419*c8dee2aaSAndroid Build Coastguard Worker }
420*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas *)421*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
422*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
423*c8dee2aaSAndroid Build Coastguard Worker if (i % 1000 == 0) {
424*c8dee2aaSAndroid Build Coastguard Worker fPath.reset(); // PathRef memory can grow without bound otherwise.
425*c8dee2aaSAndroid Build Coastguard Worker }
426*c8dee2aaSAndroid Build Coastguard Worker this->makePath(&fPath);
427*c8dee2aaSAndroid Build Coastguard Worker }
428*c8dee2aaSAndroid Build Coastguard Worker this->restartMakingPaths();
429*c8dee2aaSAndroid Build Coastguard Worker }
430*c8dee2aaSAndroid Build Coastguard Worker
431*c8dee2aaSAndroid Build Coastguard Worker private:
432*c8dee2aaSAndroid Build Coastguard Worker SkPath fPath;
433*c8dee2aaSAndroid Build Coastguard Worker
434*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = RandomPathBench;
435*c8dee2aaSAndroid Build Coastguard Worker };
436*c8dee2aaSAndroid Build Coastguard Worker
437*c8dee2aaSAndroid Build Coastguard Worker class PathCopyBench : public RandomPathBench {
438*c8dee2aaSAndroid Build Coastguard Worker public:
PathCopyBench()439*c8dee2aaSAndroid Build Coastguard Worker PathCopyBench() {
440*c8dee2aaSAndroid Build Coastguard Worker }
441*c8dee2aaSAndroid Build Coastguard Worker
442*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()443*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
444*c8dee2aaSAndroid Build Coastguard Worker return "path_copy";
445*c8dee2aaSAndroid Build Coastguard Worker }
onDelayedSetup()446*c8dee2aaSAndroid Build Coastguard Worker void onDelayedSetup() override {
447*c8dee2aaSAndroid Build Coastguard Worker this->createData(10, 100);
448*c8dee2aaSAndroid Build Coastguard Worker fPaths.reset(kPathCnt);
449*c8dee2aaSAndroid Build Coastguard Worker fCopies.reset(kPathCnt);
450*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kPathCnt; ++i) {
451*c8dee2aaSAndroid Build Coastguard Worker this->makePath(&fPaths[i]);
452*c8dee2aaSAndroid Build Coastguard Worker }
453*c8dee2aaSAndroid Build Coastguard Worker this->finishedMakingPaths();
454*c8dee2aaSAndroid Build Coastguard Worker }
onDraw(int loops,SkCanvas *)455*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
456*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
457*c8dee2aaSAndroid Build Coastguard Worker int idx = i & (kPathCnt - 1);
458*c8dee2aaSAndroid Build Coastguard Worker fCopies[idx] = fPaths[idx];
459*c8dee2aaSAndroid Build Coastguard Worker }
460*c8dee2aaSAndroid Build Coastguard Worker }
461*c8dee2aaSAndroid Build Coastguard Worker
462*c8dee2aaSAndroid Build Coastguard Worker private:
463*c8dee2aaSAndroid Build Coastguard Worker enum {
464*c8dee2aaSAndroid Build Coastguard Worker // must be a pow 2
465*c8dee2aaSAndroid Build Coastguard Worker kPathCnt = 1 << 5,
466*c8dee2aaSAndroid Build Coastguard Worker };
467*c8dee2aaSAndroid Build Coastguard Worker AutoTArray<SkPath> fPaths;
468*c8dee2aaSAndroid Build Coastguard Worker AutoTArray<SkPath> fCopies;
469*c8dee2aaSAndroid Build Coastguard Worker
470*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = RandomPathBench;
471*c8dee2aaSAndroid Build Coastguard Worker };
472*c8dee2aaSAndroid Build Coastguard Worker
473*c8dee2aaSAndroid Build Coastguard Worker class PathTransformBench : public RandomPathBench {
474*c8dee2aaSAndroid Build Coastguard Worker public:
PathTransformBench(bool inPlace)475*c8dee2aaSAndroid Build Coastguard Worker PathTransformBench(bool inPlace) : fInPlace(inPlace) {}
476*c8dee2aaSAndroid Build Coastguard Worker
477*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()478*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
479*c8dee2aaSAndroid Build Coastguard Worker return fInPlace ? "path_transform_in_place" : "path_transform_copy";
480*c8dee2aaSAndroid Build Coastguard Worker }
481*c8dee2aaSAndroid Build Coastguard Worker
onDelayedSetup()482*c8dee2aaSAndroid Build Coastguard Worker void onDelayedSetup() override {
483*c8dee2aaSAndroid Build Coastguard Worker fMatrix.setScale(5 * SK_Scalar1, 6 * SK_Scalar1);
484*c8dee2aaSAndroid Build Coastguard Worker this->createData(10, 100);
485*c8dee2aaSAndroid Build Coastguard Worker fPaths.reset(kPathCnt);
486*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kPathCnt; ++i) {
487*c8dee2aaSAndroid Build Coastguard Worker this->makePath(&fPaths[i]);
488*c8dee2aaSAndroid Build Coastguard Worker }
489*c8dee2aaSAndroid Build Coastguard Worker this->finishedMakingPaths();
490*c8dee2aaSAndroid Build Coastguard Worker if (!fInPlace) {
491*c8dee2aaSAndroid Build Coastguard Worker fTransformed.reset(kPathCnt);
492*c8dee2aaSAndroid Build Coastguard Worker }
493*c8dee2aaSAndroid Build Coastguard Worker }
494*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas *)495*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
496*c8dee2aaSAndroid Build Coastguard Worker if (fInPlace) {
497*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
498*c8dee2aaSAndroid Build Coastguard Worker fPaths[i & (kPathCnt - 1)].transform(fMatrix);
499*c8dee2aaSAndroid Build Coastguard Worker }
500*c8dee2aaSAndroid Build Coastguard Worker } else {
501*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
502*c8dee2aaSAndroid Build Coastguard Worker int idx = i & (kPathCnt - 1);
503*c8dee2aaSAndroid Build Coastguard Worker fPaths[idx].transform(fMatrix, &fTransformed[idx]);
504*c8dee2aaSAndroid Build Coastguard Worker }
505*c8dee2aaSAndroid Build Coastguard Worker }
506*c8dee2aaSAndroid Build Coastguard Worker }
507*c8dee2aaSAndroid Build Coastguard Worker
508*c8dee2aaSAndroid Build Coastguard Worker private:
509*c8dee2aaSAndroid Build Coastguard Worker enum {
510*c8dee2aaSAndroid Build Coastguard Worker // must be a pow 2
511*c8dee2aaSAndroid Build Coastguard Worker kPathCnt = 1 << 5,
512*c8dee2aaSAndroid Build Coastguard Worker };
513*c8dee2aaSAndroid Build Coastguard Worker AutoTArray<SkPath> fPaths;
514*c8dee2aaSAndroid Build Coastguard Worker AutoTArray<SkPath> fTransformed;
515*c8dee2aaSAndroid Build Coastguard Worker
516*c8dee2aaSAndroid Build Coastguard Worker SkMatrix fMatrix;
517*c8dee2aaSAndroid Build Coastguard Worker bool fInPlace;
518*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = RandomPathBench;
519*c8dee2aaSAndroid Build Coastguard Worker };
520*c8dee2aaSAndroid Build Coastguard Worker
521*c8dee2aaSAndroid Build Coastguard Worker class PathEqualityBench : public RandomPathBench {
522*c8dee2aaSAndroid Build Coastguard Worker public:
PathEqualityBench()523*c8dee2aaSAndroid Build Coastguard Worker PathEqualityBench() { }
524*c8dee2aaSAndroid Build Coastguard Worker
525*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()526*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
527*c8dee2aaSAndroid Build Coastguard Worker return "path_equality_50%";
528*c8dee2aaSAndroid Build Coastguard Worker }
529*c8dee2aaSAndroid Build Coastguard Worker
onDelayedSetup()530*c8dee2aaSAndroid Build Coastguard Worker void onDelayedSetup() override {
531*c8dee2aaSAndroid Build Coastguard Worker fParity = 0;
532*c8dee2aaSAndroid Build Coastguard Worker this->createData(10, 100);
533*c8dee2aaSAndroid Build Coastguard Worker fPaths.reset(kPathCnt);
534*c8dee2aaSAndroid Build Coastguard Worker fCopies.reset(kPathCnt);
535*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kPathCnt; ++i) {
536*c8dee2aaSAndroid Build Coastguard Worker this->makePath(&fPaths[i]);
537*c8dee2aaSAndroid Build Coastguard Worker fCopies[i] = fPaths[i];
538*c8dee2aaSAndroid Build Coastguard Worker }
539*c8dee2aaSAndroid Build Coastguard Worker this->finishedMakingPaths();
540*c8dee2aaSAndroid Build Coastguard Worker }
541*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas *)542*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
543*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
544*c8dee2aaSAndroid Build Coastguard Worker int idx = i & (kPathCnt - 1);
545*c8dee2aaSAndroid Build Coastguard Worker fParity ^= (fPaths[idx] == fCopies[idx & ~0x1]);
546*c8dee2aaSAndroid Build Coastguard Worker }
547*c8dee2aaSAndroid Build Coastguard Worker }
548*c8dee2aaSAndroid Build Coastguard Worker
549*c8dee2aaSAndroid Build Coastguard Worker private:
550*c8dee2aaSAndroid Build Coastguard Worker bool fParity; // attempt to keep compiler from optimizing out the ==
551*c8dee2aaSAndroid Build Coastguard Worker enum {
552*c8dee2aaSAndroid Build Coastguard Worker // must be a pow 2
553*c8dee2aaSAndroid Build Coastguard Worker kPathCnt = 1 << 5,
554*c8dee2aaSAndroid Build Coastguard Worker };
555*c8dee2aaSAndroid Build Coastguard Worker AutoTArray<SkPath> fPaths;
556*c8dee2aaSAndroid Build Coastguard Worker AutoTArray<SkPath> fCopies;
557*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = RandomPathBench;
558*c8dee2aaSAndroid Build Coastguard Worker };
559*c8dee2aaSAndroid Build Coastguard Worker
560*c8dee2aaSAndroid Build Coastguard Worker class SkBench_AddPathTest : public RandomPathBench {
561*c8dee2aaSAndroid Build Coastguard Worker public:
562*c8dee2aaSAndroid Build Coastguard Worker enum AddType {
563*c8dee2aaSAndroid Build Coastguard Worker kAdd_AddType,
564*c8dee2aaSAndroid Build Coastguard Worker kAddTrans_AddType,
565*c8dee2aaSAndroid Build Coastguard Worker kAddMatrix_AddType,
566*c8dee2aaSAndroid Build Coastguard Worker kReverseAdd_AddType,
567*c8dee2aaSAndroid Build Coastguard Worker kReversePathTo_AddType,
568*c8dee2aaSAndroid Build Coastguard Worker };
569*c8dee2aaSAndroid Build Coastguard Worker
SkBench_AddPathTest(AddType type)570*c8dee2aaSAndroid Build Coastguard Worker SkBench_AddPathTest(AddType type) : fType(type) {
571*c8dee2aaSAndroid Build Coastguard Worker fMatrix.setRotate(60 * SK_Scalar1);
572*c8dee2aaSAndroid Build Coastguard Worker }
573*c8dee2aaSAndroid Build Coastguard Worker
574*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()575*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
576*c8dee2aaSAndroid Build Coastguard Worker switch (fType) {
577*c8dee2aaSAndroid Build Coastguard Worker case kAdd_AddType:
578*c8dee2aaSAndroid Build Coastguard Worker return "path_add_path";
579*c8dee2aaSAndroid Build Coastguard Worker case kAddTrans_AddType:
580*c8dee2aaSAndroid Build Coastguard Worker return "path_add_path_trans";
581*c8dee2aaSAndroid Build Coastguard Worker case kAddMatrix_AddType:
582*c8dee2aaSAndroid Build Coastguard Worker return "path_add_path_matrix";
583*c8dee2aaSAndroid Build Coastguard Worker case kReverseAdd_AddType:
584*c8dee2aaSAndroid Build Coastguard Worker return "path_reverse_add_path";
585*c8dee2aaSAndroid Build Coastguard Worker case kReversePathTo_AddType:
586*c8dee2aaSAndroid Build Coastguard Worker return "path_reverse_path_to";
587*c8dee2aaSAndroid Build Coastguard Worker default:
588*c8dee2aaSAndroid Build Coastguard Worker SkDEBUGFAIL("Bad add type");
589*c8dee2aaSAndroid Build Coastguard Worker return "";
590*c8dee2aaSAndroid Build Coastguard Worker }
591*c8dee2aaSAndroid Build Coastguard Worker }
592*c8dee2aaSAndroid Build Coastguard Worker
onDelayedSetup()593*c8dee2aaSAndroid Build Coastguard Worker void onDelayedSetup() override {
594*c8dee2aaSAndroid Build Coastguard Worker // reversePathTo assumes a single contour path.
595*c8dee2aaSAndroid Build Coastguard Worker bool allowMoves = kReversePathTo_AddType != fType;
596*c8dee2aaSAndroid Build Coastguard Worker this->createData(10, 100, allowMoves);
597*c8dee2aaSAndroid Build Coastguard Worker fPaths0.reset(kPathCnt);
598*c8dee2aaSAndroid Build Coastguard Worker fPaths1.reset(kPathCnt);
599*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kPathCnt; ++i) {
600*c8dee2aaSAndroid Build Coastguard Worker this->makePath(&fPaths0[i]);
601*c8dee2aaSAndroid Build Coastguard Worker this->makePath(&fPaths1[i]);
602*c8dee2aaSAndroid Build Coastguard Worker }
603*c8dee2aaSAndroid Build Coastguard Worker this->finishedMakingPaths();
604*c8dee2aaSAndroid Build Coastguard Worker }
605*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas *)606*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
607*c8dee2aaSAndroid Build Coastguard Worker switch (fType) {
608*c8dee2aaSAndroid Build Coastguard Worker case kAdd_AddType:
609*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
610*c8dee2aaSAndroid Build Coastguard Worker int idx = i & (kPathCnt - 1);
611*c8dee2aaSAndroid Build Coastguard Worker SkPath result = fPaths0[idx];
612*c8dee2aaSAndroid Build Coastguard Worker result.addPath(fPaths1[idx]);
613*c8dee2aaSAndroid Build Coastguard Worker }
614*c8dee2aaSAndroid Build Coastguard Worker break;
615*c8dee2aaSAndroid Build Coastguard Worker case kAddTrans_AddType:
616*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
617*c8dee2aaSAndroid Build Coastguard Worker int idx = i & (kPathCnt - 1);
618*c8dee2aaSAndroid Build Coastguard Worker SkPath result = fPaths0[idx];
619*c8dee2aaSAndroid Build Coastguard Worker result.addPath(fPaths1[idx], 2 * SK_Scalar1, 5 * SK_Scalar1);
620*c8dee2aaSAndroid Build Coastguard Worker }
621*c8dee2aaSAndroid Build Coastguard Worker break;
622*c8dee2aaSAndroid Build Coastguard Worker case kAddMatrix_AddType:
623*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
624*c8dee2aaSAndroid Build Coastguard Worker int idx = i & (kPathCnt - 1);
625*c8dee2aaSAndroid Build Coastguard Worker SkPath result = fPaths0[idx];
626*c8dee2aaSAndroid Build Coastguard Worker result.addPath(fPaths1[idx], fMatrix);
627*c8dee2aaSAndroid Build Coastguard Worker }
628*c8dee2aaSAndroid Build Coastguard Worker break;
629*c8dee2aaSAndroid Build Coastguard Worker case kReverseAdd_AddType:
630*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
631*c8dee2aaSAndroid Build Coastguard Worker int idx = i & (kPathCnt - 1);
632*c8dee2aaSAndroid Build Coastguard Worker SkPath result = fPaths0[idx];
633*c8dee2aaSAndroid Build Coastguard Worker result.reverseAddPath(fPaths1[idx]);
634*c8dee2aaSAndroid Build Coastguard Worker }
635*c8dee2aaSAndroid Build Coastguard Worker break;
636*c8dee2aaSAndroid Build Coastguard Worker case kReversePathTo_AddType:
637*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
638*c8dee2aaSAndroid Build Coastguard Worker int idx = i & (kPathCnt - 1);
639*c8dee2aaSAndroid Build Coastguard Worker SkPath result = fPaths0[idx];
640*c8dee2aaSAndroid Build Coastguard Worker result.reversePathTo(fPaths1[idx]);
641*c8dee2aaSAndroid Build Coastguard Worker }
642*c8dee2aaSAndroid Build Coastguard Worker break;
643*c8dee2aaSAndroid Build Coastguard Worker }
644*c8dee2aaSAndroid Build Coastguard Worker }
645*c8dee2aaSAndroid Build Coastguard Worker
646*c8dee2aaSAndroid Build Coastguard Worker private:
647*c8dee2aaSAndroid Build Coastguard Worker AddType fType; // or reverseAddPath
648*c8dee2aaSAndroid Build Coastguard Worker enum {
649*c8dee2aaSAndroid Build Coastguard Worker // must be a pow 2
650*c8dee2aaSAndroid Build Coastguard Worker kPathCnt = 1 << 5,
651*c8dee2aaSAndroid Build Coastguard Worker };
652*c8dee2aaSAndroid Build Coastguard Worker AutoTArray<SkPath> fPaths0;
653*c8dee2aaSAndroid Build Coastguard Worker AutoTArray<SkPath> fPaths1;
654*c8dee2aaSAndroid Build Coastguard Worker SkMatrix fMatrix;
655*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = RandomPathBench;
656*c8dee2aaSAndroid Build Coastguard Worker };
657*c8dee2aaSAndroid Build Coastguard Worker
658*c8dee2aaSAndroid Build Coastguard Worker
659*c8dee2aaSAndroid Build Coastguard Worker class CirclesBench : public Benchmark {
660*c8dee2aaSAndroid Build Coastguard Worker protected:
661*c8dee2aaSAndroid Build Coastguard Worker SkString fName;
662*c8dee2aaSAndroid Build Coastguard Worker Flags fFlags;
663*c8dee2aaSAndroid Build Coastguard Worker
664*c8dee2aaSAndroid Build Coastguard Worker public:
CirclesBench(Flags flags)665*c8dee2aaSAndroid Build Coastguard Worker CirclesBench(Flags flags) : fFlags(flags) {
666*c8dee2aaSAndroid Build Coastguard Worker fName.printf("circles_%s", fFlags & kStroke_Flag ? "stroke" : "fill");
667*c8dee2aaSAndroid Build Coastguard Worker }
668*c8dee2aaSAndroid Build Coastguard Worker
669*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()670*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
671*c8dee2aaSAndroid Build Coastguard Worker return fName.c_str();
672*c8dee2aaSAndroid Build Coastguard Worker }
673*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas * canvas)674*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas* canvas) override {
675*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
676*c8dee2aaSAndroid Build Coastguard Worker
677*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorBLACK);
678*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
679*c8dee2aaSAndroid Build Coastguard Worker if (fFlags & kStroke_Flag) {
680*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kStroke_Style);
681*c8dee2aaSAndroid Build Coastguard Worker }
682*c8dee2aaSAndroid Build Coastguard Worker
683*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand;
684*c8dee2aaSAndroid Build Coastguard Worker
685*c8dee2aaSAndroid Build Coastguard Worker SkRect r;
686*c8dee2aaSAndroid Build Coastguard Worker
687*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
688*c8dee2aaSAndroid Build Coastguard Worker SkScalar radius = rand.nextUScalar1() * 3;
689*c8dee2aaSAndroid Build Coastguard Worker r.fLeft = rand.nextUScalar1() * 300;
690*c8dee2aaSAndroid Build Coastguard Worker r.fTop = rand.nextUScalar1() * 300;
691*c8dee2aaSAndroid Build Coastguard Worker r.fRight = r.fLeft + 2 * radius;
692*c8dee2aaSAndroid Build Coastguard Worker r.fBottom = r.fTop + 2 * radius;
693*c8dee2aaSAndroid Build Coastguard Worker
694*c8dee2aaSAndroid Build Coastguard Worker if (fFlags & kStroke_Flag) {
695*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(rand.nextUScalar1() * 5.0f);
696*c8dee2aaSAndroid Build Coastguard Worker }
697*c8dee2aaSAndroid Build Coastguard Worker
698*c8dee2aaSAndroid Build Coastguard Worker SkPath temp;
699*c8dee2aaSAndroid Build Coastguard Worker
700*c8dee2aaSAndroid Build Coastguard Worker // mimic how Chrome does circles
701*c8dee2aaSAndroid Build Coastguard Worker temp.arcTo(r, 0, 0, false);
702*c8dee2aaSAndroid Build Coastguard Worker temp.addOval(r, SkPathDirection::kCCW);
703*c8dee2aaSAndroid Build Coastguard Worker temp.arcTo(r, 360, 0, true);
704*c8dee2aaSAndroid Build Coastguard Worker temp.close();
705*c8dee2aaSAndroid Build Coastguard Worker
706*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(temp, paint);
707*c8dee2aaSAndroid Build Coastguard Worker }
708*c8dee2aaSAndroid Build Coastguard Worker }
709*c8dee2aaSAndroid Build Coastguard Worker
710*c8dee2aaSAndroid Build Coastguard Worker private:
711*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark;
712*c8dee2aaSAndroid Build Coastguard Worker };
713*c8dee2aaSAndroid Build Coastguard Worker
714*c8dee2aaSAndroid Build Coastguard Worker
715*c8dee2aaSAndroid Build Coastguard Worker // Chrome creates its own round rects with each corner possibly being different.
716*c8dee2aaSAndroid Build Coastguard Worker // In its "zero radius" incarnation it creates degenerate round rects.
717*c8dee2aaSAndroid Build Coastguard Worker // Note: PathTest::test_arb_round_rect_is_convex and
718*c8dee2aaSAndroid Build Coastguard Worker // test_arb_zero_rad_round_rect_is_rect perform almost exactly
719*c8dee2aaSAndroid Build Coastguard Worker // the same test (but with no drawing)
720*c8dee2aaSAndroid Build Coastguard Worker class ArbRoundRectBench : public Benchmark {
721*c8dee2aaSAndroid Build Coastguard Worker protected:
722*c8dee2aaSAndroid Build Coastguard Worker SkString fName;
723*c8dee2aaSAndroid Build Coastguard Worker
724*c8dee2aaSAndroid Build Coastguard Worker public:
ArbRoundRectBench(bool zeroRad)725*c8dee2aaSAndroid Build Coastguard Worker ArbRoundRectBench(bool zeroRad) : fZeroRad(zeroRad) {
726*c8dee2aaSAndroid Build Coastguard Worker if (zeroRad) {
727*c8dee2aaSAndroid Build Coastguard Worker fName.printf("zeroradroundrect");
728*c8dee2aaSAndroid Build Coastguard Worker } else {
729*c8dee2aaSAndroid Build Coastguard Worker fName.printf("arbroundrect");
730*c8dee2aaSAndroid Build Coastguard Worker }
731*c8dee2aaSAndroid Build Coastguard Worker }
732*c8dee2aaSAndroid Build Coastguard Worker
733*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()734*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
735*c8dee2aaSAndroid Build Coastguard Worker return fName.c_str();
736*c8dee2aaSAndroid Build Coastguard Worker }
737*c8dee2aaSAndroid Build Coastguard Worker
add_corner_arc(SkPath * path,const SkRect & rect,SkScalar xIn,SkScalar yIn,int startAngle)738*c8dee2aaSAndroid Build Coastguard Worker static void add_corner_arc(SkPath* path, const SkRect& rect,
739*c8dee2aaSAndroid Build Coastguard Worker SkScalar xIn, SkScalar yIn,
740*c8dee2aaSAndroid Build Coastguard Worker int startAngle)
741*c8dee2aaSAndroid Build Coastguard Worker {
742*c8dee2aaSAndroid Build Coastguard Worker
743*c8dee2aaSAndroid Build Coastguard Worker SkScalar rx = std::min(rect.width(), xIn);
744*c8dee2aaSAndroid Build Coastguard Worker SkScalar ry = std::min(rect.height(), yIn);
745*c8dee2aaSAndroid Build Coastguard Worker
746*c8dee2aaSAndroid Build Coastguard Worker SkRect arcRect;
747*c8dee2aaSAndroid Build Coastguard Worker arcRect.setLTRB(-rx, -ry, rx, ry);
748*c8dee2aaSAndroid Build Coastguard Worker switch (startAngle) {
749*c8dee2aaSAndroid Build Coastguard Worker case 0:
750*c8dee2aaSAndroid Build Coastguard Worker arcRect.offset(rect.fRight - arcRect.fRight, rect.fBottom - arcRect.fBottom);
751*c8dee2aaSAndroid Build Coastguard Worker break;
752*c8dee2aaSAndroid Build Coastguard Worker case 90:
753*c8dee2aaSAndroid Build Coastguard Worker arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fBottom - arcRect.fBottom);
754*c8dee2aaSAndroid Build Coastguard Worker break;
755*c8dee2aaSAndroid Build Coastguard Worker case 180:
756*c8dee2aaSAndroid Build Coastguard Worker arcRect.offset(rect.fLeft - arcRect.fLeft, rect.fTop - arcRect.fTop);
757*c8dee2aaSAndroid Build Coastguard Worker break;
758*c8dee2aaSAndroid Build Coastguard Worker case 270:
759*c8dee2aaSAndroid Build Coastguard Worker arcRect.offset(rect.fRight - arcRect.fRight, rect.fTop - arcRect.fTop);
760*c8dee2aaSAndroid Build Coastguard Worker break;
761*c8dee2aaSAndroid Build Coastguard Worker default:
762*c8dee2aaSAndroid Build Coastguard Worker break;
763*c8dee2aaSAndroid Build Coastguard Worker }
764*c8dee2aaSAndroid Build Coastguard Worker
765*c8dee2aaSAndroid Build Coastguard Worker path->arcTo(arcRect, SkIntToScalar(startAngle), SkIntToScalar(90), false);
766*c8dee2aaSAndroid Build Coastguard Worker }
767*c8dee2aaSAndroid Build Coastguard Worker
make_arb_round_rect(SkPath * path,const SkRect & r,SkScalar xCorner,SkScalar yCorner)768*c8dee2aaSAndroid Build Coastguard Worker static void make_arb_round_rect(SkPath* path, const SkRect& r,
769*c8dee2aaSAndroid Build Coastguard Worker SkScalar xCorner, SkScalar yCorner) {
770*c8dee2aaSAndroid Build Coastguard Worker // we are lazy here and use the same x & y for each corner
771*c8dee2aaSAndroid Build Coastguard Worker add_corner_arc(path, r, xCorner, yCorner, 270);
772*c8dee2aaSAndroid Build Coastguard Worker add_corner_arc(path, r, xCorner, yCorner, 0);
773*c8dee2aaSAndroid Build Coastguard Worker add_corner_arc(path, r, xCorner, yCorner, 90);
774*c8dee2aaSAndroid Build Coastguard Worker add_corner_arc(path, r, xCorner, yCorner, 180);
775*c8dee2aaSAndroid Build Coastguard Worker path->close();
776*c8dee2aaSAndroid Build Coastguard Worker
777*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(path->isConvex());
778*c8dee2aaSAndroid Build Coastguard Worker }
779*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas * canvas)780*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas* canvas) override {
781*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand;
782*c8dee2aaSAndroid Build Coastguard Worker SkRect r;
783*c8dee2aaSAndroid Build Coastguard Worker
784*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
785*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
786*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(0xff000000 | rand.nextU());
787*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
788*c8dee2aaSAndroid Build Coastguard Worker
789*c8dee2aaSAndroid Build Coastguard Worker SkScalar size = rand.nextUScalar1() * 30;
790*c8dee2aaSAndroid Build Coastguard Worker if (size < SK_Scalar1) {
791*c8dee2aaSAndroid Build Coastguard Worker continue;
792*c8dee2aaSAndroid Build Coastguard Worker }
793*c8dee2aaSAndroid Build Coastguard Worker r.fLeft = rand.nextUScalar1() * 300;
794*c8dee2aaSAndroid Build Coastguard Worker r.fTop = rand.nextUScalar1() * 300;
795*c8dee2aaSAndroid Build Coastguard Worker r.fRight = r.fLeft + 2 * size;
796*c8dee2aaSAndroid Build Coastguard Worker r.fBottom = r.fTop + 2 * size;
797*c8dee2aaSAndroid Build Coastguard Worker
798*c8dee2aaSAndroid Build Coastguard Worker SkPath temp;
799*c8dee2aaSAndroid Build Coastguard Worker
800*c8dee2aaSAndroid Build Coastguard Worker if (fZeroRad) {
801*c8dee2aaSAndroid Build Coastguard Worker make_arb_round_rect(&temp, r, 0, 0);
802*c8dee2aaSAndroid Build Coastguard Worker
803*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(temp.isRect(nullptr));
804*c8dee2aaSAndroid Build Coastguard Worker } else {
805*c8dee2aaSAndroid Build Coastguard Worker make_arb_round_rect(&temp, r, r.width() / 10, r.height() / 15);
806*c8dee2aaSAndroid Build Coastguard Worker }
807*c8dee2aaSAndroid Build Coastguard Worker
808*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(temp, paint);
809*c8dee2aaSAndroid Build Coastguard Worker }
810*c8dee2aaSAndroid Build Coastguard Worker }
811*c8dee2aaSAndroid Build Coastguard Worker
812*c8dee2aaSAndroid Build Coastguard Worker private:
813*c8dee2aaSAndroid Build Coastguard Worker bool fZeroRad; // should 0 radius rounds rects be tested?
814*c8dee2aaSAndroid Build Coastguard Worker
815*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark;
816*c8dee2aaSAndroid Build Coastguard Worker };
817*c8dee2aaSAndroid Build Coastguard Worker
818*c8dee2aaSAndroid Build Coastguard Worker class ConservativelyContainsBench : public Benchmark {
819*c8dee2aaSAndroid Build Coastguard Worker public:
820*c8dee2aaSAndroid Build Coastguard Worker enum Type {
821*c8dee2aaSAndroid Build Coastguard Worker kRect_Type,
822*c8dee2aaSAndroid Build Coastguard Worker kRoundRect_Type,
823*c8dee2aaSAndroid Build Coastguard Worker kOval_Type,
824*c8dee2aaSAndroid Build Coastguard Worker };
825*c8dee2aaSAndroid Build Coastguard Worker
ConservativelyContainsBench(Type type)826*c8dee2aaSAndroid Build Coastguard Worker ConservativelyContainsBench(Type type) {
827*c8dee2aaSAndroid Build Coastguard Worker fParity = false;
828*c8dee2aaSAndroid Build Coastguard Worker fName = "conservatively_contains_";
829*c8dee2aaSAndroid Build Coastguard Worker switch (type) {
830*c8dee2aaSAndroid Build Coastguard Worker case kRect_Type:
831*c8dee2aaSAndroid Build Coastguard Worker fName.append("rect");
832*c8dee2aaSAndroid Build Coastguard Worker fPath.addRect(kBaseRect);
833*c8dee2aaSAndroid Build Coastguard Worker break;
834*c8dee2aaSAndroid Build Coastguard Worker case kRoundRect_Type:
835*c8dee2aaSAndroid Build Coastguard Worker fName.append("round_rect");
836*c8dee2aaSAndroid Build Coastguard Worker fPath.addRoundRect(kBaseRect, kRRRadii[0], kRRRadii[1]);
837*c8dee2aaSAndroid Build Coastguard Worker break;
838*c8dee2aaSAndroid Build Coastguard Worker case kOval_Type:
839*c8dee2aaSAndroid Build Coastguard Worker fName.append("oval");
840*c8dee2aaSAndroid Build Coastguard Worker fPath.addOval(kBaseRect);
841*c8dee2aaSAndroid Build Coastguard Worker break;
842*c8dee2aaSAndroid Build Coastguard Worker }
843*c8dee2aaSAndroid Build Coastguard Worker }
844*c8dee2aaSAndroid Build Coastguard Worker
isSuitableFor(Backend backend)845*c8dee2aaSAndroid Build Coastguard Worker bool isSuitableFor(Backend backend) override {
846*c8dee2aaSAndroid Build Coastguard Worker return backend == Backend::kNonRendering;
847*c8dee2aaSAndroid Build Coastguard Worker }
848*c8dee2aaSAndroid Build Coastguard Worker
849*c8dee2aaSAndroid Build Coastguard Worker private:
onGetName()850*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
851*c8dee2aaSAndroid Build Coastguard Worker return fName.c_str();
852*c8dee2aaSAndroid Build Coastguard Worker }
853*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas *)854*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
855*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
856*c8dee2aaSAndroid Build Coastguard Worker const SkRect& rect = fQueryRects[i % kQueryRectCnt];
857*c8dee2aaSAndroid Build Coastguard Worker fParity = fParity != fPath.conservativelyContainsRect(rect);
858*c8dee2aaSAndroid Build Coastguard Worker }
859*c8dee2aaSAndroid Build Coastguard Worker }
860*c8dee2aaSAndroid Build Coastguard Worker
onDelayedSetup()861*c8dee2aaSAndroid Build Coastguard Worker void onDelayedSetup() override {
862*c8dee2aaSAndroid Build Coastguard Worker fQueryRects.resize(kQueryRectCnt);
863*c8dee2aaSAndroid Build Coastguard Worker
864*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand;
865*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < kQueryRectCnt; ++i) {
866*c8dee2aaSAndroid Build Coastguard Worker SkSize size;
867*c8dee2aaSAndroid Build Coastguard Worker SkPoint xy;
868*c8dee2aaSAndroid Build Coastguard Worker size.fWidth = rand.nextRangeScalar(kQueryMin.fWidth, kQueryMax.fWidth);
869*c8dee2aaSAndroid Build Coastguard Worker size.fHeight = rand.nextRangeScalar(kQueryMin.fHeight, kQueryMax.fHeight);
870*c8dee2aaSAndroid Build Coastguard Worker xy.fX = rand.nextRangeScalar(kBounds.fLeft, kBounds.fRight - size.fWidth);
871*c8dee2aaSAndroid Build Coastguard Worker xy.fY = rand.nextRangeScalar(kBounds.fTop, kBounds.fBottom - size.fHeight);
872*c8dee2aaSAndroid Build Coastguard Worker
873*c8dee2aaSAndroid Build Coastguard Worker fQueryRects[i] = SkRect::MakeXYWH(xy.fX, xy.fY, size.fWidth, size.fHeight);
874*c8dee2aaSAndroid Build Coastguard Worker }
875*c8dee2aaSAndroid Build Coastguard Worker }
876*c8dee2aaSAndroid Build Coastguard Worker
877*c8dee2aaSAndroid Build Coastguard Worker enum {
878*c8dee2aaSAndroid Build Coastguard Worker kQueryRectCnt = 400,
879*c8dee2aaSAndroid Build Coastguard Worker };
880*c8dee2aaSAndroid Build Coastguard Worker static const SkRect kBounds; // bounds for all random query rects
881*c8dee2aaSAndroid Build Coastguard Worker static const SkSize kQueryMin; // minimum query rect size, should be <= kQueryMax
882*c8dee2aaSAndroid Build Coastguard Worker static const SkSize kQueryMax; // max query rect size, should < kBounds
883*c8dee2aaSAndroid Build Coastguard Worker static const SkRect kBaseRect; // rect that is used to construct the path
884*c8dee2aaSAndroid Build Coastguard Worker static const SkScalar kRRRadii[2]; // x and y radii for round rect
885*c8dee2aaSAndroid Build Coastguard Worker
886*c8dee2aaSAndroid Build Coastguard Worker SkString fName;
887*c8dee2aaSAndroid Build Coastguard Worker SkPath fPath;
888*c8dee2aaSAndroid Build Coastguard Worker bool fParity;
889*c8dee2aaSAndroid Build Coastguard Worker SkTDArray<SkRect> fQueryRects;
890*c8dee2aaSAndroid Build Coastguard Worker
891*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark;
892*c8dee2aaSAndroid Build Coastguard Worker };
893*c8dee2aaSAndroid Build Coastguard Worker
894*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
895*c8dee2aaSAndroid Build Coastguard Worker
896*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkGeometry.h"
897*c8dee2aaSAndroid Build Coastguard Worker
898*c8dee2aaSAndroid Build Coastguard Worker class ConicBench_Chop : public Benchmark {
899*c8dee2aaSAndroid Build Coastguard Worker protected:
900*c8dee2aaSAndroid Build Coastguard Worker SkConic fRQ, fDst[2];
901*c8dee2aaSAndroid Build Coastguard Worker SkString fName;
902*c8dee2aaSAndroid Build Coastguard Worker public:
ConicBench_Chop()903*c8dee2aaSAndroid Build Coastguard Worker ConicBench_Chop() : fName("conic-chop") {
904*c8dee2aaSAndroid Build Coastguard Worker fRQ.fPts[0].set(0, 0);
905*c8dee2aaSAndroid Build Coastguard Worker fRQ.fPts[1].set(100, 0);
906*c8dee2aaSAndroid Build Coastguard Worker fRQ.fPts[2].set(100, 100);
907*c8dee2aaSAndroid Build Coastguard Worker fRQ.fW = SkScalarCos(SK_ScalarPI/4);
908*c8dee2aaSAndroid Build Coastguard Worker }
909*c8dee2aaSAndroid Build Coastguard Worker
isSuitableFor(Backend backend)910*c8dee2aaSAndroid Build Coastguard Worker bool isSuitableFor(Backend backend) override {
911*c8dee2aaSAndroid Build Coastguard Worker return backend == Backend::kNonRendering;
912*c8dee2aaSAndroid Build Coastguard Worker }
913*c8dee2aaSAndroid Build Coastguard Worker
914*c8dee2aaSAndroid Build Coastguard Worker private:
onGetName()915*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override { return fName.c_str(); }
916*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas *)917*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
918*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
919*c8dee2aaSAndroid Build Coastguard Worker fRQ.chop(fDst);
920*c8dee2aaSAndroid Build Coastguard Worker }
921*c8dee2aaSAndroid Build Coastguard Worker }
922*c8dee2aaSAndroid Build Coastguard Worker
923*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark;
924*c8dee2aaSAndroid Build Coastguard Worker };
925*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConicBench_Chop; )
926*c8dee2aaSAndroid Build Coastguard Worker
927*c8dee2aaSAndroid Build Coastguard Worker class ConicBench_EvalPos : public ConicBench_Chop {
928*c8dee2aaSAndroid Build Coastguard Worker const bool fUseV2;
929*c8dee2aaSAndroid Build Coastguard Worker public:
ConicBench_EvalPos(bool useV2)930*c8dee2aaSAndroid Build Coastguard Worker ConicBench_EvalPos(bool useV2) : fUseV2(useV2) {
931*c8dee2aaSAndroid Build Coastguard Worker fName.printf("conic-eval-pos%d", useV2);
932*c8dee2aaSAndroid Build Coastguard Worker }
onDraw(int loops,SkCanvas *)933*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
934*c8dee2aaSAndroid Build Coastguard Worker if (fUseV2) {
935*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
936*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < 1000; ++j) {
937*c8dee2aaSAndroid Build Coastguard Worker fDst[0].fPts[0] = fRQ.evalAt(0.4f);
938*c8dee2aaSAndroid Build Coastguard Worker }
939*c8dee2aaSAndroid Build Coastguard Worker }
940*c8dee2aaSAndroid Build Coastguard Worker } else {
941*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
942*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < 1000; ++j) {
943*c8dee2aaSAndroid Build Coastguard Worker fRQ.evalAt(0.4f, &fDst[0].fPts[0], nullptr);
944*c8dee2aaSAndroid Build Coastguard Worker }
945*c8dee2aaSAndroid Build Coastguard Worker }
946*c8dee2aaSAndroid Build Coastguard Worker }
947*c8dee2aaSAndroid Build Coastguard Worker }
948*c8dee2aaSAndroid Build Coastguard Worker };
949*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConicBench_EvalPos(false); )
950*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConicBench_EvalPos(true); )
951*c8dee2aaSAndroid Build Coastguard Worker
952*c8dee2aaSAndroid Build Coastguard Worker class ConicBench_EvalTan : public ConicBench_Chop {
953*c8dee2aaSAndroid Build Coastguard Worker const bool fUseV2;
954*c8dee2aaSAndroid Build Coastguard Worker public:
ConicBench_EvalTan(bool useV2)955*c8dee2aaSAndroid Build Coastguard Worker ConicBench_EvalTan(bool useV2) : fUseV2(useV2) {
956*c8dee2aaSAndroid Build Coastguard Worker fName.printf("conic-eval-tan%d", useV2);
957*c8dee2aaSAndroid Build Coastguard Worker }
onDraw(int loops,SkCanvas *)958*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
959*c8dee2aaSAndroid Build Coastguard Worker if (fUseV2) {
960*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
961*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < 1000; ++j) {
962*c8dee2aaSAndroid Build Coastguard Worker fDst[0].fPts[0] = fRQ.evalTangentAt(0.4f);
963*c8dee2aaSAndroid Build Coastguard Worker }
964*c8dee2aaSAndroid Build Coastguard Worker }
965*c8dee2aaSAndroid Build Coastguard Worker } else {
966*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
967*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < 1000; ++j) {
968*c8dee2aaSAndroid Build Coastguard Worker fRQ.evalAt(0.4f, nullptr, &fDst[0].fPts[0]);
969*c8dee2aaSAndroid Build Coastguard Worker }
970*c8dee2aaSAndroid Build Coastguard Worker }
971*c8dee2aaSAndroid Build Coastguard Worker }
972*c8dee2aaSAndroid Build Coastguard Worker }
973*c8dee2aaSAndroid Build Coastguard Worker };
974*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConicBench_EvalTan(false); )
975*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConicBench_EvalTan(true); )
976*c8dee2aaSAndroid Build Coastguard Worker
977*c8dee2aaSAndroid Build Coastguard Worker class ConicBench_TinyError : public Benchmark {
978*c8dee2aaSAndroid Build Coastguard Worker protected:
979*c8dee2aaSAndroid Build Coastguard Worker SkString fName;
980*c8dee2aaSAndroid Build Coastguard Worker
981*c8dee2aaSAndroid Build Coastguard Worker public:
ConicBench_TinyError()982*c8dee2aaSAndroid Build Coastguard Worker ConicBench_TinyError() : fName("conic-tinyerror") {}
983*c8dee2aaSAndroid Build Coastguard Worker
984*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()985*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override { return fName.c_str(); }
986*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas *)987*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
988*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
989*c8dee2aaSAndroid Build Coastguard Worker paint.setColor(SK_ColorBLACK);
990*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
991*c8dee2aaSAndroid Build Coastguard Worker paint.setStyle(SkPaint::kStroke_Style);
992*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(2);
993*c8dee2aaSAndroid Build Coastguard Worker
994*c8dee2aaSAndroid Build Coastguard Worker SkPath path;
995*c8dee2aaSAndroid Build Coastguard Worker path.moveTo(-100, 1);
996*c8dee2aaSAndroid Build Coastguard Worker path.cubicTo(-101, 1, -118, -47, -138, -44);
997*c8dee2aaSAndroid Build Coastguard Worker
998*c8dee2aaSAndroid Build Coastguard Worker // The large y scale factor produces a tiny error threshold.
999*c8dee2aaSAndroid Build Coastguard Worker const SkMatrix mtx = SkMatrix::MakeAll(3.07294035f, 0.833333373f, 361.111115f, 0.0f,
1000*c8dee2aaSAndroid Build Coastguard Worker 6222222.5f, 28333.334f, 0.0f, 0.0f, 1.0f);
1001*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
1002*c8dee2aaSAndroid Build Coastguard Worker SkPath dst;
1003*c8dee2aaSAndroid Build Coastguard Worker skpathutils::FillPathWithPaint(path, paint, &dst, nullptr,
1004*c8dee2aaSAndroid Build Coastguard Worker SkMatrixPriv::ComputeResScaleForStroking(mtx));
1005*c8dee2aaSAndroid Build Coastguard Worker }
1006*c8dee2aaSAndroid Build Coastguard Worker }
1007*c8dee2aaSAndroid Build Coastguard Worker
1008*c8dee2aaSAndroid Build Coastguard Worker private:
1009*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark;
1010*c8dee2aaSAndroid Build Coastguard Worker };
DEF_BENCH(return new ConicBench_TinyError;)1011*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConicBench_TinyError; )
1012*c8dee2aaSAndroid Build Coastguard Worker
1013*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
1014*c8dee2aaSAndroid Build Coastguard Worker
1015*c8dee2aaSAndroid Build Coastguard Worker static void rand_conic(SkConic* conic, SkRandom& rand) {
1016*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < 3; ++i) {
1017*c8dee2aaSAndroid Build Coastguard Worker conic->fPts[i].set(rand.nextUScalar1() * 100, rand.nextUScalar1() * 100);
1018*c8dee2aaSAndroid Build Coastguard Worker }
1019*c8dee2aaSAndroid Build Coastguard Worker if (rand.nextUScalar1() > 0.5f) {
1020*c8dee2aaSAndroid Build Coastguard Worker conic->fW = rand.nextUScalar1();
1021*c8dee2aaSAndroid Build Coastguard Worker } else {
1022*c8dee2aaSAndroid Build Coastguard Worker conic->fW = 1 + rand.nextUScalar1() * 4;
1023*c8dee2aaSAndroid Build Coastguard Worker }
1024*c8dee2aaSAndroid Build Coastguard Worker }
1025*c8dee2aaSAndroid Build Coastguard Worker
1026*c8dee2aaSAndroid Build Coastguard Worker class ConicBench : public Benchmark {
1027*c8dee2aaSAndroid Build Coastguard Worker public:
ConicBench()1028*c8dee2aaSAndroid Build Coastguard Worker ConicBench() {
1029*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand;
1030*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < CONICS; ++i) {
1031*c8dee2aaSAndroid Build Coastguard Worker rand_conic(&fConics[i], rand);
1032*c8dee2aaSAndroid Build Coastguard Worker }
1033*c8dee2aaSAndroid Build Coastguard Worker }
1034*c8dee2aaSAndroid Build Coastguard Worker
isSuitableFor(Backend backend)1035*c8dee2aaSAndroid Build Coastguard Worker bool isSuitableFor(Backend backend) override {
1036*c8dee2aaSAndroid Build Coastguard Worker return backend == Backend::kNonRendering;
1037*c8dee2aaSAndroid Build Coastguard Worker }
1038*c8dee2aaSAndroid Build Coastguard Worker
1039*c8dee2aaSAndroid Build Coastguard Worker protected:
1040*c8dee2aaSAndroid Build Coastguard Worker enum {
1041*c8dee2aaSAndroid Build Coastguard Worker CONICS = 100
1042*c8dee2aaSAndroid Build Coastguard Worker };
1043*c8dee2aaSAndroid Build Coastguard Worker SkConic fConics[CONICS];
1044*c8dee2aaSAndroid Build Coastguard Worker
1045*c8dee2aaSAndroid Build Coastguard Worker private:
1046*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark;
1047*c8dee2aaSAndroid Build Coastguard Worker };
1048*c8dee2aaSAndroid Build Coastguard Worker
1049*c8dee2aaSAndroid Build Coastguard Worker class ConicBench_ComputeError : public ConicBench {
1050*c8dee2aaSAndroid Build Coastguard Worker public:
ConicBench_ComputeError()1051*c8dee2aaSAndroid Build Coastguard Worker ConicBench_ComputeError() {}
1052*c8dee2aaSAndroid Build Coastguard Worker
1053*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()1054*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
1055*c8dee2aaSAndroid Build Coastguard Worker return "conic-compute-error";
1056*c8dee2aaSAndroid Build Coastguard Worker }
1057*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas *)1058*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
1059*c8dee2aaSAndroid Build Coastguard Worker SkVector err;
1060*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
1061*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < CONICS; ++j) {
1062*c8dee2aaSAndroid Build Coastguard Worker fConics[j].computeAsQuadError(&err);
1063*c8dee2aaSAndroid Build Coastguard Worker }
1064*c8dee2aaSAndroid Build Coastguard Worker }
1065*c8dee2aaSAndroid Build Coastguard Worker }
1066*c8dee2aaSAndroid Build Coastguard Worker
1067*c8dee2aaSAndroid Build Coastguard Worker private:
1068*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = ConicBench;
1069*c8dee2aaSAndroid Build Coastguard Worker };
1070*c8dee2aaSAndroid Build Coastguard Worker
1071*c8dee2aaSAndroid Build Coastguard Worker class ConicBench_asQuadTol : public ConicBench {
1072*c8dee2aaSAndroid Build Coastguard Worker public:
ConicBench_asQuadTol()1073*c8dee2aaSAndroid Build Coastguard Worker ConicBench_asQuadTol() {}
1074*c8dee2aaSAndroid Build Coastguard Worker
1075*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()1076*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
1077*c8dee2aaSAndroid Build Coastguard Worker return "conic-asQuadTol";
1078*c8dee2aaSAndroid Build Coastguard Worker }
1079*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas *)1080*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
1081*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
1082*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < CONICS; ++j) {
1083*c8dee2aaSAndroid Build Coastguard Worker fConics[j].asQuadTol(SK_ScalarHalf);
1084*c8dee2aaSAndroid Build Coastguard Worker }
1085*c8dee2aaSAndroid Build Coastguard Worker }
1086*c8dee2aaSAndroid Build Coastguard Worker }
1087*c8dee2aaSAndroid Build Coastguard Worker
1088*c8dee2aaSAndroid Build Coastguard Worker private:
1089*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = ConicBench;
1090*c8dee2aaSAndroid Build Coastguard Worker };
1091*c8dee2aaSAndroid Build Coastguard Worker
1092*c8dee2aaSAndroid Build Coastguard Worker class ConicBench_quadPow2 : public ConicBench {
1093*c8dee2aaSAndroid Build Coastguard Worker public:
ConicBench_quadPow2()1094*c8dee2aaSAndroid Build Coastguard Worker ConicBench_quadPow2() {}
1095*c8dee2aaSAndroid Build Coastguard Worker
1096*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()1097*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
1098*c8dee2aaSAndroid Build Coastguard Worker return "conic-quadPow2";
1099*c8dee2aaSAndroid Build Coastguard Worker }
1100*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas *)1101*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas*) override {
1102*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
1103*c8dee2aaSAndroid Build Coastguard Worker for (int j = 0; j < CONICS; ++j) {
1104*c8dee2aaSAndroid Build Coastguard Worker fConics[j].computeQuadPOW2(SK_ScalarHalf);
1105*c8dee2aaSAndroid Build Coastguard Worker }
1106*c8dee2aaSAndroid Build Coastguard Worker }
1107*c8dee2aaSAndroid Build Coastguard Worker }
1108*c8dee2aaSAndroid Build Coastguard Worker
1109*c8dee2aaSAndroid Build Coastguard Worker private:
1110*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = ConicBench;
1111*c8dee2aaSAndroid Build Coastguard Worker };
1112*c8dee2aaSAndroid Build Coastguard Worker
1113*c8dee2aaSAndroid Build Coastguard Worker ///////////////////////////////////////////////////////////////////////////////
1114*c8dee2aaSAndroid Build Coastguard Worker
1115*c8dee2aaSAndroid Build Coastguard Worker class TightBoundsBench : public Benchmark {
1116*c8dee2aaSAndroid Build Coastguard Worker SkPath fPath;
1117*c8dee2aaSAndroid Build Coastguard Worker SkString fName;
1118*c8dee2aaSAndroid Build Coastguard Worker SkRect (*fProc)(const SkPath&);
1119*c8dee2aaSAndroid Build Coastguard Worker
1120*c8dee2aaSAndroid Build Coastguard Worker public:
TightBoundsBench(SkRect (* proc)(const SkPath &),const char suffix[])1121*c8dee2aaSAndroid Build Coastguard Worker TightBoundsBench(SkRect (*proc)(const SkPath&), const char suffix[]) : fProc(proc) {
1122*c8dee2aaSAndroid Build Coastguard Worker fName.printf("tight_bounds_%s", suffix);
1123*c8dee2aaSAndroid Build Coastguard Worker
1124*c8dee2aaSAndroid Build Coastguard Worker const int N = 100;
1125*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand;
1126*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < N; ++i) {
1127*c8dee2aaSAndroid Build Coastguard Worker fPath.moveTo(rand.nextF()*100, rand.nextF()*100);
1128*c8dee2aaSAndroid Build Coastguard Worker fPath.lineTo(rand.nextF()*100, rand.nextF()*100);
1129*c8dee2aaSAndroid Build Coastguard Worker fPath.quadTo(rand.nextF()*100, rand.nextF()*100, rand.nextF()*100, rand.nextF()*100);
1130*c8dee2aaSAndroid Build Coastguard Worker fPath.conicTo(rand.nextF()*100, rand.nextF()*100, rand.nextF()*100, rand.nextF()*100,
1131*c8dee2aaSAndroid Build Coastguard Worker rand.nextF()*10);
1132*c8dee2aaSAndroid Build Coastguard Worker fPath.cubicTo(rand.nextF()*100, rand.nextF()*100, rand.nextF()*100, rand.nextF()*100,
1133*c8dee2aaSAndroid Build Coastguard Worker rand.nextF()*100, rand.nextF()*100);
1134*c8dee2aaSAndroid Build Coastguard Worker }
1135*c8dee2aaSAndroid Build Coastguard Worker }
1136*c8dee2aaSAndroid Build Coastguard Worker
1137*c8dee2aaSAndroid Build Coastguard Worker protected:
isSuitableFor(Backend backend)1138*c8dee2aaSAndroid Build Coastguard Worker bool isSuitableFor(Backend backend) override {
1139*c8dee2aaSAndroid Build Coastguard Worker return backend == Backend::kNonRendering;
1140*c8dee2aaSAndroid Build Coastguard Worker }
1141*c8dee2aaSAndroid Build Coastguard Worker
onGetName()1142*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override { return fName.c_str(); }
1143*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas * canvas)1144*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas* canvas) override {
1145*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops*100; ++i) {
1146*c8dee2aaSAndroid Build Coastguard Worker fProc(fPath);
1147*c8dee2aaSAndroid Build Coastguard Worker }
1148*c8dee2aaSAndroid Build Coastguard Worker }
1149*c8dee2aaSAndroid Build Coastguard Worker
1150*c8dee2aaSAndroid Build Coastguard Worker private:
1151*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark;
1152*c8dee2aaSAndroid Build Coastguard Worker };
1153*c8dee2aaSAndroid Build Coastguard Worker
1154*c8dee2aaSAndroid Build Coastguard Worker
1155*c8dee2aaSAndroid Build Coastguard Worker const SkRect ConservativelyContainsBench::kBounds = SkRect::MakeWH(SkIntToScalar(100), SkIntToScalar(100));
1156*c8dee2aaSAndroid Build Coastguard Worker const SkSize ConservativelyContainsBench::kQueryMin = {SkIntToScalar(1), SkIntToScalar(1)};
1157*c8dee2aaSAndroid Build Coastguard Worker const SkSize ConservativelyContainsBench::kQueryMax = {SkIntToScalar(40), SkIntToScalar(40)};
1158*c8dee2aaSAndroid Build Coastguard Worker const SkRect ConservativelyContainsBench::kBaseRect = SkRect::MakeXYWH(SkIntToScalar(25), SkIntToScalar(25), SkIntToScalar(50), SkIntToScalar(50));
1159*c8dee2aaSAndroid Build Coastguard Worker const SkScalar ConservativelyContainsBench::kRRRadii[2] = {SkIntToScalar(5), SkIntToScalar(10)};
1160*c8dee2aaSAndroid Build Coastguard Worker
1161*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new TrianglePathBench(FLAGS00); )
1162*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new TrianglePathBench(FLAGS01); )
1163*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new TrianglePathBench(FLAGS10); )
1164*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new TrianglePathBench(FLAGS11); )
1165*c8dee2aaSAndroid Build Coastguard Worker
1166*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new RectPathBench(FLAGS00); )
1167*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new RectPathBench(FLAGS01); )
1168*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new RectPathBench(FLAGS10); )
1169*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new RectPathBench(FLAGS11); )
1170*c8dee2aaSAndroid Build Coastguard Worker
1171*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new RotatedRectBench(FLAGS00, false, 45));
1172*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new RotatedRectBench(FLAGS10, false, 45));
1173*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new RotatedRectBench(FLAGS00, true, 45));
1174*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new RotatedRectBench(FLAGS10, true, 45));
1175*c8dee2aaSAndroid Build Coastguard Worker
1176*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new OvalPathBench(FLAGS00); )
1177*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new OvalPathBench(FLAGS01); )
1178*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new OvalPathBench(FLAGS10); )
1179*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new OvalPathBench(FLAGS11); )
1180*c8dee2aaSAndroid Build Coastguard Worker
1181*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CirclePathBench(FLAGS00); )
1182*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CirclePathBench(FLAGS01); )
1183*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CirclePathBench(FLAGS10); )
1184*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CirclePathBench(FLAGS11); )
1185*c8dee2aaSAndroid Build Coastguard Worker
1186*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new NonAACirclePathBench(FLAGS00); )
1187*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new NonAACirclePathBench(FLAGS10); )
1188*c8dee2aaSAndroid Build Coastguard Worker
1189*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new AAAConcavePathBench(FLAGS00); )
1190*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new AAAConcavePathBench(FLAGS10); )
1191*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new AAAConvexPathBench(FLAGS00); )
1192*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new AAAConvexPathBench(FLAGS10); )
1193*c8dee2aaSAndroid Build Coastguard Worker
1194*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new SawToothPathBench(FLAGS00); )
1195*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new SawToothPathBench(FLAGS01); )
1196*c8dee2aaSAndroid Build Coastguard Worker
1197*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new LongCurvedPathBench(FLAGS00); )
1198*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new LongCurvedPathBench(FLAGS01); )
1199*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new LongLinePathBench(FLAGS00); )
1200*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new LongLinePathBench(FLAGS01); )
1201*c8dee2aaSAndroid Build Coastguard Worker
1202*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PathCreateBench(); )
1203*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PathCopyBench(); )
1204*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PathTransformBench(true); )
1205*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PathTransformBench(false); )
1206*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new PathEqualityBench(); )
1207*c8dee2aaSAndroid Build Coastguard Worker
1208*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAdd_AddType); )
1209*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAddTrans_AddType); )
1210*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kAddMatrix_AddType); )
1211*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kReverseAdd_AddType); )
1212*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new SkBench_AddPathTest(SkBench_AddPathTest::kReversePathTo_AddType); )
1213*c8dee2aaSAndroid Build Coastguard Worker
1214*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CirclesBench(FLAGS00); )
1215*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CirclesBench(FLAGS01); )
1216*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ArbRoundRectBench(false); )
1217*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ArbRoundRectBench(true); )
1218*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kRect_Type); )
1219*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kRoundRect_Type); )
1220*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConservativelyContainsBench(ConservativelyContainsBench::kOval_Type); )
1221*c8dee2aaSAndroid Build Coastguard Worker
1222*c8dee2aaSAndroid Build Coastguard Worker #include "include/pathops/SkPathOps.h"
1223*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkPathPriv.h"
1224*c8dee2aaSAndroid Build Coastguard Worker
__anonb7dfbe8b0802(const SkPath& path)1225*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new TightBoundsBench([](const SkPath& path){ return path.computeTightBounds();},
1226*c8dee2aaSAndroid Build Coastguard Worker "priv"); )
__anonb7dfbe8b0902(const SkPath& path) 1227*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new TightBoundsBench([](const SkPath& path) {
1228*c8dee2aaSAndroid Build Coastguard Worker SkRect bounds; TightBounds(path, &bounds); return bounds;
1229*c8dee2aaSAndroid Build Coastguard Worker }, "pathops"); )
1230*c8dee2aaSAndroid Build Coastguard Worker
1231*c8dee2aaSAndroid Build Coastguard Worker // These seem to be optimized away, which is troublesome for timing.
1232*c8dee2aaSAndroid Build Coastguard Worker /*
1233*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConicBench_Chop5() )
1234*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConicBench_ComputeError() )
1235*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConicBench_asQuadTol() )
1236*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new ConicBench_quadPow2() )
1237*c8dee2aaSAndroid Build Coastguard Worker */
1238*c8dee2aaSAndroid Build Coastguard Worker
1239*c8dee2aaSAndroid Build Coastguard Worker class CommonConvexBench : public Benchmark {
1240*c8dee2aaSAndroid Build Coastguard Worker protected:
1241*c8dee2aaSAndroid Build Coastguard Worker SkString fName;
1242*c8dee2aaSAndroid Build Coastguard Worker SkPath fPath;
1243*c8dee2aaSAndroid Build Coastguard Worker const bool fAA;
1244*c8dee2aaSAndroid Build Coastguard Worker
1245*c8dee2aaSAndroid Build Coastguard Worker public:
CommonConvexBench(int w,int h,bool forceConcave,bool aa)1246*c8dee2aaSAndroid Build Coastguard Worker CommonConvexBench(int w, int h, bool forceConcave, bool aa) : fAA(aa) {
1247*c8dee2aaSAndroid Build Coastguard Worker fName.printf("convex_path_%d_%d_%d_%d", w, h, forceConcave, aa);
1248*c8dee2aaSAndroid Build Coastguard Worker
1249*c8dee2aaSAndroid Build Coastguard Worker SkRect r = SkRect::MakeXYWH(10, 10, w*1.0f, h*1.0f);
1250*c8dee2aaSAndroid Build Coastguard Worker fPath.addRRect(SkRRect::MakeRectXY(r, w/8.0f, h/8.0f));
1251*c8dee2aaSAndroid Build Coastguard Worker
1252*c8dee2aaSAndroid Build Coastguard Worker if (forceConcave) {
1253*c8dee2aaSAndroid Build Coastguard Worker SkPathPriv::SetConvexity(fPath, SkPathConvexity::kConcave);
1254*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(!fPath.isConvex());
1255*c8dee2aaSAndroid Build Coastguard Worker } else {
1256*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(fPath.isConvex());
1257*c8dee2aaSAndroid Build Coastguard Worker }
1258*c8dee2aaSAndroid Build Coastguard Worker }
1259*c8dee2aaSAndroid Build Coastguard Worker
1260*c8dee2aaSAndroid Build Coastguard Worker protected:
onGetName()1261*c8dee2aaSAndroid Build Coastguard Worker const char* onGetName() override {
1262*c8dee2aaSAndroid Build Coastguard Worker return fName.c_str();
1263*c8dee2aaSAndroid Build Coastguard Worker }
1264*c8dee2aaSAndroid Build Coastguard Worker
onDraw(int loops,SkCanvas * canvas)1265*c8dee2aaSAndroid Build Coastguard Worker void onDraw(int loops, SkCanvas* canvas) override {
1266*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
1267*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(fAA);
1268*c8dee2aaSAndroid Build Coastguard Worker
1269*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loops; ++i) {
1270*c8dee2aaSAndroid Build Coastguard Worker for (int inner = 0; inner < 100; ++inner) {
1271*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPath(fPath, paint);
1272*c8dee2aaSAndroid Build Coastguard Worker }
1273*c8dee2aaSAndroid Build Coastguard Worker }
1274*c8dee2aaSAndroid Build Coastguard Worker }
1275*c8dee2aaSAndroid Build Coastguard Worker
1276*c8dee2aaSAndroid Build Coastguard Worker private:
1277*c8dee2aaSAndroid Build Coastguard Worker using INHERITED = Benchmark;
1278*c8dee2aaSAndroid Build Coastguard Worker };
1279*c8dee2aaSAndroid Build Coastguard Worker
1280*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CommonConvexBench( 16, 16, false, false); )
1281*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CommonConvexBench( 16, 16, true, false); )
1282*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CommonConvexBench( 16, 16, false, true); )
1283*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CommonConvexBench( 16, 16, true, true); )
1284*c8dee2aaSAndroid Build Coastguard Worker
1285*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CommonConvexBench(200, 16, false, false); )
1286*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CommonConvexBench(200, 16, true, false); )
1287*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CommonConvexBench(200, 16, false, true); )
1288*c8dee2aaSAndroid Build Coastguard Worker DEF_BENCH( return new CommonConvexBench(200, 16, true, true); )
1289