blob: e6c68b59095b6421520fd86ae2622e575517cbc9 [file] [log] [blame]
tfarinaf168b862014-06-19 12:32:29 -07001#include "Benchmark.h"
commit-bot@chromium.orgc25d2212013-12-02 22:32:47 +00002#include "SkColorPriv.h"
3#include "SkRandom.h"
4#include "SkString.h"
5
6template <bool kFast, bool kScale>
tfarinaf168b862014-06-19 12:32:29 -07007class FourByteInterpBench : public Benchmark {
commit-bot@chromium.orgc25d2212013-12-02 22:32:47 +00008public:
9 FourByteInterpBench() {
10 fName.set("four_byte_interp");
11 fName.append(kFast ? "_fast" : "_slow");
12 fName.append(kScale ? "_255" : "_256");
commit-bot@chromium.orgc25d2212013-12-02 22:32:47 +000013 }
14
mtklein36352bf2015-03-25 18:17:31 -070015 bool isSuitableFor(Backend backend) override {
commit-bot@chromium.orgc25d2212013-12-02 22:32:47 +000016 return backend == kNonRendering_Backend;
17 }
18
mtklein36352bf2015-03-25 18:17:31 -070019 const char* onGetName() override { return fName.c_str(); }
commit-bot@chromium.orgc25d2212013-12-02 22:32:47 +000020
mtklein36352bf2015-03-25 18:17:31 -070021 void onPreDraw() override {
commit-bot@chromium.orgcc6db402013-12-05 16:43:08 +000022 // 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
mtklein36352bf2015-03-25 18:17:31 -070036 void onDraw(const int loops, SkCanvas*) override {
commit-bot@chromium.orgcc6db402013-12-05 16:43:08 +000037 // We xor results of FourByteInterp into junk to make sure the function runs.
commit-bot@chromium.orgc25d2212013-12-02 22:32:47 +000038 volatile SkPMColor junk = 0;
commit-bot@chromium.orgcc6db402013-12-05 16:43:08 +000039
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 }
commit-bot@chromium.orgc25d2212013-12-02 22:32:47 +000063 }
64 }
65 }
66 }
67
68private:
69 SkString fName;
commit-bot@chromium.orgcc6db402013-12-05 16:43:08 +000070 static const int kInputs = 10; // Arbitrary.
71 volatile unsigned fSrcs[kInputs];
72 volatile unsigned fDsts[kInputs];
commit-bot@chromium.orgc25d2212013-12-02 22:32:47 +000073 unsigned fScales[257]; // We need space for [0, 256].
74};
75
76#define COMMA ,
77DEF_BENCH( return SkNEW(FourByteInterpBench<true COMMA true>); )
78DEF_BENCH( return SkNEW(FourByteInterpBench<true COMMA false>); )
79DEF_BENCH( return SkNEW(FourByteInterpBench<false COMMA true>); )
80DEF_BENCH( return SkNEW(FourByteInterpBench<false COMMA false>); )
81#undef COMMA