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 13class GeometryBench : public Benchmark { 14public: 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 27protected: 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 38private: 39 SkString fName; 40}; 41 42class GeoRectBench : public GeometryBench { 43public: 44 GeoRectBench(const char suffix[]) : GeometryBench(suffix) {} 45 46protected: 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 63class GeoRectBench_intersect : public GeoRectBench { 64public: 65 GeoRectBench_intersect() : GeoRectBench("rect_intersect") {} 66 67protected: 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 80class GeoRectBench_intersect_rect : public GeoRectBench { 81public: 82 GeoRectBench_intersect_rect() : GeoRectBench("rect_intersect_rect") {} 83 84protected: 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 97class GeoRectBench_Intersects : public GeoRectBench { 98public: 99 GeoRectBench_Intersects() : GeoRectBench("rect_Intersects") {} 100 101protected: 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 113class GeoRectBench_sort : public GeoRectBench { 114public: 115 GeoRectBench_sort() : GeoRectBench("rect_sort") {} 116 117protected: 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 127DEF_BENCH( return new GeoRectBench_intersect; ) 128DEF_BENCH( return new GeoRectBench_intersect_rect; ) 129DEF_BENCH( return new GeoRectBench_Intersects; ) 130 131DEF_BENCH( return new GeoRectBench_sort; ) 132 133/////////////////////////////////////////////////////////////////////////////////////////////////// 134 135class QuadBenchBase : public GeometryBench { 136protected: 137 SkPoint fPts[4]; 138public: 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 147class EvalQuadAt0 : public QuadBenchBase { 148public: 149 EvalQuadAt0() : QuadBenchBase("evalquadat0") {} 150protected: 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}; 161DEF_BENCH( return new EvalQuadAt0; ) 162 163class EvalQuadAt1 : public QuadBenchBase { 164public: 165 EvalQuadAt1() : QuadBenchBase("evalquadat1") {} 166protected: 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}; 177DEF_BENCH( return new EvalQuadAt1; ) 178 179//////// 180 181class EvalQuadTangentAt0 : public QuadBenchBase { 182public: 183 EvalQuadTangentAt0() : QuadBenchBase("evalquadtangentat0") {} 184protected: 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}; 195DEF_BENCH( return new EvalQuadTangentAt0; ) 196 197class EvalQuadTangentAt1 : public QuadBenchBase { 198public: 199 EvalQuadTangentAt1() : QuadBenchBase("evalquadtangentat1") {} 200protected: 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}; 211DEF_BENCH( return new EvalQuadTangentAt1; ) 212 213//////// 214 215class ChopQuadAt : public QuadBenchBase { 216public: 217 ChopQuadAt() : QuadBenchBase("chopquadat") {} 218protected: 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}; 229DEF_BENCH( return new ChopQuadAt; ) 230 231class ChopCubicAt : public QuadBenchBase { 232public: 233 ChopCubicAt() : QuadBenchBase("chopcubicat0") {} 234protected: 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}; 245DEF_BENCH( return new ChopCubicAt; ) 246