blob: 14caee5ef0bbbc25064fcc98a32cc30b38de6a11 [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
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "bench/Benchmark.h"
Jim Van Vertha5ef3972019-05-01 13:28:07 -04009#include "include/core/SkRect.h"
John Stiles9d5461f2020-07-27 15:53:49 -040010#include "include/private/SkTemplates.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "src/utils/SkPolyUtils.h"
Jim Van Verth061cc212018-07-11 14:09:09 -040012
13class PolyUtilsBench : public Benchmark {
Jim Van Verth00673692018-07-23 11:23:39 -040014public:
Jim Van Verth061cc212018-07-11 14:09:09 -040015 // Evaluate SkTriangulateSimplePolygon's performance (via derived classes) on:
16 // a non-self-intersecting star, a circle of tiny line segments and a self-intersecting star
Jim Van Verth00673692018-07-23 11:23:39 -040017 enum class Type { kConvexCheck, kSimpleCheck, kInsetConvex, kOffsetSimple, kTessellateSimple };
Jim Van Verth061cc212018-07-11 14:09:09 -040018
Jim Van Verth00673692018-07-23 11:23:39 -040019 PolyUtilsBench(Type type) : fType(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -040020
21 virtual void appendName(SkString*) = 0;
22 virtual void makePoly(SkTDArray<SkPoint>* poly) = 0;
23 virtual int complexity() { return 0; }
24
25protected:
26 const char* onGetName() override {
27 fName = "poly_utils_";
28 this->appendName(&fName);
Jim Van Verth00673692018-07-23 11:23:39 -040029 switch (fType) {
30 case Type::kConvexCheck:
31 fName.append("_c");
32 break;
33 case Type::kSimpleCheck:
34 fName.append("_s");
35 break;
36 case Type::kInsetConvex:
37 fName.append("_i");
38 break;
39 case Type::kOffsetSimple:
40 fName.append("_o");
41 break;
42 case Type::kTessellateSimple:
43 fName.append("_t");
44 break;
45 }
Jim Van Verth061cc212018-07-11 14:09:09 -040046 return fName.c_str();
47 }
48
49 void onDraw(int loops, SkCanvas* canvas) override {
50 SkTDArray<SkPoint> poly;
51 this->makePoly(&poly);
Jim Van Verth00673692018-07-23 11:23:39 -040052 switch (fType) {
53 case Type::kConvexCheck:
54 for (int i = 0; i < loops; i++) {
55 (void)SkIsConvexPolygon(poly.begin(), poly.count());
56 }
57 break;
58 case Type::kSimpleCheck:
59 for (int i = 0; i < loops; i++) {
60 (void)SkIsSimplePolygon(poly.begin(), poly.count());
61 }
62 break;
63 case Type::kInsetConvex:
64 if (SkIsConvexPolygon(poly.begin(), poly.count())) {
65 SkTDArray<SkPoint> result;
66 for (int i = 0; i < loops; i++) {
67 (void)SkInsetConvexPolygon(poly.begin(), poly.count(), 10, &result);
68 (void)SkInsetConvexPolygon(poly.begin(), poly.count(), 40, &result);
69 }
70 }
71 break;
72 case Type::kOffsetSimple:
73 if (SkIsSimplePolygon(poly.begin(), poly.count())) {
74 SkTDArray<SkPoint> result;
Jim Van Vertha5ef3972019-05-01 13:28:07 -040075 SkRect bounds;
76 bounds.setBounds(poly.begin(), poly.count());
Jim Van Verth00673692018-07-23 11:23:39 -040077 for (int i = 0; i < loops; i++) {
Jim Van Vertha5ef3972019-05-01 13:28:07 -040078 (void)SkOffsetSimplePolygon(poly.begin(), poly.count(), bounds, 10,
79 &result);
80 (void)SkOffsetSimplePolygon(poly.begin(), poly.count(), bounds, -10,
81 &result);
Jim Van Verth00673692018-07-23 11:23:39 -040082 }
83 }
84 break;
85 case Type::kTessellateSimple:
86 if (SkIsSimplePolygon(poly.begin(), poly.count())) {
87 SkAutoSTMalloc<64, uint16_t> indexMap(poly.count());
88 for (int i = 0; i < poly.count(); ++i) {
89 indexMap[i] = i;
90 }
91 SkTDArray<uint16_t> triangleIndices;
92 for (int i = 0; i < loops; i++) {
93 SkTriangulateSimplePolygon(poly.begin(), indexMap, poly.count(),
94 &triangleIndices);
95 }
96 }
97 break;
Jim Van Verth061cc212018-07-11 14:09:09 -040098 }
99 }
100
101private:
Jim Van Verth00673692018-07-23 11:23:39 -0400102 SkString fName;
103 Type fType;
104
John Stiles7571f9e2020-09-02 22:42:33 -0400105 using INHERITED = Benchmark;
Jim Van Verth061cc212018-07-11 14:09:09 -0400106};
107
108class StarPolyUtilsBench : public PolyUtilsBench {
109public:
Jim Van Verth00673692018-07-23 11:23:39 -0400110 StarPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -0400111
112 void appendName(SkString* name) override {
113 name->append("star");
114 }
115 void makePoly(SkTDArray<SkPoint>* poly) override {
116 // create non-intersecting star
117 const SkScalar c = SkIntToScalar(45);
118 const SkScalar r1 = SkIntToScalar(20);
119 const SkScalar r2 = SkIntToScalar(3);
120 const int n = 500;
121 SkScalar rad = 0;
122 const SkScalar drad = SK_ScalarPI / n;
123 for (int i = 0; i < n; i++) {
Brian Osman4428f2c2019-04-02 10:59:28 -0400124 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r1, c + SkScalarSin(rad) * r1);
Jim Van Verth061cc212018-07-11 14:09:09 -0400125 rad += drad;
Brian Osman4428f2c2019-04-02 10:59:28 -0400126 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r2, c + SkScalarSin(rad) * r2);
Jim Van Verth061cc212018-07-11 14:09:09 -0400127 rad += drad;
128 }
129 }
130private:
John Stiles7571f9e2020-09-02 22:42:33 -0400131 using INHERITED = PolyUtilsBench;
Jim Van Verth061cc212018-07-11 14:09:09 -0400132};
133
134class CirclePolyUtilsBench : public PolyUtilsBench {
135public:
Jim Van Verth00673692018-07-23 11:23:39 -0400136 CirclePolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -0400137
138 void appendName(SkString* name) override {
139 name->append("circle");
140 }
141 void makePoly(SkTDArray<SkPoint>* poly) override {
142 // create circle with many vertices
143 const SkScalar c = SkIntToScalar(45);
144 const SkScalar r = SkIntToScalar(20);
145 const int n = 1000;
146 SkScalar rad = 0;
147 const SkScalar drad = 2 * SK_ScalarPI / n;
148 for (int i = 0; i < n; i++) {
Brian Osman4428f2c2019-04-02 10:59:28 -0400149 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
Jim Van Verth061cc212018-07-11 14:09:09 -0400150 rad += drad;
151 }
152 }
153private:
John Stiles7571f9e2020-09-02 22:42:33 -0400154 using INHERITED = PolyUtilsBench;
Jim Van Verth061cc212018-07-11 14:09:09 -0400155};
156
157class IntersectingPolyUtilsBench : public PolyUtilsBench {
158public:
Jim Van Verth00673692018-07-23 11:23:39 -0400159 IntersectingPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -0400160
161 void appendName(SkString* name) override {
162 name->append("intersecting");
163 }
164 void makePoly(SkTDArray<SkPoint>* poly) override {
165 // create self-intersecting star
166 const SkScalar c = SkIntToScalar(45);
167 const SkScalar r = SkIntToScalar(20);
168 const int n = 1000;
169
170 SkScalar rad = -SK_ScalarPI / 2;
171 const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
172 *poly->push() = SkPoint::Make(c, c - r);
173 for (int i = 1; i < n; i++) {
174 rad += drad;
Brian Osman4428f2c2019-04-02 10:59:28 -0400175 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
Jim Van Verth061cc212018-07-11 14:09:09 -0400176 }
177 }
178private:
John Stiles7571f9e2020-09-02 22:42:33 -0400179 using INHERITED = PolyUtilsBench;
Jim Van Verth061cc212018-07-11 14:09:09 -0400180};
181
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400182// familiar videogame character
183class NotchPolyUtilsBench : public PolyUtilsBench {
184public:
185 NotchPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
186
187 void appendName(SkString* name) override {
188 name->append("notch");
189 }
190 void makePoly(SkTDArray<SkPoint>* poly) override {
191 // create 3/4 circle with many vertices
192 const SkScalar c = SkIntToScalar(45);
193 const SkScalar r = SkIntToScalar(20);
194 const int n = 1000;
195 SkScalar rad = 0;
196 const SkScalar drad = 3 * SK_ScalarPI / (2*n);
197 for (int i = 0; i < n; i++) {
Brian Osman4428f2c2019-04-02 10:59:28 -0400198 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400199 rad += drad;
200 }
201 // and the mouth
202 *poly->push() = SkPoint::Make(45, 45);
203 }
204private:
John Stiles7571f9e2020-09-02 22:42:33 -0400205 using INHERITED = PolyUtilsBench;
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400206};
207
208class IceCreamPolyUtilsBench : public PolyUtilsBench {
209public:
210 IceCreamPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
211
212 void appendName(SkString* name) override {
213 name->append("icecream");
214 }
215 void makePoly(SkTDArray<SkPoint>* poly) override {
216 // create 3/4 circle with many vertices
217 const SkScalar c = SkIntToScalar(45);
218 const SkScalar r = SkIntToScalar(20);
219 const int n = 1000;
220 SkScalar rad = 0;
221 const SkScalar drad = 3 * SK_ScalarPI / (2*n);
222 for (int i = 0; i < n; i++) {
Brian Osman4428f2c2019-04-02 10:59:28 -0400223 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400224 rad += drad;
225 }
226 // and the tip of the cone
227 *poly->push() = SkPoint::Make(90, 0);
228 }
229private:
John Stiles7571f9e2020-09-02 22:42:33 -0400230 using INHERITED = PolyUtilsBench;
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400231};
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