1 /* 2 * Copyright 2011 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 #ifndef Benchmark_DEFINED 9 #define Benchmark_DEFINED 10 11 #include "include/core/SkPoint.h" 12 #include "include/core/SkRefCnt.h" 13 #include "include/core/SkString.h" 14 #include "tools/Registry.h" 15 16 #define DEF_BENCH3(code, N) \ 17 static BenchRegistry gBench##N([](void*) -> Benchmark* { code; }); 18 #define DEF_BENCH2(code, N) DEF_BENCH3(code, N) 19 #define DEF_BENCH(code) DEF_BENCH2(code, __COUNTER__) 20 21 /* 22 * With the above macros, you can register benches as follows (at the bottom 23 * of your .cpp) 24 * 25 * DEF_BENCH(return new MyBenchmark(...)) 26 * DEF_BENCH(return new MyBenchmark(...)) 27 * DEF_BENCH(return new MyBenchmark(...)) 28 */ 29 30 struct GrContextOptions; 31 class SkCanvas; 32 class SkPaint; 33 34 class Benchmark : public SkRefCnt { 35 public: 36 Benchmark(); 37 38 const char* getName(); 39 const char* getUniqueName(); 40 SkIPoint getSize(); 41 42 enum Backend { 43 kNonRendering_Backend, 44 kRaster_Backend, 45 kGPU_Backend, 46 kPDF_Backend, 47 kHWUI_Backend, 48 }; 49 50 // Call to determine whether the benchmark is intended for 51 // the rendering mode. isSuitableFor(Backend backend)52 virtual bool isSuitableFor(Backend backend) { 53 return backend != kNonRendering_Backend; 54 } 55 56 // Allows a benchmark to override options used to construct the GrContext. modifyGrContextOptions(GrContextOptions *)57 virtual void modifyGrContextOptions(GrContextOptions*) {} 58 calculateLoops(int defaultLoops)59 virtual int calculateLoops(int defaultLoops) const { 60 return defaultLoops; 61 } 62 63 // Call before draw, allows the benchmark to do setup work outside of the 64 // timer. When a benchmark is repeatedly drawn, this should be called once 65 // before the initial draw. 66 void delayedSetup(); 67 68 // Called once before and after a series of draw calls to a single canvas. 69 // The setup/break down in these calls is not timed. 70 void perCanvasPreDraw(SkCanvas*); 71 void perCanvasPostDraw(SkCanvas*); 72 73 // Called just before and after each call to draw(). Not timed. 74 void preDraw(SkCanvas*); 75 void postDraw(SkCanvas*); 76 77 // Bench framework can tune loops to be large enough for stable timing. 78 void draw(int loops, SkCanvas*); 79 getGpuStats(SkCanvas *,SkTArray<SkString> * keys,SkTArray<double> * values)80 virtual void getGpuStats(SkCanvas*, SkTArray<SkString>* keys, SkTArray<double>* values) {} 81 82 // Count of units (pixels, whatever) being exercised, to scale timing by. getUnits()83 int getUnits() const { return fUnits; } 84 85 protected: setUnits(int units)86 void setUnits(int units) { SkASSERT(units > 0); fUnits = units; } 87 88 virtual void setupPaint(SkPaint* paint); 89 90 virtual const char* onGetName() = 0; onGetUniqueName()91 virtual const char* onGetUniqueName() { return this->onGetName(); } onDelayedSetup()92 virtual void onDelayedSetup() {} onPerCanvasPreDraw(SkCanvas *)93 virtual void onPerCanvasPreDraw(SkCanvas*) {} onPerCanvasPostDraw(SkCanvas *)94 virtual void onPerCanvasPostDraw(SkCanvas*) {} onPreDraw(SkCanvas *)95 virtual void onPreDraw(SkCanvas*) {} onPostDraw(SkCanvas *)96 virtual void onPostDraw(SkCanvas*) {} 97 // Each bench should do its main work in a loop like this: 98 // for (int i = 0; i < loops; i++) { <work here> } 99 virtual void onDraw(int loops, SkCanvas*) = 0; 100 101 virtual SkIPoint onGetSize(); 102 103 private: 104 int fUnits = 1; 105 106 typedef SkRefCnt INHERITED; 107 }; 108 109 typedef sk_tools::Registry<Benchmark*(*)(void*)> BenchRegistry; 110 111 #endif 112