/*
 * Copyright 2012 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/SkCanvas.h"
#include "include/core/SkString.h"
#include "include/private/base/SkTemplates.h"
#include "src/base/SkRandom.h"
#include "src/core/SkChecksum.h"
#include "src/core/SkMD5.h"

#include <memory>

enum ChecksumType {
    kMD5_ChecksumType,
    kWyhash_ChecksumType,
};

class ComputeChecksumBench : public Benchmark {
public:
    // All instances of this benchmark compute a checksum over 64K (or slightly less, if the
    // block size doesn't divide evenly).
    constexpr static size_t kBufferSize = 64 * 1024;

    ChecksumType fType;
    size_t fBlockSize;
    SkString fName;
    std::unique_ptr<uint8_t[]> fData;

    ComputeChecksumBench(ChecksumType type, size_t blockSize) : fType(type), fBlockSize(blockSize) {
        SkASSERT(blockSize <= kBufferSize);

        switch (fType) {
            case kMD5_ChecksumType: fName = "compute_md5"; break;
            case kWyhash_ChecksumType: fName = "compute_wyhash"; break;
        }
        fName.appendf("_%d", static_cast<int>(fBlockSize));
    }

    bool isSuitableFor(Backend backend) override { return backend == kNonRendering_Backend; }
    const char* onGetName() override { return fName.c_str(); }

    void onPreDraw(SkCanvas*) override {
        fData.reset(new uint8_t[kBufferSize]);

        SkRandom rand;
        for (size_t i = 0; i < kBufferSize; ++i) {
            fData[i] = rand.nextBits(8);
        }
    }

    void onPostDraw(SkCanvas*) override {
        fData.reset();
    }

    void onDraw(int loops, SkCanvas*) override {
        volatile uint32_t result = 0;
        const size_t blockCount = kBufferSize / fBlockSize;
        const uint8_t* bufEnd = fData.get() + (blockCount * fBlockSize);
        for (int i = 0; i < loops; i++) {
            for (const uint8_t* buf = fData.get(); buf < bufEnd; buf += fBlockSize) {
                switch (fType) {
                    case kMD5_ChecksumType: {
                        SkMD5 md5;
                        md5.write(buf, fBlockSize);
                        (void)md5.finish();
                        break;
                    }
                    case kWyhash_ChecksumType:
                        result = SkChecksum::Hash32(buf, fBlockSize);
                        break;
                }
            }
        }
        sk_ignore_unused_variable(result);
    }
};

///////////////////////////////////////////////////////////////////////////////

DEF_BENCH( return new ComputeChecksumBench(kMD5_ChecksumType, 1024); )

#define DEF_CHECKSUM_BENCH(T) \
    DEF_BENCH( return new ComputeChecksumBench(T, 4); ) \
    DEF_BENCH( return new ComputeChecksumBench(T, 8); ) \
    DEF_BENCH( return new ComputeChecksumBench(T, 15); ) \
    DEF_BENCH( return new ComputeChecksumBench(T, 16); ) \
    DEF_BENCH( return new ComputeChecksumBench(T, 31); ) \
    DEF_BENCH( return new ComputeChecksumBench(T, 32); ) \
    DEF_BENCH( return new ComputeChecksumBench(T, 96); ) \
    DEF_BENCH( return new ComputeChecksumBench(T, 1024); )

DEF_CHECKSUM_BENCH(kWyhash_ChecksumType)
