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