xref: /aosp_15_r20/external/skia/bench/Benchmark.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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