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