blob: a42ea70d239968f6c1656d2d7ce2d645337c8b36 [file] [log] [blame]
Jim Van Verth061cc212018-07-11 14:09:09 -04001/*
2 * Copyright 2018 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 "SkPolyUtils.h"
10
11class PolyUtilsBench : public Benchmark {
Jim Van Verth00673692018-07-23 11:23:39 -040012public:
Jim Van Verth061cc212018-07-11 14:09:09 -040013 // Evaluate SkTriangulateSimplePolygon's performance (via derived classes) on:
14 // a non-self-intersecting star, a circle of tiny line segments and a self-intersecting star
Jim Van Verth00673692018-07-23 11:23:39 -040015 enum class Type { kConvexCheck, kSimpleCheck, kInsetConvex, kOffsetSimple, kTessellateSimple };
Jim Van Verth061cc212018-07-11 14:09:09 -040016
Jim Van Verth00673692018-07-23 11:23:39 -040017 PolyUtilsBench(Type type) : fType(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -040018
19 virtual void appendName(SkString*) = 0;
20 virtual void makePoly(SkTDArray<SkPoint>* poly) = 0;
21 virtual int complexity() { return 0; }
22
23protected:
24 const char* onGetName() override {
25 fName = "poly_utils_";
26 this->appendName(&fName);
Jim Van Verth00673692018-07-23 11:23:39 -040027 switch (fType) {
28 case Type::kConvexCheck:
29 fName.append("_c");
30 break;
31 case Type::kSimpleCheck:
32 fName.append("_s");
33 break;
34 case Type::kInsetConvex:
35 fName.append("_i");
36 break;
37 case Type::kOffsetSimple:
38 fName.append("_o");
39 break;
40 case Type::kTessellateSimple:
41 fName.append("_t");
42 break;
43 }
Jim Van Verth061cc212018-07-11 14:09:09 -040044 return fName.c_str();
45 }
46
47 void onDraw(int loops, SkCanvas* canvas) override {
48 SkTDArray<SkPoint> poly;
49 this->makePoly(&poly);
Jim Van Verth00673692018-07-23 11:23:39 -040050 switch (fType) {
51 case Type::kConvexCheck:
52 for (int i = 0; i < loops; i++) {
53 (void)SkIsConvexPolygon(poly.begin(), poly.count());
54 }
55 break;
56 case Type::kSimpleCheck:
57 for (int i = 0; i < loops; i++) {
58 (void)SkIsSimplePolygon(poly.begin(), poly.count());
59 }
60 break;
61 case Type::kInsetConvex:
62 if (SkIsConvexPolygon(poly.begin(), poly.count())) {
63 SkTDArray<SkPoint> result;
64 for (int i = 0; i < loops; i++) {
65 (void)SkInsetConvexPolygon(poly.begin(), poly.count(), 10, &result);
66 (void)SkInsetConvexPolygon(poly.begin(), poly.count(), 40, &result);
67 }
68 }
69 break;
70 case Type::kOffsetSimple:
71 if (SkIsSimplePolygon(poly.begin(), poly.count())) {
72 SkTDArray<SkPoint> result;
73 for (int i = 0; i < loops; i++) {
74 (void)SkOffsetSimplePolygon(poly.begin(), poly.count(), 10, &result);
75 (void)SkOffsetSimplePolygon(poly.begin(), poly.count(), -10, &result);
76 }
77 }
78 break;
79 case Type::kTessellateSimple:
80 if (SkIsSimplePolygon(poly.begin(), poly.count())) {
81 SkAutoSTMalloc<64, uint16_t> indexMap(poly.count());
82 for (int i = 0; i < poly.count(); ++i) {
83 indexMap[i] = i;
84 }
85 SkTDArray<uint16_t> triangleIndices;
86 for (int i = 0; i < loops; i++) {
87 SkTriangulateSimplePolygon(poly.begin(), indexMap, poly.count(),
88 &triangleIndices);
89 }
90 }
91 break;
Jim Van Verth061cc212018-07-11 14:09:09 -040092 }
93 }
94
95private:
Jim Van Verth00673692018-07-23 11:23:39 -040096 SkString fName;
97 Type fType;
98
Jim Van Verth061cc212018-07-11 14:09:09 -040099 typedef Benchmark INHERITED;
100};
101
102class StarPolyUtilsBench : public PolyUtilsBench {
103public:
Jim Van Verth00673692018-07-23 11:23:39 -0400104 StarPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -0400105
106 void appendName(SkString* name) override {
107 name->append("star");
108 }
109 void makePoly(SkTDArray<SkPoint>* poly) override {
110 // create non-intersecting star
111 const SkScalar c = SkIntToScalar(45);
112 const SkScalar r1 = SkIntToScalar(20);
113 const SkScalar r2 = SkIntToScalar(3);
114 const int n = 500;
115 SkScalar rad = 0;
116 const SkScalar drad = SK_ScalarPI / n;
117 for (int i = 0; i < n; i++) {
118 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
119 *poly->push() = SkPoint::Make(c + cosV * r1, c + sinV * r1);
120 rad += drad;
121 sinV = SkScalarSinCos(rad, &cosV);
122 *poly->push() = SkPoint::Make(c + cosV * r2, c + sinV * r2);
123 rad += drad;
124 }
125 }
126private:
127 typedef PolyUtilsBench INHERITED;
128};
129
130class CirclePolyUtilsBench : public PolyUtilsBench {
131public:
Jim Van Verth00673692018-07-23 11:23:39 -0400132 CirclePolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -0400133
134 void appendName(SkString* name) override {
135 name->append("circle");
136 }
137 void makePoly(SkTDArray<SkPoint>* poly) override {
138 // create circle with many vertices
139 const SkScalar c = SkIntToScalar(45);
140 const SkScalar r = SkIntToScalar(20);
141 const int n = 1000;
142 SkScalar rad = 0;
143 const SkScalar drad = 2 * SK_ScalarPI / n;
144 for (int i = 0; i < n; i++) {
145 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
146 *poly->push() = SkPoint::Make(c + cosV * r, c + sinV * r);
147 rad += drad;
148 }
149 }
150private:
151 typedef PolyUtilsBench INHERITED;
152};
153
154class IntersectingPolyUtilsBench : public PolyUtilsBench {
155public:
Jim Van Verth00673692018-07-23 11:23:39 -0400156 IntersectingPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -0400157
158 void appendName(SkString* name) override {
159 name->append("intersecting");
160 }
161 void makePoly(SkTDArray<SkPoint>* poly) override {
162 // create self-intersecting star
163 const SkScalar c = SkIntToScalar(45);
164 const SkScalar r = SkIntToScalar(20);
165 const int n = 1000;
166
167 SkScalar rad = -SK_ScalarPI / 2;
168 const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
169 *poly->push() = SkPoint::Make(c, c - r);
170 for (int i = 1; i < n; i++) {
171 rad += drad;
172 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
173 *poly->push() = SkPoint::Make(c + cosV * r, c + sinV * r);
174 }
175 }
176private:
177 typedef PolyUtilsBench INHERITED;
178};
179
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400180// familiar videogame character
181class NotchPolyUtilsBench : public PolyUtilsBench {
182public:
183 NotchPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
184
185 void appendName(SkString* name) override {
186 name->append("notch");
187 }
188 void makePoly(SkTDArray<SkPoint>* poly) override {
189 // create 3/4 circle with many vertices
190 const SkScalar c = SkIntToScalar(45);
191 const SkScalar r = SkIntToScalar(20);
192 const int n = 1000;
193 SkScalar rad = 0;
194 const SkScalar drad = 3 * SK_ScalarPI / (2*n);
195 for (int i = 0; i < n; i++) {
196 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
197 *poly->push() = SkPoint::Make(c + cosV * r, c + sinV * r);
198 rad += drad;
199 }
200 // and the mouth
201 *poly->push() = SkPoint::Make(45, 45);
202 }
203private:
204 typedef PolyUtilsBench INHERITED;
205};
206
207class IceCreamPolyUtilsBench : public PolyUtilsBench {
208public:
209 IceCreamPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
210
211 void appendName(SkString* name) override {
212 name->append("icecream");
213 }
214 void makePoly(SkTDArray<SkPoint>* poly) override {
215 // create 3/4 circle with many vertices
216 const SkScalar c = SkIntToScalar(45);
217 const SkScalar r = SkIntToScalar(20);
218 const int n = 1000;
219 SkScalar rad = 0;
220 const SkScalar drad = 3 * SK_ScalarPI / (2*n);
221 for (int i = 0; i < n; i++) {
222 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
223 *poly->push() = SkPoint::Make(c + cosV * r, c + sinV * r);
224 rad += drad;
225 }
226 // and the tip of the cone
227 *poly->push() = SkPoint::Make(90, 0);
228 }
229private:
230 typedef PolyUtilsBench INHERITED;
231};
232
Jim Van Verth00673692018-07-23 11:23:39 -0400233DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
234DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
235DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
236DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
237DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
238DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
239DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
240DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
241DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
242DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
243DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
244DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
245DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
246DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
247DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400248DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
249DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
250DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
251DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
252DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
253DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
254DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
255DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
256DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
257DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
258