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