9178aa4b510fdfce639e51742367e0baa28136f6
[platform/upstream/libSkiaSharp.git] / bench / GeometryBench.cpp
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:
15     GeometryBench(const char suffix[]) : fVolatileInt(0) {
16         fName.printf("geo_%s", suffix);
17     }
18
19     const char* onGetName() SK_OVERRIDE {
20         return fName.c_str();
21     }
22
23     bool isSuitableFor(Backend backend) SK_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      */
36     virtual void virtualCallToFoilOptimizers(int n) { fVolatileInt += n; }
37
38 private:
39     SkString fName;
40 };
41
42 class GeoRectBench : public GeometryBench {
43 public:
44     GeoRectBench(const char suffix[]) : GeometryBench(suffix) {}
45
46 protected:
47     SkRect fRects[2048];
48
49     virtual void onPreDraw() {
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:
65     GeoRectBench_intersect() : GeoRectBench("rect_intersect") {}
66
67 protected:
68     void onDraw(const int loops, SkCanvas* canvas) SK_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:
82     GeoRectBench_intersect_rect() : GeoRectBench("rect_intersect_rect") {}
83
84 protected:
85     void onDraw(const int loops, SkCanvas* canvas) SK_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:
99     GeoRectBench_Intersects() : GeoRectBench("rect_Intersects") {}
100     
101 protected:
102     void onDraw(const int loops, SkCanvas* canvas) SK_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:
115     GeoRectBench_sort() : GeoRectBench("rect_sort") {}
116     
117 protected:
118     void onDraw(const int loops, SkCanvas* canvas) SK_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:
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:
149     EvalQuadAt0() : QuadBenchBase("evalquadat0") {}
150 protected:
151     void onDraw(const int loops, SkCanvas* canvas) SK_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:
165     EvalQuadAt1() : QuadBenchBase("evalquadat1") {}
166 protected:
167     void onDraw(const int loops, SkCanvas* canvas) SK_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:
183     EvalQuadTangentAt0() : QuadBenchBase("evalquadtangentat0") {}
184 protected:
185     void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
186         SkPoint result;
187         for (int outer = 0; outer < loops; ++outer) {
188             SkEvalQuadAt(fPts, 0.5f, NULL, &result);
189             SkEvalQuadAt(fPts, 0.5f, NULL, &result);
190             SkEvalQuadAt(fPts, 0.5f, NULL, &result);
191             SkEvalQuadAt(fPts, 0.5f, NULL, &result);
192         }
193     }
194 };
195 DEF_BENCH( return new EvalQuadTangentAt0; )
196
197 class EvalQuadTangentAt1 : public QuadBenchBase {
198 public:
199     EvalQuadTangentAt1() : QuadBenchBase("evalquadtangentat1") {}
200 protected:
201     void onDraw(const int loops, SkCanvas* canvas) SK_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 ChopQuadAt0 : public QuadBenchBase {
216 public:
217     ChopQuadAt0() : QuadBenchBase("chopquadat0") {}
218 protected:
219     void onDraw(const int loops, SkCanvas* canvas) SK_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 ChopQuadAt0; )
230
231 class ChopQuadAt1 : public QuadBenchBase {
232 public:
233     ChopQuadAt1() : QuadBenchBase("chopquadat1") {}
234 protected:
235     void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
236         SkPoint dst[5];
237         for (int outer = 0; outer < loops; ++outer) {
238             SkChopQuadAt2(fPts, dst, 0.5f);
239             SkChopQuadAt2(fPts, dst, 0.5f);
240             SkChopQuadAt2(fPts, dst, 0.5f);
241             SkChopQuadAt2(fPts, dst, 0.5f);
242         }
243     }
244 };
245 DEF_BENCH( return new ChopQuadAt1; )
246
247 class ChopCubicAt0 : public QuadBenchBase {
248 public:
249     ChopCubicAt0() : QuadBenchBase("chopcubicat0") {}
250 protected:
251     void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
252         SkPoint dst[7];
253         for (int outer = 0; outer < loops; ++outer) {
254             SkChopCubicAt(fPts, dst, 0.5f);
255             SkChopCubicAt(fPts, dst, 0.5f);
256             SkChopCubicAt(fPts, dst, 0.5f);
257             SkChopCubicAt(fPts, dst, 0.5f);
258         }
259     }
260 };
261 DEF_BENCH( return new ChopCubicAt0; )
262
263 class ChopCubicAt1 : public QuadBenchBase {
264 public:
265     ChopCubicAt1() : QuadBenchBase("chopcubicat1") {}
266 protected:
267     void onDraw(const int loops, SkCanvas* canvas) SK_OVERRIDE {
268         SkPoint dst[7];
269         for (int outer = 0; outer < loops; ++outer) {
270             SkChopCubicAt2(fPts, dst, 0.5f);
271             SkChopCubicAt2(fPts, dst, 0.5f);
272             SkChopCubicAt2(fPts, dst, 0.5f);
273             SkChopCubicAt2(fPts, dst, 0.5f);
274         }
275     }
276 };
277 DEF_BENCH( return new ChopCubicAt1; )
278