Home | History | Annotate | Download | only in bench
      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 "SkPoint.h"
     12 #include "SkRefCnt.h"
     13 #include "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.
     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.
     57     virtual void modifyGrContextOptions(GrContextOptions*) {}
     58 
     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 
     80     virtual void getGpuStats(SkCanvas*, SkTArray<SkString>* keys, SkTArray<double>* values) {}
     81 
     82 protected:
     83     virtual void setupPaint(SkPaint* paint);
     84 
     85     virtual const char* onGetName() = 0;
     86     virtual const char* onGetUniqueName() { return this->onGetName(); }
     87     virtual void onDelayedSetup() {}
     88     virtual void onPerCanvasPreDraw(SkCanvas*) {}
     89     virtual void onPerCanvasPostDraw(SkCanvas*) {}
     90     virtual void onPreDraw(SkCanvas*) {}
     91     virtual void onPostDraw(SkCanvas*) {}
     92     // Each bench should do its main work in a loop like this:
     93     //   for (int i = 0; i < loops; i++) { <work here> }
     94     virtual void onDraw(int loops, SkCanvas*) = 0;
     95 
     96     virtual SkIPoint onGetSize();
     97 
     98 private:
     99     typedef SkRefCnt INHERITED;
    100 };
    101 
    102 typedef sk_tools::Registry<Benchmark*(*)(void*)> BenchRegistry;
    103 
    104 #endif
    105