• 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/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