1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2018 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "bench/Benchmark.h" 9cb93a386Sopenharmony_ci#include "include/core/SkRect.h" 10cb93a386Sopenharmony_ci#include "include/private/SkTemplates.h" 11cb93a386Sopenharmony_ci#include "src/utils/SkPolyUtils.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ciclass PolyUtilsBench : public Benchmark { 14cb93a386Sopenharmony_cipublic: 15cb93a386Sopenharmony_ci // Evaluate SkTriangulateSimplePolygon's performance (via derived classes) on: 16cb93a386Sopenharmony_ci // a non-self-intersecting star, a circle of tiny line segments and a self-intersecting star 17cb93a386Sopenharmony_ci enum class Type { kConvexCheck, kSimpleCheck, kInsetConvex, kOffsetSimple, kTessellateSimple }; 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_ci PolyUtilsBench(Type type) : fType(type) {} 20cb93a386Sopenharmony_ci 21cb93a386Sopenharmony_ci virtual void appendName(SkString*) = 0; 22cb93a386Sopenharmony_ci virtual void makePoly(SkTDArray<SkPoint>* poly) = 0; 23cb93a386Sopenharmony_ci virtual int complexity() { return 0; } 24cb93a386Sopenharmony_ci 25cb93a386Sopenharmony_ciprotected: 26cb93a386Sopenharmony_ci const char* onGetName() override { 27cb93a386Sopenharmony_ci fName = "poly_utils_"; 28cb93a386Sopenharmony_ci this->appendName(&fName); 29cb93a386Sopenharmony_ci switch (fType) { 30cb93a386Sopenharmony_ci case Type::kConvexCheck: 31cb93a386Sopenharmony_ci fName.append("_c"); 32cb93a386Sopenharmony_ci break; 33cb93a386Sopenharmony_ci case Type::kSimpleCheck: 34cb93a386Sopenharmony_ci fName.append("_s"); 35cb93a386Sopenharmony_ci break; 36cb93a386Sopenharmony_ci case Type::kInsetConvex: 37cb93a386Sopenharmony_ci fName.append("_i"); 38cb93a386Sopenharmony_ci break; 39cb93a386Sopenharmony_ci case Type::kOffsetSimple: 40cb93a386Sopenharmony_ci fName.append("_o"); 41cb93a386Sopenharmony_ci break; 42cb93a386Sopenharmony_ci case Type::kTessellateSimple: 43cb93a386Sopenharmony_ci fName.append("_t"); 44cb93a386Sopenharmony_ci break; 45cb93a386Sopenharmony_ci } 46cb93a386Sopenharmony_ci return fName.c_str(); 47cb93a386Sopenharmony_ci } 48cb93a386Sopenharmony_ci 49cb93a386Sopenharmony_ci void onDraw(int loops, SkCanvas* canvas) override { 50cb93a386Sopenharmony_ci SkTDArray<SkPoint> poly; 51cb93a386Sopenharmony_ci this->makePoly(&poly); 52cb93a386Sopenharmony_ci switch (fType) { 53cb93a386Sopenharmony_ci case Type::kConvexCheck: 54cb93a386Sopenharmony_ci for (int i = 0; i < loops; i++) { 55cb93a386Sopenharmony_ci (void)SkIsConvexPolygon(poly.begin(), poly.count()); 56cb93a386Sopenharmony_ci } 57cb93a386Sopenharmony_ci break; 58cb93a386Sopenharmony_ci case Type::kSimpleCheck: 59cb93a386Sopenharmony_ci for (int i = 0; i < loops; i++) { 60cb93a386Sopenharmony_ci (void)SkIsSimplePolygon(poly.begin(), poly.count()); 61cb93a386Sopenharmony_ci } 62cb93a386Sopenharmony_ci break; 63cb93a386Sopenharmony_ci case Type::kInsetConvex: 64cb93a386Sopenharmony_ci if (SkIsConvexPolygon(poly.begin(), poly.count())) { 65cb93a386Sopenharmony_ci SkTDArray<SkPoint> result; 66cb93a386Sopenharmony_ci for (int i = 0; i < loops; i++) { 67cb93a386Sopenharmony_ci (void)SkInsetConvexPolygon(poly.begin(), poly.count(), 10, &result); 68cb93a386Sopenharmony_ci (void)SkInsetConvexPolygon(poly.begin(), poly.count(), 40, &result); 69cb93a386Sopenharmony_ci } 70cb93a386Sopenharmony_ci } 71cb93a386Sopenharmony_ci break; 72cb93a386Sopenharmony_ci case Type::kOffsetSimple: 73cb93a386Sopenharmony_ci if (SkIsSimplePolygon(poly.begin(), poly.count())) { 74cb93a386Sopenharmony_ci SkTDArray<SkPoint> result; 75cb93a386Sopenharmony_ci SkRect bounds; 76cb93a386Sopenharmony_ci bounds.setBounds(poly.begin(), poly.count()); 77cb93a386Sopenharmony_ci for (int i = 0; i < loops; i++) { 78cb93a386Sopenharmony_ci (void)SkOffsetSimplePolygon(poly.begin(), poly.count(), bounds, 10, 79cb93a386Sopenharmony_ci &result); 80cb93a386Sopenharmony_ci (void)SkOffsetSimplePolygon(poly.begin(), poly.count(), bounds, -10, 81cb93a386Sopenharmony_ci &result); 82cb93a386Sopenharmony_ci } 83cb93a386Sopenharmony_ci } 84cb93a386Sopenharmony_ci break; 85cb93a386Sopenharmony_ci case Type::kTessellateSimple: 86cb93a386Sopenharmony_ci if (SkIsSimplePolygon(poly.begin(), poly.count())) { 87cb93a386Sopenharmony_ci SkAutoSTMalloc<64, uint16_t> indexMap(poly.count()); 88cb93a386Sopenharmony_ci for (int i = 0; i < poly.count(); ++i) { 89cb93a386Sopenharmony_ci indexMap[i] = i; 90cb93a386Sopenharmony_ci } 91cb93a386Sopenharmony_ci SkTDArray<uint16_t> triangleIndices; 92cb93a386Sopenharmony_ci for (int i = 0; i < loops; i++) { 93cb93a386Sopenharmony_ci SkTriangulateSimplePolygon(poly.begin(), indexMap, poly.count(), 94cb93a386Sopenharmony_ci &triangleIndices); 95cb93a386Sopenharmony_ci } 96cb93a386Sopenharmony_ci } 97cb93a386Sopenharmony_ci break; 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci } 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ciprivate: 102cb93a386Sopenharmony_ci SkString fName; 103cb93a386Sopenharmony_ci Type fType; 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_ci using INHERITED = Benchmark; 106cb93a386Sopenharmony_ci}; 107cb93a386Sopenharmony_ci 108cb93a386Sopenharmony_ciclass StarPolyUtilsBench : public PolyUtilsBench { 109cb93a386Sopenharmony_cipublic: 110cb93a386Sopenharmony_ci StarPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {} 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ci void appendName(SkString* name) override { 113cb93a386Sopenharmony_ci name->append("star"); 114cb93a386Sopenharmony_ci } 115cb93a386Sopenharmony_ci void makePoly(SkTDArray<SkPoint>* poly) override { 116cb93a386Sopenharmony_ci // create non-intersecting star 117cb93a386Sopenharmony_ci const SkScalar c = SkIntToScalar(45); 118cb93a386Sopenharmony_ci const SkScalar r1 = SkIntToScalar(20); 119cb93a386Sopenharmony_ci const SkScalar r2 = SkIntToScalar(3); 120cb93a386Sopenharmony_ci const int n = 500; 121cb93a386Sopenharmony_ci SkScalar rad = 0; 122cb93a386Sopenharmony_ci const SkScalar drad = SK_ScalarPI / n; 123cb93a386Sopenharmony_ci for (int i = 0; i < n; i++) { 124cb93a386Sopenharmony_ci *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r1, c + SkScalarSin(rad) * r1); 125cb93a386Sopenharmony_ci rad += drad; 126cb93a386Sopenharmony_ci *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r2, c + SkScalarSin(rad) * r2); 127cb93a386Sopenharmony_ci rad += drad; 128cb93a386Sopenharmony_ci } 129cb93a386Sopenharmony_ci } 130cb93a386Sopenharmony_ciprivate: 131cb93a386Sopenharmony_ci using INHERITED = PolyUtilsBench; 132cb93a386Sopenharmony_ci}; 133cb93a386Sopenharmony_ci 134cb93a386Sopenharmony_ciclass CirclePolyUtilsBench : public PolyUtilsBench { 135cb93a386Sopenharmony_cipublic: 136cb93a386Sopenharmony_ci CirclePolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {} 137cb93a386Sopenharmony_ci 138cb93a386Sopenharmony_ci void appendName(SkString* name) override { 139cb93a386Sopenharmony_ci name->append("circle"); 140cb93a386Sopenharmony_ci } 141cb93a386Sopenharmony_ci void makePoly(SkTDArray<SkPoint>* poly) override { 142cb93a386Sopenharmony_ci // create circle with many vertices 143cb93a386Sopenharmony_ci const SkScalar c = SkIntToScalar(45); 144cb93a386Sopenharmony_ci const SkScalar r = SkIntToScalar(20); 145cb93a386Sopenharmony_ci const int n = 1000; 146cb93a386Sopenharmony_ci SkScalar rad = 0; 147cb93a386Sopenharmony_ci const SkScalar drad = 2 * SK_ScalarPI / n; 148cb93a386Sopenharmony_ci for (int i = 0; i < n; i++) { 149cb93a386Sopenharmony_ci *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r); 150cb93a386Sopenharmony_ci rad += drad; 151cb93a386Sopenharmony_ci } 152cb93a386Sopenharmony_ci } 153cb93a386Sopenharmony_ciprivate: 154cb93a386Sopenharmony_ci using INHERITED = PolyUtilsBench; 155cb93a386Sopenharmony_ci}; 156cb93a386Sopenharmony_ci 157cb93a386Sopenharmony_ciclass IntersectingPolyUtilsBench : public PolyUtilsBench { 158cb93a386Sopenharmony_cipublic: 159cb93a386Sopenharmony_ci IntersectingPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {} 160cb93a386Sopenharmony_ci 161cb93a386Sopenharmony_ci void appendName(SkString* name) override { 162cb93a386Sopenharmony_ci name->append("intersecting"); 163cb93a386Sopenharmony_ci } 164cb93a386Sopenharmony_ci void makePoly(SkTDArray<SkPoint>* poly) override { 165cb93a386Sopenharmony_ci // create self-intersecting star 166cb93a386Sopenharmony_ci const SkScalar c = SkIntToScalar(45); 167cb93a386Sopenharmony_ci const SkScalar r = SkIntToScalar(20); 168cb93a386Sopenharmony_ci const int n = 1000; 169cb93a386Sopenharmony_ci 170cb93a386Sopenharmony_ci SkScalar rad = -SK_ScalarPI / 2; 171cb93a386Sopenharmony_ci const SkScalar drad = (n >> 1) * SK_ScalarPI * 2 / n; 172cb93a386Sopenharmony_ci *poly->push() = SkPoint::Make(c, c - r); 173cb93a386Sopenharmony_ci for (int i = 1; i < n; i++) { 174cb93a386Sopenharmony_ci rad += drad; 175cb93a386Sopenharmony_ci *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r); 176cb93a386Sopenharmony_ci } 177cb93a386Sopenharmony_ci } 178cb93a386Sopenharmony_ciprivate: 179cb93a386Sopenharmony_ci using INHERITED = PolyUtilsBench; 180cb93a386Sopenharmony_ci}; 181cb93a386Sopenharmony_ci 182cb93a386Sopenharmony_ci// familiar videogame character 183cb93a386Sopenharmony_ciclass NotchPolyUtilsBench : public PolyUtilsBench { 184cb93a386Sopenharmony_cipublic: 185cb93a386Sopenharmony_ci NotchPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {} 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_ci void appendName(SkString* name) override { 188cb93a386Sopenharmony_ci name->append("notch"); 189cb93a386Sopenharmony_ci } 190cb93a386Sopenharmony_ci void makePoly(SkTDArray<SkPoint>* poly) override { 191cb93a386Sopenharmony_ci // create 3/4 circle with many vertices 192cb93a386Sopenharmony_ci const SkScalar c = SkIntToScalar(45); 193cb93a386Sopenharmony_ci const SkScalar r = SkIntToScalar(20); 194cb93a386Sopenharmony_ci const int n = 1000; 195cb93a386Sopenharmony_ci SkScalar rad = 0; 196cb93a386Sopenharmony_ci const SkScalar drad = 3 * SK_ScalarPI / (2*n); 197cb93a386Sopenharmony_ci for (int i = 0; i < n; i++) { 198cb93a386Sopenharmony_ci *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r); 199cb93a386Sopenharmony_ci rad += drad; 200cb93a386Sopenharmony_ci } 201cb93a386Sopenharmony_ci // and the mouth 202cb93a386Sopenharmony_ci *poly->push() = SkPoint::Make(45, 45); 203cb93a386Sopenharmony_ci } 204cb93a386Sopenharmony_ciprivate: 205cb93a386Sopenharmony_ci using INHERITED = PolyUtilsBench; 206cb93a386Sopenharmony_ci}; 207cb93a386Sopenharmony_ci 208cb93a386Sopenharmony_ciclass IceCreamPolyUtilsBench : public PolyUtilsBench { 209cb93a386Sopenharmony_cipublic: 210cb93a386Sopenharmony_ci IceCreamPolyUtilsBench(PolyUtilsBench::Type type) : INHERITED(type) {} 211cb93a386Sopenharmony_ci 212cb93a386Sopenharmony_ci void appendName(SkString* name) override { 213cb93a386Sopenharmony_ci name->append("icecream"); 214cb93a386Sopenharmony_ci } 215cb93a386Sopenharmony_ci void makePoly(SkTDArray<SkPoint>* poly) override { 216cb93a386Sopenharmony_ci // create 3/4 circle with many vertices 217cb93a386Sopenharmony_ci const SkScalar c = SkIntToScalar(45); 218cb93a386Sopenharmony_ci const SkScalar r = SkIntToScalar(20); 219cb93a386Sopenharmony_ci const int n = 1000; 220cb93a386Sopenharmony_ci SkScalar rad = 0; 221cb93a386Sopenharmony_ci const SkScalar drad = 3 * SK_ScalarPI / (2*n); 222cb93a386Sopenharmony_ci for (int i = 0; i < n; i++) { 223cb93a386Sopenharmony_ci *poly->push() = SkPoint::Make(c + SkScalarCos(rad) * r, c + SkScalarSin(rad) * r); 224cb93a386Sopenharmony_ci rad += drad; 225cb93a386Sopenharmony_ci } 226cb93a386Sopenharmony_ci // and the tip of the cone 227cb93a386Sopenharmony_ci *poly->push() = SkPoint::Make(90, 0); 228cb93a386Sopenharmony_ci } 229cb93a386Sopenharmony_ciprivate: 230cb93a386Sopenharmony_ci using INHERITED = PolyUtilsBench; 231cb93a386Sopenharmony_ci}; 232cb93a386Sopenharmony_ci 233cb93a386Sopenharmony_ciDEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);) 234cb93a386Sopenharmony_ciDEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);) 235cb93a386Sopenharmony_ciDEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);) 236cb93a386Sopenharmony_ciDEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);) 237cb93a386Sopenharmony_ciDEF_BENCH(return new StarPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);) 238cb93a386Sopenharmony_ciDEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);) 239cb93a386Sopenharmony_ciDEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);) 240cb93a386Sopenharmony_ciDEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);) 241cb93a386Sopenharmony_ciDEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);) 242cb93a386Sopenharmony_ciDEF_BENCH(return new CirclePolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);) 243cb93a386Sopenharmony_ciDEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);) 244cb93a386Sopenharmony_ciDEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);) 245cb93a386Sopenharmony_ciDEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);) 246cb93a386Sopenharmony_ciDEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);) 247cb93a386Sopenharmony_ciDEF_BENCH(return new IntersectingPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);) 248cb93a386Sopenharmony_ciDEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);) 249cb93a386Sopenharmony_ciDEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);) 250cb93a386Sopenharmony_ciDEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);) 251cb93a386Sopenharmony_ciDEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);) 252cb93a386Sopenharmony_ciDEF_BENCH(return new NotchPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);) 253cb93a386Sopenharmony_ciDEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kConvexCheck);) 254cb93a386Sopenharmony_ciDEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kSimpleCheck);) 255cb93a386Sopenharmony_ciDEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kInsetConvex);) 256cb93a386Sopenharmony_ciDEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kOffsetSimple);) 257cb93a386Sopenharmony_ciDEF_BENCH(return new IceCreamPolyUtilsBench(PolyUtilsBench::Type::kTessellateSimple);) 258cb93a386Sopenharmony_ci 259