blob: 5cbff93bfeaeb9e7f580681a011f3fb85eb7ef23 [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++) {
Brian Osman4428f2c2019-04-02 10:59:28 -0400118 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r1, c + SkScalarSin(rad) * r1);
Jim Van Verth061cc212018-07-11 14:09:09 -0400119 rad += drad;
Brian Osman4428f2c2019-04-02 10:59:28 -0400120 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r2, c + SkScalarSin(rad) * r2);
Jim Van Verth061cc212018-07-11 14:09:09 -0400121 rad += drad;
122 }
123 }
124private:
125 typedef PolyUtilsBench INHERITED;
126};
127
128class CirclePolyUtilsBench : public PolyUtilsBench {
129public:
Jim Van Verth00673692018-07-23 11:23:39 -0400130 CirclePolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -0400131
132 void appendName(SkString* name) override {
133 name->append("circle");
134 }
135 void makePoly(SkTDArray<SkPoint>* poly) override {
136 // create circle with many vertices
137 const SkScalar c = SkIntToScalar(45);
138 const SkScalar r = SkIntToScalar(20);
139 const int n = 1000;
140 SkScalar rad = 0;
141 const SkScalar drad = 2 * SK_ScalarPI / n;
142 for (int i = 0; i < n; i++) {
Brian Osman4428f2c2019-04-02 10:59:28 -0400143 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
Jim Van Verth061cc212018-07-11 14:09:09 -0400144 rad += drad;
145 }
146 }
147private:
148 typedef PolyUtilsBench INHERITED;
149};
150
151class IntersectingPolyUtilsBench : public PolyUtilsBench {
152public:
Jim Van Verth00673692018-07-23 11:23:39 -0400153 IntersectingPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -0400154
155 void appendName(SkString* name) override {
156 name->append("intersecting");
157 }
158 void makePoly(SkTDArray<SkPoint>* poly) override {
159 // create self-intersecting star
160 const SkScalar c = SkIntToScalar(45);
161 const SkScalar r = SkIntToScalar(20);
162 const int n = 1000;
163
164 SkScalar rad = -SK_ScalarPI / 2;
165 const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
166 *poly->push() = SkPoint::Make(c, c - r);
167 for (int i = 1; i < n; i++) {
168 rad += drad;
Brian Osman4428f2c2019-04-02 10:59:28 -0400169 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
Jim Van Verth061cc212018-07-11 14:09:09 -0400170 }
171 }
172private:
173 typedef PolyUtilsBench INHERITED;
174};
175
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400176// familiar videogame character
177class NotchPolyUtilsBench : public PolyUtilsBench {
178public:
179 NotchPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
180
181 void appendName(SkString* name) override {
182 name->append("notch");
183 }
184 void makePoly(SkTDArray<SkPoint>* poly) override {
185 // create 3/4 circle with many vertices
186 const SkScalar c = SkIntToScalar(45);
187 const SkScalar r = SkIntToScalar(20);
188 const int n = 1000;
189 SkScalar rad = 0;
190 const SkScalar drad = 3 * SK_ScalarPI / (2*n);
191 for (int i = 0; i < n; i++) {
Brian Osman4428f2c2019-04-02 10:59:28 -0400192 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400193 rad += drad;
194 }
195 // and the mouth
196 *poly->push() = SkPoint::Make(45, 45);
197 }
198private:
199 typedef PolyUtilsBench INHERITED;
200};
201
202class IceCreamPolyUtilsBench : public PolyUtilsBench {
203public:
204 IceCreamPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
205
206 void appendName(SkString* name) override {
207 name->append("icecream");
208 }
209 void makePoly(SkTDArray<SkPoint>* poly) override {
210 // create 3/4 circle with many vertices
211 const SkScalar c = SkIntToScalar(45);
212 const SkScalar r = SkIntToScalar(20);
213 const int n = 1000;
214 SkScalar rad = 0;
215 const SkScalar drad = 3 * SK_ScalarPI / (2*n);
216 for (int i = 0; i < n; i++) {
Brian Osman4428f2c2019-04-02 10:59:28 -0400217 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400218 rad += drad;
219 }
220 // and the tip of the cone
221 *poly->push() = SkPoint::Make(90, 0);
222 }
223private:
224 typedef PolyUtilsBench INHERITED;
225};
226
Jim Van Verth00673692018-07-23 11:23:39 -0400227DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
228DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
229DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
230DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
231DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
232DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
233DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
234DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
235DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
236DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
237DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
238DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
239DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
240DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
241DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400242DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
243DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
244DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
245DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
246DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
247DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
248DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
249DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
250DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
251DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
252