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