#include "Benchmark.h"
#include "SkColorPriv.h"
#include "SkRandom.h"
#include "SkString.h"

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 == kNonRendering_Backend;
    }

    const char* onGetName() override { return fName.c_str(); }

    void onPreDraw() 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(const int loops, SkCanvas*) override {
        // We xor results of FourByteInterp into junk to make sure the function runs.
        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.
    volatile unsigned fSrcs[kInputs];
    volatile unsigned fDsts[kInputs];
    unsigned fScales[257];  // We need space for [0, 256].
};

#define COMMA ,
DEF_BENCH( return SkNEW(FourByteInterpBench<true COMMA true>); )
DEF_BENCH( return SkNEW(FourByteInterpBench<true COMMA false>); )
DEF_BENCH( return SkNEW(FourByteInterpBench<false COMMA true>); )
DEF_BENCH( return SkNEW(FourByteInterpBench<false COMMA false>); )
#undef COMMA
