1 /* 2 * Copyright 2014 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 "SkGeometry.h" 10 #include "SkRandom.h" 11 #include "SkRect.h" 12 13 class GeometryBench : public Benchmark { 14 public: 15 GeometryBench(const char suffix[]) : fVolatileInt(0) { 16 fName.printf("geo_%s", suffix); 17 } 18 19 const char* onGetName() override { 20 return fName.c_str(); 21 } 22 23 bool isSuitableFor(Backend backend) override { 24 return kNonRendering_Backend == backend; 25 } 26 27 protected: 28 volatile int fVolatileInt; 29 30 /** 31 * Subclasses can call this to try to defeat the optimizer (with some result of their 32 * inner loop), since it will fool the compiler into assuming that "n" is actually 33 * needed somewhere, and since this method is not const, the member fields cannot 34 * be assumed to be const before and after the call. 35 */ 36 virtual void virtualCallToFoilOptimizers(int n) { fVolatileInt += n; } 37 38 private: 39 SkString fName; 40 }; 41 42 class GeoRectBench : public GeometryBench { 43 public: 44 GeoRectBench(const char suffix[]) : GeometryBench(suffix) {} 45 46 protected: 47 SkRect fRects[2048]; 48 49 virtual void onDelayedSetup() { 50 const SkScalar min = -100; 51 const SkScalar max = 100; 52 SkRandom rand; 53 for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) { 54 SkScalar x = rand.nextRangeScalar(min, max); 55 SkScalar y = rand.nextRangeScalar(min, max); 56 SkScalar w = rand.nextRangeScalar(min, max); 57 SkScalar h = rand.nextRangeScalar(min, max); 58 fRects[i].setXYWH(x, y, w, h); 59 } 60 } 61 }; 62 63 class GeoRectBench_intersect : public GeoRectBench { 64 public: 65 GeoRectBench_intersect() : GeoRectBench("rect_intersect") {} 66 67 protected: 68 void onDraw(int loops, SkCanvas* canvas) override { 69 for (int outer = 0; outer < loops; ++outer) { 70 int count = 0; 71 for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) { 72 SkRect r = fRects[0]; 73 count += r.intersect(fRects[i]); 74 } 75 this->virtualCallToFoilOptimizers(count); 76 } 77 } 78 }; 79 80 class GeoRectBench_intersect_rect : public GeoRectBench { 81 public: 82 GeoRectBench_intersect_rect() : GeoRectBench("rect_intersect_rect") {} 83 84 protected: 85 void onDraw(int loops, SkCanvas* canvas) override { 86 for (int outer = 0; outer < loops; ++outer) { 87 int count = 0; 88 SkRect r; 89 for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) { 90 count += r.intersect(fRects[0], fRects[i]); 91 } 92 this->virtualCallToFoilOptimizers(count); 93 } 94 } 95 }; 96 97 class GeoRectBench_Intersects : public GeoRectBench { 98 public: 99 GeoRectBench_Intersects() : GeoRectBench("rect_Intersects") {} 100 101 protected: 102 void onDraw(int loops, SkCanvas* canvas) override { 103 for (int outer = 0; outer < loops; ++outer) { 104 int count = 0; 105 for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) { 106 count += SkRect::Intersects(fRects[0], fRects[i]); 107 } 108 this->virtualCallToFoilOptimizers(count); 109 } 110 } 111 }; 112 113 class GeoRectBench_sort : public GeoRectBench { 114 public: 115 GeoRectBench_sort() : GeoRectBench("rect_sort") {} 116 117 protected: 118 void onDraw(int loops, SkCanvas* canvas) override { 119 for (int outer = 0; outer < loops; ++outer) { 120 for (size_t i = 0; i < SK_ARRAY_COUNT(fRects); ++i) { 121 fRects[i].sort(); 122 } 123 } 124 } 125 }; 126 127 DEF_BENCH( return new GeoRectBench_intersect; ) 128 DEF_BENCH( return new GeoRectBench_intersect_rect; ) 129 DEF_BENCH( return new GeoRectBench_Intersects; ) 130 131 DEF_BENCH( return new GeoRectBench_sort; ) 132 133 /////////////////////////////////////////////////////////////////////////////////////////////////// 134 135 class QuadBenchBase : public GeometryBench { 136 protected: 137 SkPoint fPts[4]; 138 public: 139 QuadBenchBase(const char name[]) : GeometryBench(name) { 140 SkRandom rand; 141 for (int i = 0; i < 4; ++i) { 142 fPts[i].set(rand.nextUScalar1(), rand.nextUScalar1()); 143 } 144 } 145 }; 146 147 class EvalQuadAt0 : public QuadBenchBase { 148 public: 149 EvalQuadAt0() : QuadBenchBase("evalquadat0") {} 150 protected: 151 void onDraw(int loops, SkCanvas* canvas) override { 152 SkPoint result; 153 for (int outer = 0; outer < loops; ++outer) { 154 SkEvalQuadAt(fPts, 0.5f, &result); 155 SkEvalQuadAt(fPts, 0.5f, &result); 156 SkEvalQuadAt(fPts, 0.5f, &result); 157 SkEvalQuadAt(fPts, 0.5f, &result); 158 } 159 } 160 }; 161 DEF_BENCH( return new EvalQuadAt0; ) 162 163 class EvalQuadAt1 : public QuadBenchBase { 164 public: 165 EvalQuadAt1() : QuadBenchBase("evalquadat1") {} 166 protected: 167 void onDraw(int loops, SkCanvas* canvas) override { 168 SkPoint result; 169 for (int outer = 0; outer < loops; ++outer) { 170 result = SkEvalQuadAt(fPts, 0.5f); 171 result = SkEvalQuadAt(fPts, 0.5f); 172 result = SkEvalQuadAt(fPts, 0.5f); 173 result = SkEvalQuadAt(fPts, 0.5f); 174 } 175 } 176 }; 177 DEF_BENCH( return new EvalQuadAt1; ) 178 179 //////// 180 181 class EvalQuadTangentAt0 : public QuadBenchBase { 182 public: 183 EvalQuadTangentAt0() : QuadBenchBase("evalquadtangentat0") {} 184 protected: 185 void onDraw(int loops, SkCanvas* canvas) override { 186 SkPoint result; 187 for (int outer = 0; outer < loops; ++outer) { 188 SkEvalQuadAt(fPts, 0.5f, nullptr, &result); 189 SkEvalQuadAt(fPts, 0.5f, nullptr, &result); 190 SkEvalQuadAt(fPts, 0.5f, nullptr, &result); 191 SkEvalQuadAt(fPts, 0.5f, nullptr, &result); 192 } 193 } 194 }; 195 DEF_BENCH( return new EvalQuadTangentAt0; ) 196 197 class EvalQuadTangentAt1 : public QuadBenchBase { 198 public: 199 EvalQuadTangentAt1() : QuadBenchBase("evalquadtangentat1") {} 200 protected: 201 void onDraw(int loops, SkCanvas* canvas) override { 202 SkPoint result; 203 for (int outer = 0; outer < loops; ++outer) { 204 result = SkEvalQuadTangentAt(fPts, 0.5f); 205 result = SkEvalQuadTangentAt(fPts, 0.5f); 206 result = SkEvalQuadTangentAt(fPts, 0.5f); 207 result = SkEvalQuadTangentAt(fPts, 0.5f); 208 } 209 } 210 }; 211 DEF_BENCH( return new EvalQuadTangentAt1; ) 212 213 //////// 214 215 class ChopQuadAt : public QuadBenchBase { 216 public: 217 ChopQuadAt() : QuadBenchBase("chopquadat") {} 218 protected: 219 void onDraw(int loops, SkCanvas* canvas) override { 220 SkPoint dst[5]; 221 for (int outer = 0; outer < loops; ++outer) { 222 SkChopQuadAt(fPts, dst, 0.5f); 223 SkChopQuadAt(fPts, dst, 0.5f); 224 SkChopQuadAt(fPts, dst, 0.5f); 225 SkChopQuadAt(fPts, dst, 0.5f); 226 } 227 } 228 }; 229 DEF_BENCH( return new ChopQuadAt; ) 230 231 class ChopCubicAt : public QuadBenchBase { 232 public: 233 ChopCubicAt() : QuadBenchBase("chopcubicat0") {} 234 protected: 235 void onDraw(int loops, SkCanvas* canvas) override { 236 SkPoint dst[7]; 237 for (int outer = 0; outer < loops; ++outer) { 238 SkChopCubicAt(fPts, dst, 0.5f); 239 SkChopCubicAt(fPts, dst, 0.5f); 240 SkChopCubicAt(fPts, dst, 0.5f); 241 SkChopCubicAt(fPts, dst, 0.5f); 242 } 243 } 244 }; 245 DEF_BENCH( return new ChopCubicAt; ) 246 247