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 "SkColorPriv.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