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 "SkTRegistry.h"
     15 
     16 #define DEF_BENCH(code)                                                 \
     17 namespace {                                                             \
     18 static Benchmark* SK_MACRO_APPEND_LINE(factory)(void*) { code; }      \
     19 BenchRegistry SK_MACRO_APPEND_LINE(g_R_)(SK_MACRO_APPEND_LINE(factory)); \
     20 }
     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 
     32 class SkCanvas;
     33 class SkPaint;
     34 
     35 class SkTriState {
     36 public:
     37     enum State {
     38         kDefault,
     39         kTrue,
     40         kFalse
     41     };
     42     static const char* Name[];
     43 };
     44 
     45 class Benchmark : public SkRefCnt {
     46 public:
     47     SK_DECLARE_INST_COUNT(Benchmark)
     48 
     49     Benchmark();
     50 
     51     const char* getName();
     52     const char* getUniqueName();
     53     SkIPoint getSize();
     54 
     55     enum Backend {
     56         kNonRendering_Backend,
     57         kRaster_Backend,
     58         kGPU_Backend,
     59         kPDF_Backend,
     60     };
     61 
     62     // Call to determine whether the benchmark is intended for
     63     // the rendering mode.
     64     virtual bool isSuitableFor(Backend backend) {
     65         return backend != kNonRendering_Backend;
     66     }
     67 
     68     // Call before draw, allows the benchmark to do setup work outside of the
     69     // timer. When a benchmark is repeatedly drawn, this should be called once
     70     // before the initial draw.
     71     void preDraw();
     72 
     73     // Bench framework can tune loops to be large enough for stable timing.
     74     void draw(const int loops, SkCanvas*);
     75 
     76     void setForceAlpha(int alpha) {
     77         fForceAlpha = alpha;
     78     }
     79 
     80     void setDither(SkTriState::State state) {
     81         fDither = state;
     82     }
     83 
     84     /** Assign masks for paint-flags. These will be applied when setupPaint()
     85      *  is called.
     86      *
     87      *  Performs the following on the paint:
     88      *      uint32_t flags = paint.getFlags();
     89      *      flags &= ~clearMask;
     90      *      flags |= orMask;
     91      *      paint.setFlags(flags);
     92      */
     93     void setPaintMasks(uint32_t orMask, uint32_t clearMask) {
     94         fOrMask = orMask;
     95         fClearMask = clearMask;
     96     }
     97 
     98 protected:
     99     virtual void setupPaint(SkPaint* paint);
    100 
    101     virtual const char* onGetName() = 0;
    102     virtual const char* onGetUniqueName() { return this->onGetName(); }
    103     virtual void onPreDraw() {}
    104     // Each bench should do its main work in a loop like this:
    105     //   for (int i = 0; i < loops; i++) { <work here> }
    106     virtual void onDraw(const int loops, SkCanvas*) = 0;
    107 
    108     virtual SkIPoint onGetSize();
    109 
    110 private:
    111     int     fForceAlpha;
    112     SkTriState::State  fDither;
    113     uint32_t    fOrMask, fClearMask;
    114 
    115     typedef SkRefCnt INHERITED;
    116 };
    117 
    118 typedef SkTRegistry<Benchmark*(*)(void*)> BenchRegistry;
    119 
    120 #endif
    121