blob: 1b987fa038a15c199f68097c491562bdb5c86a0b [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 {
12 // Evaluate SkTriangulateSimplePolygon's performance (via derived classes) on:
13 // a non-self-intersecting star, a circle of tiny line segments and a self-intersecting star
14
15 SkString fName;
16public:
17 PolyUtilsBench() {}
18
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);
27 return fName.c_str();
28 }
29
30 void onDraw(int loops, SkCanvas* canvas) override {
31 SkTDArray<SkPoint> poly;
32 this->makePoly(&poly);
33 SkAutoSTMalloc<64, uint16_t> indexMap(poly.count());
34 for (int i = 0; i < poly.count(); ++i) {
35 indexMap[i] = i;
36 }
37 SkTDArray<uint16_t> triangleIndices;
38 for (int i = 0; i < loops; i++) {
39 if (SkIsSimplePolygon(poly.begin(), poly.count())) {
40 SkTriangulateSimplePolygon(poly.begin(), indexMap, poly.count(),
41 &triangleIndices);
42 }
43 }
44 }
45
46private:
47 typedef Benchmark INHERITED;
48};
49
50class StarPolyUtilsBench : public PolyUtilsBench {
51public:
52 StarPolyUtilsBench() {}
53
54 void appendName(SkString* name) override {
55 name->append("star");
56 }
57 void makePoly(SkTDArray<SkPoint>* poly) override {
58 // create non-intersecting star
59 const SkScalar c = SkIntToScalar(45);
60 const SkScalar r1 = SkIntToScalar(20);
61 const SkScalar r2 = SkIntToScalar(3);
62 const int n = 500;
63 SkScalar rad = 0;
64 const SkScalar drad = SK_ScalarPI / n;
65 for (int i = 0; i < n; i++) {
66 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
67 *poly->push() = SkPoint::Make(c + cosV * r1, c + sinV * r1);
68 rad += drad;
69 sinV = SkScalarSinCos(rad, &cosV);
70 *poly->push() = SkPoint::Make(c + cosV * r2, c + sinV * r2);
71 rad += drad;
72 }
73 }
74private:
75 typedef PolyUtilsBench INHERITED;
76};
77
78class CirclePolyUtilsBench : public PolyUtilsBench {
79public:
80 CirclePolyUtilsBench() {}
81
82 void appendName(SkString* name) override {
83 name->append("circle");
84 }
85 void makePoly(SkTDArray<SkPoint>* poly) override {
86 // create circle with many vertices
87 const SkScalar c = SkIntToScalar(45);
88 const SkScalar r = SkIntToScalar(20);
89 const int n = 1000;
90 SkScalar rad = 0;
91 const SkScalar drad = 2 * SK_ScalarPI / n;
92 for (int i = 0; i < n; i++) {
93 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
94 *poly->push() = SkPoint::Make(c + cosV * r, c + sinV * r);
95 rad += drad;
96 }
97 }
98private:
99 typedef PolyUtilsBench INHERITED;
100};
101
102class IntersectingPolyUtilsBench : public PolyUtilsBench {
103public:
104 IntersectingPolyUtilsBench() {}
105
106 void appendName(SkString* name) override {
107 name->append("intersecting");
108 }
109 void makePoly(SkTDArray<SkPoint>* poly) override {
110 // create self-intersecting star
111 const SkScalar c = SkIntToScalar(45);
112 const SkScalar r = SkIntToScalar(20);
113 const int n = 1000;
114
115 SkScalar rad = -SK_ScalarPI / 2;
116 const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n;
117 *poly->push() = SkPoint::Make(c, c - r);
118 for (int i = 1; i < n; i++) {
119 rad += drad;
120 SkScalar cosV, sinV = SkScalarSinCos(rad, &cosV);
121 *poly->push() = SkPoint::Make(c + cosV * r, c + sinV * r);
122 }
123 }
124private:
125 typedef PolyUtilsBench INHERITED;
126};
127
128DEF_BENCH(return new StarPolyUtilsBench();)
129DEF_BENCH(return new CirclePolyUtilsBench();)
130DEF_BENCH(return new IntersectingPolyUtilsBench();)