1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2014 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/SkRect.h"
10cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h"
11cb93a386Sopenharmony_ci#include "src/core/SkGeometry.h"
12cb93a386Sopenharmony_ci#include "src/core/SkPathPriv.h"
13cb93a386Sopenharmony_ci
14cb93a386Sopenharmony_ciclass GeometryBench : public Benchmark {
15cb93a386Sopenharmony_cipublic:
16cb93a386Sopenharmony_ci    GeometryBench(const char suffix[]) : fVolatileInt(0) {
17cb93a386Sopenharmony_ci        fName.printf("geo_%s", suffix);
18cb93a386Sopenharmony_ci    }
19cb93a386Sopenharmony_ci
20cb93a386Sopenharmony_ci    const char* onGetName() override {
21cb93a386Sopenharmony_ci        return fName.c_str();
22cb93a386Sopenharmony_ci    }
23cb93a386Sopenharmony_ci
24cb93a386Sopenharmony_ci    bool isSuitableFor(Backend backend) override {
25cb93a386Sopenharmony_ci        return kNonRendering_Backend == backend;
26cb93a386Sopenharmony_ci    }
27cb93a386Sopenharmony_ci
28cb93a386Sopenharmony_ciprotected:
29cb93a386Sopenharmony_ci    volatile int fVolatileInt;
30cb93a386Sopenharmony_ci
31cb93a386Sopenharmony_ci    /**
32cb93a386Sopenharmony_ci     *  Subclasses can call this to try to defeat the optimizer (with some result of their
33cb93a386Sopenharmony_ci     *  inner loop), since it will fool the compiler into assuming that "n" is actually
34cb93a386Sopenharmony_ci     *  needed somewhere, and since this method is not const, the member fields cannot
35cb93a386Sopenharmony_ci     *  be assumed to be const before and after the call.
36cb93a386Sopenharmony_ci     */
37cb93a386Sopenharmony_ci    virtual void virtualCallToFoilOptimizers(int n) { fVolatileInt += n; }
38cb93a386Sopenharmony_ci
39cb93a386Sopenharmony_ciprivate:
40cb93a386Sopenharmony_ci    SkString fName;
41cb93a386Sopenharmony_ci};
42cb93a386Sopenharmony_ci
43cb93a386Sopenharmony_ciclass GeoRectBench : public GeometryBench {
44cb93a386Sopenharmony_cipublic:
45cb93a386Sopenharmony_ci    GeoRectBench(const char suffix[]) : GeometryBench(suffix) {}
46cb93a386Sopenharmony_ci
47cb93a386Sopenharmony_ciprotected:
48cb93a386Sopenharmony_ci    SkRect fRects[2048];
49cb93a386Sopenharmony_ci
50cb93a386Sopenharmony_ci    void onDelayedSetup() override {
51cb93a386Sopenharmony_ci        const SkScalar min = -100;
52cb93a386Sopenharmony_ci        const SkScalar max = 100;
53cb93a386Sopenharmony_ci        SkRandom rand;
54cb93a386Sopenharmony_ci        for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
55cb93a386Sopenharmony_ci            SkScalar x = rand.nextRangeScalar(min, max);
56cb93a386Sopenharmony_ci            SkScalar y = rand.nextRangeScalar(min, max);
57cb93a386Sopenharmony_ci            SkScalar w = rand.nextRangeScalar(min, max);
58cb93a386Sopenharmony_ci            SkScalar h = rand.nextRangeScalar(min, max);
59cb93a386Sopenharmony_ci            fRects[i].setXYWH(x, y, w, h);
60cb93a386Sopenharmony_ci        }
61cb93a386Sopenharmony_ci    }
62cb93a386Sopenharmony_ci};
63cb93a386Sopenharmony_ci
64cb93a386Sopenharmony_ciclass GeoRectBench_intersect : public GeoRectBench {
65cb93a386Sopenharmony_cipublic:
66cb93a386Sopenharmony_ci    GeoRectBench_intersect() : GeoRectBench("rect_intersect") {}
67cb93a386Sopenharmony_ci
68cb93a386Sopenharmony_ciprotected:
69cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
70cb93a386Sopenharmony_ci        for (int outer = 0; outer < loops; ++outer) {
71cb93a386Sopenharmony_ci            int count = 0;
72cb93a386Sopenharmony_ci            for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
73cb93a386Sopenharmony_ci                SkRect r = fRects[0];
74cb93a386Sopenharmony_ci                count += r.intersect(fRects[i]);
75cb93a386Sopenharmony_ci            }
76cb93a386Sopenharmony_ci            this->virtualCallToFoilOptimizers(count);
77cb93a386Sopenharmony_ci        }
78cb93a386Sopenharmony_ci    }
79cb93a386Sopenharmony_ci};
80cb93a386Sopenharmony_ci
81cb93a386Sopenharmony_ciclass GeoRectBench_intersect_rect : public GeoRectBench {
82cb93a386Sopenharmony_cipublic:
83cb93a386Sopenharmony_ci    GeoRectBench_intersect_rect() : GeoRectBench("rect_intersect_rect") {}
84cb93a386Sopenharmony_ci
85cb93a386Sopenharmony_ciprotected:
86cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
87cb93a386Sopenharmony_ci        for (int outer = 0; outer < loops; ++outer) {
88cb93a386Sopenharmony_ci            int count = 0;
89cb93a386Sopenharmony_ci            SkRect r;
90cb93a386Sopenharmony_ci            for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
91cb93a386Sopenharmony_ci                count += r.intersect(fRects[0], fRects[i]);
92cb93a386Sopenharmony_ci            }
93cb93a386Sopenharmony_ci            this->virtualCallToFoilOptimizers(count);
94cb93a386Sopenharmony_ci        }
95cb93a386Sopenharmony_ci    }
96cb93a386Sopenharmony_ci};
97cb93a386Sopenharmony_ci
98cb93a386Sopenharmony_ciclass GeoRectBench_Intersects : public GeoRectBench {
99cb93a386Sopenharmony_cipublic:
100cb93a386Sopenharmony_ci    GeoRectBench_Intersects() : GeoRectBench("rect_Intersects") {}
101cb93a386Sopenharmony_ci
102cb93a386Sopenharmony_ciprotected:
103cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
104cb93a386Sopenharmony_ci        for (int outer = 0; outer < loops; ++outer) {
105cb93a386Sopenharmony_ci            int count = 0;
106cb93a386Sopenharmony_ci            for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
107cb93a386Sopenharmony_ci                count += SkRect::Intersects(fRects[0], fRects[i]);
108cb93a386Sopenharmony_ci            }
109cb93a386Sopenharmony_ci            this->virtualCallToFoilOptimizers(count);
110cb93a386Sopenharmony_ci        }
111cb93a386Sopenharmony_ci    }
112cb93a386Sopenharmony_ci};
113cb93a386Sopenharmony_ci
114cb93a386Sopenharmony_ciclass GeoRectBench_sort : public GeoRectBench {
115cb93a386Sopenharmony_cipublic:
116cb93a386Sopenharmony_ci    GeoRectBench_sort() : GeoRectBench("rect_sort") {}
117cb93a386Sopenharmony_ci
118cb93a386Sopenharmony_ciprotected:
119cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
120cb93a386Sopenharmony_ci        for (int outer = 0; outer < loops; ++outer) {
121cb93a386Sopenharmony_ci            for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
122cb93a386Sopenharmony_ci                fRects[i].sort();
123cb93a386Sopenharmony_ci            }
124cb93a386Sopenharmony_ci        }
125cb93a386Sopenharmony_ci    }
126cb93a386Sopenharmony_ci};
127cb93a386Sopenharmony_ci
128cb93a386Sopenharmony_ciDEF_BENCH( return new GeoRectBench_intersect; )
129cb93a386Sopenharmony_ciDEF_BENCH( return new GeoRectBench_intersect_rect; )
130cb93a386Sopenharmony_ciDEF_BENCH( return new GeoRectBench_Intersects; )
131cb93a386Sopenharmony_ci
132cb93a386Sopenharmony_ciDEF_BENCH( return new GeoRectBench_sort; )
133cb93a386Sopenharmony_ci
134cb93a386Sopenharmony_ci///////////////////////////////////////////////////////////////////////////////////////////////////
135cb93a386Sopenharmony_ci
136cb93a386Sopenharmony_ciclass QuadBenchBase : public GeometryBench {
137cb93a386Sopenharmony_ciprotected:
138cb93a386Sopenharmony_ci    SkPoint fPts[4];
139cb93a386Sopenharmony_cipublic:
140cb93a386Sopenharmony_ci    QuadBenchBase(const char name[]) : GeometryBench(name) {
141cb93a386Sopenharmony_ci        SkRandom rand;
142cb93a386Sopenharmony_ci        for (int i = 0; i < 4; ++i) {
143cb93a386Sopenharmony_ci            fPts[i].set(rand.nextUScalar1(), rand.nextUScalar1());
144cb93a386Sopenharmony_ci        }
145cb93a386Sopenharmony_ci    }
146cb93a386Sopenharmony_ci};
147cb93a386Sopenharmony_ci
148cb93a386Sopenharmony_ciclass EvalQuadAt0 : public QuadBenchBase {
149cb93a386Sopenharmony_cipublic:
150cb93a386Sopenharmony_ci    EvalQuadAt0() : QuadBenchBase("evalquadat0") {}
151cb93a386Sopenharmony_ciprotected:
152cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
153cb93a386Sopenharmony_ci        SkPoint result;
154cb93a386Sopenharmony_ci        for (int outer = 0; outer < loops; ++outer) {
155cb93a386Sopenharmony_ci            SkEvalQuadAt(fPts, 0.5f, &result);
156cb93a386Sopenharmony_ci            SkEvalQuadAt(fPts, 0.5f, &result);
157cb93a386Sopenharmony_ci            SkEvalQuadAt(fPts, 0.5f, &result);
158cb93a386Sopenharmony_ci            SkEvalQuadAt(fPts, 0.5f, &result);
159cb93a386Sopenharmony_ci        }
160cb93a386Sopenharmony_ci    }
161cb93a386Sopenharmony_ci};
162cb93a386Sopenharmony_ciDEF_BENCH( return new EvalQuadAt0; )
163cb93a386Sopenharmony_ci
164cb93a386Sopenharmony_ciclass EvalQuadAt1 : public QuadBenchBase {
165cb93a386Sopenharmony_cipublic:
166cb93a386Sopenharmony_ci    EvalQuadAt1() : QuadBenchBase("evalquadat1") {}
167cb93a386Sopenharmony_ciprotected:
168cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
169cb93a386Sopenharmony_ci        SkPoint result;
170cb93a386Sopenharmony_ci        for (int outer = 0; outer < loops; ++outer) {
171cb93a386Sopenharmony_ci            result = SkEvalQuadAt(fPts, 0.5f);
172cb93a386Sopenharmony_ci            result = SkEvalQuadAt(fPts, 0.5f);
173cb93a386Sopenharmony_ci            result = SkEvalQuadAt(fPts, 0.5f);
174cb93a386Sopenharmony_ci            result = SkEvalQuadAt(fPts, 0.5f);
175cb93a386Sopenharmony_ci        }
176cb93a386Sopenharmony_ci    }
177cb93a386Sopenharmony_ci};
178cb93a386Sopenharmony_ciDEF_BENCH( return new EvalQuadAt1; )
179cb93a386Sopenharmony_ci
180cb93a386Sopenharmony_ci////////
181cb93a386Sopenharmony_ci
182cb93a386Sopenharmony_ciclass EvalQuadTangentAt0 : public QuadBenchBase {
183cb93a386Sopenharmony_cipublic:
184cb93a386Sopenharmony_ci    EvalQuadTangentAt0() : QuadBenchBase("evalquadtangentat0") {}
185cb93a386Sopenharmony_ciprotected:
186cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
187cb93a386Sopenharmony_ci        SkPoint result;
188cb93a386Sopenharmony_ci        for (int outer = 0; outer < loops; ++outer) {
189cb93a386Sopenharmony_ci            SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
190cb93a386Sopenharmony_ci            SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
191cb93a386Sopenharmony_ci            SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
192cb93a386Sopenharmony_ci            SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
193cb93a386Sopenharmony_ci        }
194cb93a386Sopenharmony_ci    }
195cb93a386Sopenharmony_ci};
196cb93a386Sopenharmony_ciDEF_BENCH( return new EvalQuadTangentAt0; )
197cb93a386Sopenharmony_ci
198cb93a386Sopenharmony_ciclass EvalQuadTangentAt1 : public QuadBenchBase {
199cb93a386Sopenharmony_cipublic:
200cb93a386Sopenharmony_ci    EvalQuadTangentAt1() : QuadBenchBase("evalquadtangentat1") {}
201cb93a386Sopenharmony_ciprotected:
202cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
203cb93a386Sopenharmony_ci        SkPoint result;
204cb93a386Sopenharmony_ci        for (int outer = 0; outer < loops; ++outer) {
205cb93a386Sopenharmony_ci            result = SkEvalQuadTangentAt(fPts, 0.5f);
206cb93a386Sopenharmony_ci            result = SkEvalQuadTangentAt(fPts, 0.5f);
207cb93a386Sopenharmony_ci            result = SkEvalQuadTangentAt(fPts, 0.5f);
208cb93a386Sopenharmony_ci            result = SkEvalQuadTangentAt(fPts, 0.5f);
209cb93a386Sopenharmony_ci        }
210cb93a386Sopenharmony_ci    }
211cb93a386Sopenharmony_ci};
212cb93a386Sopenharmony_ciDEF_BENCH( return new EvalQuadTangentAt1; )
213cb93a386Sopenharmony_ci
214cb93a386Sopenharmony_ci////////
215cb93a386Sopenharmony_ci
216cb93a386Sopenharmony_ciclass ChopQuadAt : public QuadBenchBase {
217cb93a386Sopenharmony_cipublic:
218cb93a386Sopenharmony_ci    ChopQuadAt() : QuadBenchBase("chopquadat") {}
219cb93a386Sopenharmony_ciprotected:
220cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
221cb93a386Sopenharmony_ci        SkPoint dst[5];
222cb93a386Sopenharmony_ci        for (int outer = 0; outer < loops; ++outer) {
223cb93a386Sopenharmony_ci            SkChopQuadAt(fPts, dst, 0.5f);
224cb93a386Sopenharmony_ci            SkChopQuadAt(fPts, dst, 0.5f);
225cb93a386Sopenharmony_ci            SkChopQuadAt(fPts, dst, 0.5f);
226cb93a386Sopenharmony_ci            SkChopQuadAt(fPts, dst, 0.5f);
227cb93a386Sopenharmony_ci        }
228cb93a386Sopenharmony_ci    }
229cb93a386Sopenharmony_ci};
230cb93a386Sopenharmony_ciDEF_BENCH( return new ChopQuadAt; )
231cb93a386Sopenharmony_ci
232cb93a386Sopenharmony_ciclass ChopCubicAt : public QuadBenchBase {
233cb93a386Sopenharmony_cipublic:
234cb93a386Sopenharmony_ci    ChopCubicAt() : QuadBenchBase("chopcubicat0") {}
235cb93a386Sopenharmony_ciprotected:
236cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
237cb93a386Sopenharmony_ci        SkPoint dst[7];
238cb93a386Sopenharmony_ci        for (int outer = 0; outer < loops; ++outer) {
239cb93a386Sopenharmony_ci            SkChopCubicAt(fPts, dst, 0.5f);
240cb93a386Sopenharmony_ci            SkChopCubicAt(fPts, dst, 0.5f);
241cb93a386Sopenharmony_ci            SkChopCubicAt(fPts, dst, 0.5f);
242cb93a386Sopenharmony_ci            SkChopCubicAt(fPts, dst, 0.5f);
243cb93a386Sopenharmony_ci        }
244cb93a386Sopenharmony_ci    }
245cb93a386Sopenharmony_ci};
246cb93a386Sopenharmony_ciDEF_BENCH( return new ChopCubicAt; )
247cb93a386Sopenharmony_ci
248cb93a386Sopenharmony_ci#include "include/core/SkPath.h"
249cb93a386Sopenharmony_ci
250cb93a386Sopenharmony_ciclass ConvexityBench : public Benchmark {
251cb93a386Sopenharmony_ci    SkPath fPath;
252cb93a386Sopenharmony_ci
253cb93a386Sopenharmony_cipublic:
254cb93a386Sopenharmony_ci    ConvexityBench(const char suffix[]) {
255cb93a386Sopenharmony_ci        fName.printf("convexity_%s", suffix);
256cb93a386Sopenharmony_ci    }
257cb93a386Sopenharmony_ci
258cb93a386Sopenharmony_ci    const char* onGetName() override {
259cb93a386Sopenharmony_ci        return fName.c_str();
260cb93a386Sopenharmony_ci    }
261cb93a386Sopenharmony_ci
262cb93a386Sopenharmony_ci    bool isSuitableFor(Backend backend) override {
263cb93a386Sopenharmony_ci        return kNonRendering_Backend == backend;
264cb93a386Sopenharmony_ci    }
265cb93a386Sopenharmony_ci
266cb93a386Sopenharmony_ci    virtual void preparePath(SkPath*) = 0;
267cb93a386Sopenharmony_ci
268cb93a386Sopenharmony_ciprotected:
269cb93a386Sopenharmony_ci    void onPreDraw(SkCanvas*) override {
270cb93a386Sopenharmony_ci        this->preparePath(&fPath);
271cb93a386Sopenharmony_ci    }
272cb93a386Sopenharmony_ci
273cb93a386Sopenharmony_ci    void onDraw(int loops, SkCanvas* canvas) override {
274cb93a386Sopenharmony_ci        for (int i = 0; i < loops; ++i) {
275cb93a386Sopenharmony_ci            SkPathPriv::ForceComputeConvexity(fPath);
276cb93a386Sopenharmony_ci        }
277cb93a386Sopenharmony_ci    }
278cb93a386Sopenharmony_ci
279cb93a386Sopenharmony_ciprivate:
280cb93a386Sopenharmony_ci    SkString fName;
281cb93a386Sopenharmony_ci};
282cb93a386Sopenharmony_ci
283cb93a386Sopenharmony_ciclass RRectConvexityBench : public ConvexityBench {
284cb93a386Sopenharmony_cipublic:
285cb93a386Sopenharmony_ci    RRectConvexityBench() : ConvexityBench("rrect") {}
286cb93a386Sopenharmony_ci
287cb93a386Sopenharmony_ci    void preparePath(SkPath* path) override {
288cb93a386Sopenharmony_ci        SkRRect rr;
289cb93a386Sopenharmony_ci        rr.setRectXY({0, 0, 100, 100}, 20, 30);
290cb93a386Sopenharmony_ci        path->addRRect(rr);
291cb93a386Sopenharmony_ci    }
292cb93a386Sopenharmony_ci};
293cb93a386Sopenharmony_ciDEF_BENCH( return new RRectConvexityBench; )
294cb93a386Sopenharmony_ci
295