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/SkRefCnt.h" 12 #include "include/core/SkSize.h" 13 #include "include/core/SkString.h" 14 #include "include/private/base/SkTArray.h" 15 #include "tools/Registry.h" 16 17 #if defined(SK_GRAPHITE) 18 #include "include/gpu/graphite/Context.h" 19 #endif 20 21 #define DEF_BENCH3(code, N) \ 22 static BenchRegistry gBench##N([](void*) -> Benchmark* { code; }); 23 #define DEF_BENCH2(code, N) DEF_BENCH3(code, N) 24 #define DEF_BENCH(code) DEF_BENCH2(code, __COUNTER__) 25 26 /* 27 * With the above macros, you can register benches as follows (at the bottom 28 * of your .cpp) 29 * 30 * DEF_BENCH(return new MyBenchmark(...)) 31 * DEF_BENCH(return new MyBenchmark(...)) 32 * DEF_BENCH(return new MyBenchmark(...)) 33 */ 34 35 struct GrContextOptions; 36 class GrRecordingContext; 37 class SkCanvas; 38 class SkPaint; 39 40 class Benchmark : public SkRefCnt { 41 public: 42 Benchmark(); 43 44 const char* getName(); 45 const char* getUniqueName(); 46 SkISize getSize(); 47 48 enum class Backend { 49 kNonRendering, 50 kRaster, 51 kGanesh, 52 kGraphite, 53 kPDF, 54 kHWUI, 55 }; 56 57 // Call to determine whether the benchmark is intended for 58 // the rendering mode. isSuitableFor(Backend backend)59 virtual bool isSuitableFor(Backend backend) { 60 return backend != Backend::kNonRendering; 61 } 62 63 // Allows a benchmark to override options used to construct the GrContext. modifyGrContextOptions(GrContextOptions *)64 virtual void modifyGrContextOptions(GrContextOptions*) {} 65 66 #if defined(SK_GRAPHITE) modifyGraphiteContextOptions(skgpu::graphite::ContextOptions *)67 virtual void modifyGraphiteContextOptions(skgpu::graphite::ContextOptions*) {} 68 #endif 69 70 // Whether or not this benchmark requires multiple samples to get a meaningful result. shouldLoop()71 virtual bool shouldLoop() const { 72 return true; 73 } 74 75 // Call before draw, allows the benchmark to do setup work outside of the 76 // timer. When a benchmark is repeatedly drawn, this should be called once 77 // before the initial draw. 78 void delayedSetup(); 79 80 // Called once before and after a series of draw calls to a single canvas. 81 // The setup/break down in these calls is not timed. 82 void perCanvasPreDraw(SkCanvas*); 83 void perCanvasPostDraw(SkCanvas*); 84 85 // Called just before and after each call to draw(). Not timed. 86 void preDraw(SkCanvas*); 87 void postDraw(SkCanvas*); 88 89 // Bench framework can tune loops to be large enough for stable timing. 90 void draw(int loops, SkCanvas*); 91 getGpuStats(SkCanvas *,skia_private::TArray<SkString> * keys,skia_private::TArray<double> * values)92 virtual void getGpuStats(SkCanvas*, 93 skia_private::TArray<SkString>* keys, 94 skia_private::TArray<double>* values) {} 95 96 // Replaces the GrRecordingContext's dmsaaStats() with a single frame of this benchmark. getDMSAAStats(GrRecordingContext *)97 virtual bool getDMSAAStats(GrRecordingContext*) { return false; } 98 99 // Count of units (pixels, whatever) being exercised, to scale timing by. getUnits()100 int getUnits() const { return fUnits; } 101 102 protected: setUnits(int units)103 void setUnits(int units) { SkASSERT(units > 0); fUnits = units; } 104 105 virtual void setupPaint(SkPaint* paint); 106 107 virtual const char* onGetName() = 0; onGetUniqueName()108 virtual const char* onGetUniqueName() { return this->onGetName(); } onDelayedSetup()109 virtual void onDelayedSetup() {} onPerCanvasPreDraw(SkCanvas *)110 virtual void onPerCanvasPreDraw(SkCanvas*) {} onPerCanvasPostDraw(SkCanvas *)111 virtual void onPerCanvasPostDraw(SkCanvas*) {} onPreDraw(SkCanvas *)112 virtual void onPreDraw(SkCanvas*) {} onPostDraw(SkCanvas *)113 virtual void onPostDraw(SkCanvas*) {} 114 // Each bench should do its main work in a loop like this: 115 // for (int i = 0; i < loops; i++) { <work here> } 116 virtual void onDraw(int loops, SkCanvas*) = 0; 117 118 virtual SkISize onGetSize(); 119 120 private: 121 int fUnits = 1; 122 123 using INHERITED = SkRefCnt; 124 }; 125 126 typedef sk_tools::Registry<Benchmark*(*)(void*)> BenchRegistry; 127 128 #endif 129