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