blob: 6e71a3083b495c6ea9626b0a0ba0425d23f29cbc [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"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "src/utils/SkPolyUtils.h"
Jim Van Verth061cc212018-07-11 14:09:09 -040011
12class PolyUtilsBench : public Benchmark {
Jim Van Verth00673692018-07-23 11:23:39 -040013public:
Jim Van Verth061cc212018-07-11 14:09:09 -040014 // Evaluate SkTriangulateSimplePolygon's performance (via derived classes) on:
15 // a non-self-intersecting star, a circle of tiny line segments and a self-intersecting star
Jim Van Verth00673692018-07-23 11:23:39 -040016 enum class Type { kConvexCheck, kSimpleCheck, kInsetConvex, kOffsetSimple, kTessellateSimple };
Jim Van Verth061cc212018-07-11 14:09:09 -040017
Jim Van Verth00673692018-07-23 11:23:39 -040018 PolyUtilsBench(Type type) : fType(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -040019
20 virtual void appendName(SkString*) = 0;
21 virtual void makePoly(SkTDArray<SkPoint>* poly) = 0;
22 virtual int complexity() { return 0; }
23
24protected:
25 const char* onGetName() override {
26 fName = "poly_utils_";
27 this->appendName(&fName);
Jim Van Verth00673692018-07-23 11:23:39 -040028 switch (fType) {
29 case Type::kConvexCheck:
30 fName.append("_c");
31 break;
32 case Type::kSimpleCheck:
33 fName.append("_s");
34 break;
35 case Type::kInsetConvex:
36 fName.append("_i");
37 break;
38 case Type::kOffsetSimple:
39 fName.append("_o");
40 break;
41 case Type::kTessellateSimple:
42 fName.append("_t");
43 break;
44 }
Jim Van Verth061cc212018-07-11 14:09:09 -040045 return fName.c_str();
46 }
47
48 void onDraw(int loops, SkCanvas* canvas) override {
49 SkTDArray<SkPoint> poly;
50 this->makePoly(&poly);
Jim Van Verth00673692018-07-23 11:23:39 -040051 switch (fType) {
52 case Type::kConvexCheck:
53 for (int i = 0; i < loops; i++) {
54 (void)SkIsConvexPolygon(poly.begin(), poly.count());
55 }
56 break;
57 case Type::kSimpleCheck:
58 for (int i = 0; i < loops; i++) {
59 (void)SkIsSimplePolygon(poly.begin(), poly.count());
60 }
61 break;
62 case Type::kInsetConvex:
63 if (SkIsConvexPolygon(poly.begin(), poly.count())) {
64 SkTDArray<SkPoint> result;
65 for (int i = 0; i < loops; i++) {
66 (void)SkInsetConvexPolygon(poly.begin(), poly.count(), 10, &result);
67 (void)SkInsetConvexPolygon(poly.begin(), poly.count(), 40, &result);
68 }
69 }
70 break;
71 case Type::kOffsetSimple:
72 if (SkIsSimplePolygon(poly.begin(), poly.count())) {
73 SkTDArray<SkPoint> result;
Jim Van Vertha5ef3972019-05-01 13:28:07 -040074 SkRect bounds;
75 bounds.setBounds(poly.begin(), poly.count());
Jim Van Verth00673692018-07-23 11:23:39 -040076 for (int i = 0; i < loops; i++) {
Jim Van Vertha5ef3972019-05-01 13:28:07 -040077 (void)SkOffsetSimplePolygon(poly.begin(), poly.count(), bounds, 10,
78 &result);
79 (void)SkOffsetSimplePolygon(poly.begin(), poly.count(), bounds, -10,
80 &result);
Jim Van Verth00673692018-07-23 11:23:39 -040081 }
82 }
83 break;
84 case Type::kTessellateSimple:
85 if (SkIsSimplePolygon(poly.begin(), poly.count())) {
86 SkAutoSTMalloc<64, uint16_t> indexMap(poly.count());
87 for (int i = 0; i < poly.count(); ++i) {
88 indexMap[i] = i;
89 }
90 SkTDArray<uint16_t> triangleIndices;
91 for (int i = 0; i < loops; i++) {
92 SkTriangulateSimplePolygon(poly.begin(), indexMap, poly.count(),
93 &triangleIndices);
94 }
95 }
96 break;
Jim Van Verth061cc212018-07-11 14:09:09 -040097 }
98 }
99
100private:
Jim Van Verth00673692018-07-23 11:23:39 -0400101 SkString fName;
102 Type fType;
103
Jim Van Verth061cc212018-07-11 14:09:09 -0400104 typedef Benchmark INHERITED;
105};
106
107class StarPolyUtilsBench : public PolyUtilsBench {
108public:
Jim Van Verth00673692018-07-23 11:23:39 -0400109 StarPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -0400110
111 void appendName(SkString* name) override {
112 name->append("star");
113 }
114 void makePoly(SkTDArray<SkPoint>* poly) override {
115 // create non-intersecting star
116 const SkScalar c = SkIntToScalar(45);
117 const SkScalar r1 = SkIntToScalar(20);
118 const SkScalar r2 = SkIntToScalar(3);
119 const int n = 500;
120 SkScalar rad = 0;
121 const SkScalar drad = SK_ScalarPI / n;
122 for (int i = 0; i < n; i++) {
Brian Osman4428f2c2019-04-02 10:59:28 -0400123 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r1, c + SkScalarSin(rad) * r1);
Jim Van Verth061cc212018-07-11 14:09:09 -0400124 rad += drad;
Brian Osman4428f2c2019-04-02 10:59:28 -0400125 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r2, c + SkScalarSin(rad) * r2);
Jim Van Verth061cc212018-07-11 14:09:09 -0400126 rad += drad;
127 }
128 }
129private:
130 typedef PolyUtilsBench INHERITED;
131};
132
133class CirclePolyUtilsBench : public PolyUtilsBench {
134public:
Jim Van Verth00673692018-07-23 11:23:39 -0400135 CirclePolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -0400136
137 void appendName(SkString* name) override {
138 name->append("circle");
139 }
140 void makePoly(SkTDArray<SkPoint>* poly) override {
141 // create circle with many vertices
142 const SkScalar c = SkIntToScalar(45);
143 const SkScalar r = SkIntToScalar(20);
144 const int n = 1000;
145 SkScalar rad = 0;
146 const SkScalar drad = 2 * SK_ScalarPI / n;
147 for (int i = 0; i < n; i++) {
Brian Osman4428f2c2019-04-02 10:59:28 -0400148 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
Jim Van Verth061cc212018-07-11 14:09:09 -0400149 rad += drad;
150 }
151 }
152private:
153 typedef PolyUtilsBench INHERITED;
154};
155
156class IntersectingPolyUtilsBench : public PolyUtilsBench {
157public:
Jim Van Verth00673692018-07-23 11:23:39 -0400158 IntersectingPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
Jim Van Verth061cc212018-07-11 14:09:09 -0400159
160 void appendName(SkString* name) override {
161 name->append("intersecting");
162 }
163 void makePoly(SkTDArray<SkPoint>* poly) override {
164 // create self-intersecting star
165 const SkScalar c = SkIntToScalar(45);
166 const SkScalar r = SkIntToScalar(20);
167 const int n = 1000;
168
169 SkScalar rad = -SK_ScalarPI / 2;
170 const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
171 *poly->push() = SkPoint::Make(c, c - r);
172 for (int i = 1; i < n; i++) {
173 rad += drad;
Brian Osman4428f2c2019-04-02 10:59:28 -0400174 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
Jim Van Verth061cc212018-07-11 14:09:09 -0400175 }
176 }
177private:
178 typedef PolyUtilsBench INHERITED;
179};
180
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400181// familiar videogame character
182class NotchPolyUtilsBench : public PolyUtilsBench {
183public:
184 NotchPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {}
185
186 void appendName(SkString* name) override {
187 name->append("notch");
188 }
189 void makePoly(SkTDArray<SkPoint>* poly) override {
190 // create 3/4 circle with many vertices
191 const SkScalar c = SkIntToScalar(45);
192 const SkScalar r = SkIntToScalar(20);
193 const int n = 1000;
194 SkScalar rad = 0;
195 const SkScalar drad = 3 * SK_ScalarPI / (2*n);
196 for (int i = 0; i < n; i++) {
Brian Osman4428f2c2019-04-02 10:59:28 -0400197 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400198 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++) {
Brian Osman4428f2c2019-04-02 10:59:28 -0400222 *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r);
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400223 rad += drad;
224 }
225 // and the tip of the cone
226 *poly->push() = SkPoint::Make(90, 0);
227 }
228private:
229 typedef PolyUtilsBench INHERITED;
230};
231
Jim Van Verth00673692018-07-23 11:23:39 -0400232DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
233DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
234DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
235DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
236DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
237DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
238DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
239DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
240DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
241DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
242DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
243DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
244DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
245DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
246DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
Jim Van Verth0f1bb922018-09-20 11:25:04 -0400247DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
248DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
249DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
250DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
251DEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
252DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
253DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
254DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
255DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
256DEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
257