• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "bench/Benchmark.h"
8 #include "include/core/SkString.h"
9 #include "include/private/SkColorData.h"
10 #include "include/utils/SkRandom.h"
11 
12 template <bool kFast, bool kScale>
13 class FourByteInterpBench : public Benchmark {
14 public:
FourByteInterpBench()15     FourByteInterpBench() {
16         fName.set("four_byte_interp");
17         fName.append(kFast ? "_fast" : "_slow");
18         fName.append(kScale ? "_255" : "_256");
19     }
20 
isSuitableFor(Backend backend)21     bool isSuitableFor(Backend backend) override {
22         return backend == kNonRendering_Backend;
23     }
24 
onGetName()25     const char* onGetName() override { return fName.c_str(); }
26 
onDelayedSetup()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 
onDraw(int loops,SkCanvas *)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