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