• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "SkBenchmark.h"
2 #include "SkColorPriv.h"
3 #include "SkRandom.h"
4 #include "SkString.h"
5 
6 template <bool kFast, bool kScale>
7 class FourByteInterpBench : public SkBenchmark {
8 public:
FourByteInterpBench()9     FourByteInterpBench() {
10         fName.set("four_byte_interp");
11         fName.append(kFast ? "_fast" : "_slow");
12         fName.append(kScale ? "_255" : "_256");
13     }
14 
isSuitableFor(Backend backend)15     virtual bool isSuitableFor(Backend backend) SK_OVERRIDE {
16         return backend == kNonRendering_Backend;
17     }
18 
onGetName()19     virtual const char* onGetName() SK_OVERRIDE { return fName.c_str(); }
20 
onPreDraw()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 
onDraw(const int loops,SkCanvas *)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