| /* | |
| * Copyright 2013 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #include "bench/Benchmark.h" | |
| #include "include/core/SkString.h" | |
| #include "src/core/SkColorData.h" | |
| #include "src/core/SkRandom.h" | |
| #include <array> | |
| template <bool kFast, bool kScale> | |
| class FourByteInterpBench : public Benchmark { | |
| public: | |
| FourByteInterpBench() { | |
| fName.set("four_byte_interp"); | |
| fName.append(kFast ? "_fast" : "_slow"); | |
| fName.append(kScale ? "_255" : "_256"); | |
| } | |
| bool isSuitableFor(Backend backend) override { | |
| return backend == Backend::kNonRendering; | |
| } | |
| const char* onGetName() override { return fName.c_str(); } | |
| void onDelayedSetup() override { | |
| // A handful of random srcs and dsts. | |
| SkRandom rand; | |
| for (int i = 0; i < kInputs; i++) { | |
| fSrcs[i] = SkPreMultiplyColor(rand.nextU()); | |
| fDsts[i] = SkPreMultiplyColor(rand.nextU()); | |
| } | |
| // We'll exhaustively test all scales instead of using random numbers. | |
| for (int i = 0; i <= 256; i++) { | |
| fScales[i] = i; | |
| } | |
| if (kScale) fScales[256] = 255; // We'll just do 255 twice if we're limited to [0,255]. | |
| } | |
| void onDraw(int loops, SkCanvas*) override { | |
| // We xor results of FourByteInterp into junk to make sure the function runs. | |
| [[maybe_unused]] volatile SkPMColor junk = 0; | |
| for (int loop = 0; loop < loops; loop++) { | |
| for (int i = 0; i < kInputs; i++) { | |
| for (size_t j = 0; j <= 256; j++) { | |
| // Note: we really want to load src and dst here and not outside in the i-loop. | |
| // If we put the loads there, a clever compiler will do the not-insignificant | |
| // work in the FourByteInterps that depends only on src and dst outside this | |
| // loop, so we'd only be benchmarking the back half of those functions that also | |
| // depends on scale. Even here, these must be volatile arrays to prevent that | |
| // clever compiler from hoisting the loads out of the loop on its own. | |
| const SkPMColor src = fSrcs[i]; | |
| const SkPMColor dst = fDsts[i]; | |
| const unsigned scale = fScales[j]; | |
| if (kFast && kScale) { | |
| junk = SkFastFourByteInterp(src, dst, scale); | |
| } else if (kFast) { | |
| junk = SkFastFourByteInterp256(src, dst, scale); | |
| } else if (kScale) { | |
| junk = SkFourByteInterp(src, dst, scale); | |
| } else { | |
| junk = SkFourByteInterp256(src, dst, scale); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| private: | |
| SkString fName; | |
| static const int kInputs = 10; // Arbitrary. | |
| std::array<volatile unsigned int, kInputs> fSrcs; | |
| std::array<volatile unsigned int, kInputs> fDsts; | |
| std::array<unsigned int, 257> fScales; // We need space for [0, 256]. | |
| }; | |
| #define COMMA , | |
| DEF_BENCH(return (new FourByteInterpBench<true COMMA true>);) | |
| DEF_BENCH(return (new FourByteInterpBench<true COMMA false>);) | |
| DEF_BENCH(return (new FourByteInterpBench<false COMMA true>);) | |
| DEF_BENCH(return (new FourByteInterpBench<false COMMA false>);) | |
| #undef COMMA |