blob: e03c51cf8d3001710fb5c9084853cfebdc5b30e5 [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 Verth00673692018-07-23 11:23:39 -0400180DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
181DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
182DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
183DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
184DEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
185DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
186DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
187DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
188DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
189DEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)
190DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);)
191DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);)
192DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);)
193DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);)
194DEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);)