• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "Benchmark.h"
9 #include "SkGeometry.h"
10 #include "SkRandom.h"
11 #include "SkRect.h"
12 
13 class GeometryBench : public Benchmark {
14 public:
GeometryBench(const char suffix[])15     GeometryBench(const char suffix[]) : fVolatileInt(0) {
16         fName.printf("geo_%s", suffix);
17     }
18 
onGetName()19     const char* onGetName() override {
20         return fName.c_str();
21     }
22 
isSuitableFor(Backend backend)23     bool isSuitableFor(Backend backend) override {
24         return kNonRendering_Backend == backend;
25     }
26 
27 protected:
28     volatile int fVolatileInt;
29 
30     /**
31      *  Subclasses can call this to try to defeat the optimizer (with some result of their
32      *  inner loop), since it will fool the compiler into assuming that "n" is actually
33      *  needed somewhere, and since this method is not const, the member fields cannot
34      *  be assumed to be const before and after the call.
35      */
virtualCallToFoilOptimizers(int n)36     virtual void virtualCallToFoilOptimizers(int n) { fVolatileInt += n; }
37 
38 private:
39     SkString fName;
40 };
41 
42 class GeoRectBench : public GeometryBench {
43 public:
GeoRectBench(const char suffix[])44     GeoRectBench(const char suffix[]) : GeometryBench(suffix) {}
45 
46 protected:
47     SkRect fRects[2048];
48 
onDelayedSetup()49     virtual void onDelayedSetup() {
50         const SkScalar min = -100;
51         const SkScalar max = 100;
52         SkRandom rand;
53         for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
54             SkScalar x = rand.nextRangeScalar(min, max);
55             SkScalar y = rand.nextRangeScalar(min, max);
56             SkScalar w = rand.nextRangeScalar(min, max);
57             SkScalar h = rand.nextRangeScalar(min, max);
58             fRects[i].setXYWH(x, y, w, h);
59         }
60     }
61 };
62 
63 class GeoRectBench_intersect : public GeoRectBench {
64 public:
GeoRectBench_intersect()65     GeoRectBench_intersect() : GeoRectBench("rect_intersect") {}
66 
67 protected:
onDraw(int loops,SkCanvas * canvas)68     void onDraw(int loops, SkCanvas* canvas) override {
69         for (int outer = 0; outer < loops; ++outer) {
70             int count = 0;
71             for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
72                 SkRect r = fRects[0];
73                 count += r.intersect(fRects[i]);
74             }
75             this->virtualCallToFoilOptimizers(count);
76         }
77     }
78 };
79 
80 class GeoRectBench_intersect_rect : public GeoRectBench {
81 public:
GeoRectBench_intersect_rect()82     GeoRectBench_intersect_rect() : GeoRectBench("rect_intersect_rect") {}
83 
84 protected:
onDraw(int loops,SkCanvas * canvas)85     void onDraw(int loops, SkCanvas* canvas) override {
86         for (int outer = 0; outer < loops; ++outer) {
87             int count = 0;
88             SkRect r;
89             for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
90                 count += r.intersect(fRects[0], fRects[i]);
91             }
92             this->virtualCallToFoilOptimizers(count);
93         }
94     }
95 };
96 
97 class GeoRectBench_Intersects : public GeoRectBench {
98 public:
GeoRectBench_Intersects()99     GeoRectBench_Intersects() : GeoRectBench("rect_Intersects") {}
100 
101 protected:
onDraw(int loops,SkCanvas * canvas)102     void onDraw(int loops, SkCanvas* canvas) override {
103         for (int outer = 0; outer < loops; ++outer) {
104             int count = 0;
105             for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
106                 count += SkRect::Intersects(fRects[0], fRects[i]);
107             }
108             this->virtualCallToFoilOptimizers(count);
109         }
110     }
111 };
112 
113 class GeoRectBench_sort : public GeoRectBench {
114 public:
GeoRectBench_sort()115     GeoRectBench_sort() : GeoRectBench("rect_sort") {}
116 
117 protected:
onDraw(int loops,SkCanvas * canvas)118     void onDraw(int loops, SkCanvas* canvas) override {
119         for (int outer = 0; outer < loops; ++outer) {
120             for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) {
121                 fRects[i].sort();
122             }
123         }
124     }
125 };
126 
127 DEF_BENCH( return new GeoRectBench_intersect; )
128 DEF_BENCH( return new GeoRectBench_intersect_rect; )
129 DEF_BENCH( return new GeoRectBench_Intersects; )
130 
131 DEF_BENCH( return new GeoRectBench_sort; )
132 
133 ///////////////////////////////////////////////////////////////////////////////////////////////////
134 
135 class QuadBenchBase : public GeometryBench {
136 protected:
137     SkPoint fPts[4];
138 public:
QuadBenchBase(const char name[])139     QuadBenchBase(const char name[]) : GeometryBench(name) {
140         SkRandom rand;
141         for (int i = 0; i < 4; ++i) {
142             fPts[i].set(rand.nextUScalar1(), rand.nextUScalar1());
143         }
144     }
145 };
146 
147 class EvalQuadAt0 : public QuadBenchBase {
148 public:
EvalQuadAt0()149     EvalQuadAt0() : QuadBenchBase("evalquadat0") {}
150 protected:
onDraw(int loops,SkCanvas * canvas)151     void onDraw(int loops, SkCanvas* canvas) override {
152         SkPoint result;
153         for (int outer = 0; outer < loops; ++outer) {
154             SkEvalQuadAt(fPts, 0.5f, &result);
155             SkEvalQuadAt(fPts, 0.5f, &result);
156             SkEvalQuadAt(fPts, 0.5f, &result);
157             SkEvalQuadAt(fPts, 0.5f, &result);
158         }
159     }
160 };
161 DEF_BENCH( return new EvalQuadAt0; )
162 
163 class EvalQuadAt1 : public QuadBenchBase {
164 public:
EvalQuadAt1()165     EvalQuadAt1() : QuadBenchBase("evalquadat1") {}
166 protected:
onDraw(int loops,SkCanvas * canvas)167     void onDraw(int loops, SkCanvas* canvas) override {
168         SkPoint result;
169         for (int outer = 0; outer < loops; ++outer) {
170             result = SkEvalQuadAt(fPts, 0.5f);
171             result = SkEvalQuadAt(fPts, 0.5f);
172             result = SkEvalQuadAt(fPts, 0.5f);
173             result = SkEvalQuadAt(fPts, 0.5f);
174         }
175     }
176 };
177 DEF_BENCH( return new EvalQuadAt1; )
178 
179 ////////
180 
181 class EvalQuadTangentAt0 : public QuadBenchBase {
182 public:
EvalQuadTangentAt0()183     EvalQuadTangentAt0() : QuadBenchBase("evalquadtangentat0") {}
184 protected:
onDraw(int loops,SkCanvas * canvas)185     void onDraw(int loops, SkCanvas* canvas) override {
186         SkPoint result;
187         for (int outer = 0; outer < loops; ++outer) {
188             SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
189             SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
190             SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
191             SkEvalQuadAt(fPts, 0.5f, nullptr, &result);
192         }
193     }
194 };
195 DEF_BENCH( return new EvalQuadTangentAt0; )
196 
197 class EvalQuadTangentAt1 : public QuadBenchBase {
198 public:
EvalQuadTangentAt1()199     EvalQuadTangentAt1() : QuadBenchBase("evalquadtangentat1") {}
200 protected:
onDraw(int loops,SkCanvas * canvas)201     void onDraw(int loops, SkCanvas* canvas) override {
202         SkPoint result;
203         for (int outer = 0; outer < loops; ++outer) {
204             result = SkEvalQuadTangentAt(fPts, 0.5f);
205             result = SkEvalQuadTangentAt(fPts, 0.5f);
206             result = SkEvalQuadTangentAt(fPts, 0.5f);
207             result = SkEvalQuadTangentAt(fPts, 0.5f);
208         }
209     }
210 };
211 DEF_BENCH( return new EvalQuadTangentAt1; )
212 
213 ////////
214 
215 class ChopQuadAt : public QuadBenchBase {
216 public:
ChopQuadAt()217     ChopQuadAt() : QuadBenchBase("chopquadat") {}
218 protected:
onDraw(int loops,SkCanvas * canvas)219     void onDraw(int loops, SkCanvas* canvas) override {
220         SkPoint dst[5];
221         for (int outer = 0; outer < loops; ++outer) {
222             SkChopQuadAt(fPts, dst, 0.5f);
223             SkChopQuadAt(fPts, dst, 0.5f);
224             SkChopQuadAt(fPts, dst, 0.5f);
225             SkChopQuadAt(fPts, dst, 0.5f);
226         }
227     }
228 };
229 DEF_BENCH( return new ChopQuadAt; )
230 
231 class ChopCubicAt : public QuadBenchBase {
232 public:
ChopCubicAt()233     ChopCubicAt() : QuadBenchBase("chopcubicat0") {}
234 protected:
onDraw(int loops,SkCanvas * canvas)235     void onDraw(int loops, SkCanvas* canvas) override {
236         SkPoint dst[7];
237         for (int outer = 0; outer < loops; ++outer) {
238             SkChopCubicAt(fPts, dst, 0.5f);
239             SkChopCubicAt(fPts, dst, 0.5f);
240             SkChopCubicAt(fPts, dst, 0.5f);
241             SkChopCubicAt(fPts, dst, 0.5f);
242         }
243     }
244 };
245 DEF_BENCH( return new ChopCubicAt; )
246