Home | History | Annotate | Download | only in bench
      1 #include "Benchmark.h"
      2 #include "SkColorPriv.h"
      3 #include "SkRandom.h"
      4 #include "SkString.h"
      5 
      6 template <bool kFast, bool kScale>
      7 class FourByteInterpBench : public Benchmark {
      8 public:
      9     FourByteInterpBench() {
     10         fName.set("four_byte_interp");
     11         fName.append(kFast ? "_fast" : "_slow");
     12         fName.append(kScale ? "_255" : "_256");
     13     }
     14 
     15     virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
     16         return backend == kNonRendering_Backend;
     17     }
     18 
     19     virtual const char* onGetName() SK_OVERRIDE { return fName.c_str(); }
     20 
     21     virtual void onPreDraw() SK_OVERRIDE {
     22         // A handful of random srcs and dsts.
     23         SkRandom rand;
     24         for (int i = 0; i < kInputs; i++) {
     25             fSrcs[i] = SkPreMultiplyColor(rand.nextU());
     26             fDsts[i] = SkPreMultiplyColor(rand.nextU());
     27         }
     28 
     29         // We'll exhaustively test all scales instead of using random numbers.
     30         for (int i = 0; i <= 256; i++) {
     31             fScales[i] = i;
     32         }
     33         if (kScale) fScales[256] = 255;  // We'll just do 255 twice if we're limited to [0,255].
     34     }
     35 
     36     virtual void onDraw(const int loops, SkCanvas*) SK_OVERRIDE {
     37         // We xor results of FourByteInterp into junk to make sure the function runs.
     38         volatile SkPMColor junk = 0;
     39 
     40         for (int loop = 0; loop < loops; loop++) {
     41             for (int i = 0; i < kInputs; i++) {
     42                 for (size_t j = 0; j <= 256; j++) {
     43                     // Note: we really want to load src and dst here and not outside in the i-loop.
     44                     // If we put the loads there, a clever compiler will do the not-insignificant
     45                     // work in the FourByteInterps that depends only on src and dst outside this
     46                     // loop, so we'd only be benchmarking the back half of those functions that also
     47                     // depends on scale.  Even here, these must be volatile arrays to prevent that
     48                     // clever compiler from hoisting the loads out of the loop on its own.
     49                     const SkPMColor src = fSrcs[i];
     50                     const SkPMColor dst = fDsts[i];
     51 
     52                     const unsigned scale = fScales[j];
     53 
     54                     if (kFast && kScale) {
     55                         junk ^= SkFastFourByteInterp(src, dst, scale);
     56                     } else if (kFast) {
     57                         junk ^= SkFastFourByteInterp256(src, dst, scale);
     58                     } else if (kScale) {
     59                         junk ^= SkFourByteInterp(src, dst, scale);
     60                     } else {
     61                         junk ^= SkFourByteInterp256(src, dst, scale);
     62                     }
     63                 }
     64             }
     65         }
     66     }
     67 
     68 private:
     69     SkString fName;
     70     static const int kInputs = 10;  // Arbitrary.
     71     volatile unsigned fSrcs[kInputs];
     72     volatile unsigned fDsts[kInputs];
     73     unsigned fScales[257];  // We need space for [0, 256].
     74 };
     75 
     76 #define COMMA ,
     77 DEF_BENCH( return SkNEW(FourByteInterpBench<true COMMA true>); )
     78 DEF_BENCH( return SkNEW(FourByteInterpBench<true COMMA false>); )
     79 DEF_BENCH( return SkNEW(FourByteInterpBench<false COMMA true>); )
     80 DEF_BENCH( return SkNEW(FourByteInterpBench<false COMMA false>); )
     81 #undef COMMA
     82