/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <memory>
#include "Benchmark.h"
#include "SkBitmapProcShader.h"
#include "SkColor.h"
#include "SkArenaAlloc.h"
#include "SkImage.h"
#include "SkLinearBitmapPipeline.h"
#include "SkPM4f.h"
#include "SkShader.h"

struct CommonBitmapFPBenchmark : public Benchmark {
    CommonBitmapFPBenchmark(
        SkISize srcSize,
        bool isSRGB,
        SkMatrix m,
        bool useBilerp,
        SkShader::TileMode xTile,
        SkShader::TileMode yTile)
        : fIsSRGB(isSRGB)
        , fM{m}
        , fUseBilerp{useBilerp}
        , fXTile{xTile}
        , fYTile{yTile} {
        fSrcSize = srcSize;
    }

    static SkString tileName(const char* pre, SkShader::TileMode mode) {
        SkString name{pre};
        switch (mode) {
            case SkShader::kClamp_TileMode:
                name.append("Clamp");
                return name;
            case SkShader::kRepeat_TileMode:
                name.append("Repeat");
                return name;
            case SkShader::kMirror_TileMode:
                name.append("Mirror");
                return name;
            default:
                name.append("Unknown");
                return name;
        }
    }

    const char* onGetName() override {
        fName.set("SkBitmapFP");
        if (fM.getType() & SkMatrix::kPerspective_Mask) {
            fName.append("Perspective");
        } else if (fM.getType() & SkMatrix::kAffine_Mask) {
            fName.append("Affine");
        } else if (fM.getType() & SkMatrix::kScale_Mask) {
            fName.append("Scale");
        } else if (fM.getType() & SkMatrix::kTranslate_Mask) {
            fName.append("Translate");
        } else {
            fName.append("Identity");
        }

        fName.append(tileName("X", fXTile));
        fName.append(tileName("Y", fYTile));

        if (fUseBilerp) {
            fName.append("Filter");
        } else {
            fName.append("Nearest");
        }

        fName.appendf("%s", BaseName().c_str());

        return fName.c_str();
    }

    void onPreDraw(SkCanvas*) override {
        int width = fSrcSize.fWidth;
        int height = fSrcSize.fHeight;
        fBitmap.reset(new uint32_t[width * height]);
        for (int y = 0; y < height; y++) {
            for (int x = 0; x < width; x++) {
                fBitmap[y * width + x] = (y << 8) + x + (128<<24);
            }
        }

        bool trash = fM.invert(&fInvert);
        sk_ignore_unused_variable(trash);

        fInfo = SkImageInfo::MakeN32Premul(width, height, fIsSRGB ?
                                      SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named) : nullptr);
    }

    bool isSuitableFor(Backend backend) override {
        return backend == kNonRendering_Backend;
    }

    virtual SkString BaseName() = 0;

    SkString fName;
    SkISize fSrcSize;
    bool fIsSRGB;
    SkMatrix fM;
    SkMatrix fInvert;
    bool fUseBilerp;
    SkShader::TileMode fXTile;
    SkShader::TileMode fYTile;
    SkImageInfo fInfo;
    std::unique_ptr<uint32_t[]> fBitmap;
};

struct SkBitmapFPGeneral final : public CommonBitmapFPBenchmark {
    SkBitmapFPGeneral(
        SkISize srcSize,
        bool isSRGB,
        SkMatrix m,
        bool useBilerp,
        SkShader::TileMode xTile,
        SkShader::TileMode yTile)
            : CommonBitmapFPBenchmark(srcSize, isSRGB, m, useBilerp, xTile, yTile) { }

    SkString BaseName() override {
        SkString name;
        if (fInfo.gammaCloseToSRGB()) {
            name.set("sRGB");
        } else {
            name.set("Linr");
        }
        return name;
    }

    void onDraw(int loops, SkCanvas*) override {
        int width = fSrcSize.fWidth;
        int height = fSrcSize.fHeight;

        SkAutoTMalloc<SkPM4f> FPbuffer(width*height);

        SkFilterQuality filterQuality;
        if (fUseBilerp) {
            filterQuality = SkFilterQuality::kLow_SkFilterQuality;
        } else {
            filterQuality = SkFilterQuality::kNone_SkFilterQuality;
        }

        SkPixmap srcPixmap{fInfo, fBitmap.get(), static_cast<size_t>(4 * width)};


        char storage[600];
        SkArenaAlloc allocator{storage, sizeof(storage), 512};
        SkLinearBitmapPipeline pipeline{
            fInvert, filterQuality, fXTile, fYTile, SK_ColorBLACK, srcPixmap, &allocator};

        int count = 100;

        for (int n = 0; n < 1000*loops; n++) {
            pipeline.shadeSpan4f(3, 6, FPbuffer, count);
        }
    }
};

struct SkBitmapFPOrigShader : public CommonBitmapFPBenchmark {
    SkBitmapFPOrigShader(
        SkISize srcSize,
        bool isSRGB,
        SkMatrix m,
        bool useBilerp,
        SkShader::TileMode xTile,
        SkShader::TileMode yTile)
            : CommonBitmapFPBenchmark(srcSize, isSRGB, m, useBilerp, xTile, yTile) { }

    SkString BaseName() override {
        SkString name{"Orig"};
        return name;
    }

    void onPreDraw(SkCanvas* c) override {
        CommonBitmapFPBenchmark::onPreDraw(c);

        fImage = SkImage::MakeRasterCopy(
            SkPixmap(fInfo, fBitmap.get(), sizeof(SkPMColor) * fSrcSize.fWidth));
        fPaint.setShader(fImage->makeShader(fXTile, fYTile));
        if (fUseBilerp) {
            fPaint.setFilterQuality(SkFilterQuality::kLow_SkFilterQuality);
        } else {
            fPaint.setFilterQuality(SkFilterQuality::kNone_SkFilterQuality);
        }
    }

    void onPostDraw(SkCanvas*) override {

    }

    void onDraw(int loops, SkCanvas*) override {
        int width = fSrcSize.fWidth;
        int height = fSrcSize.fHeight;

        SkAutoTMalloc<SkPMColor> buffer4b(width*height);

        uint32_t storage[kSkBlitterContextSize];
        const SkShader::ContextRec rec(fPaint, fM, nullptr,
                                       SkShader::ContextRec::kPMColor_DstType,
                                       nullptr);
        SkASSERT(fPaint.getShader()->contextSize(rec) <= sizeof(storage));
        SkShader::Context* ctx = fPaint.getShader()->createContext(rec, storage);

        int count = 100;

        for (int n = 0; n < 1000*loops; n++) {
            ctx->shadeSpan(3, 6, buffer4b, count);
        }

        ctx->~Context();
    }
    SkPaint fPaint;
    sk_sp<SkImage> fImage;
};

const bool gSRGB = true;
const bool gLinearRGB = false;
static SkISize srcSize = SkISize::Make(120, 100);
static SkMatrix mI = SkMatrix::I();
DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gSRGB, mI, false,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gLinearRGB, mI, false,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPOrigShader(
    srcSize, gLinearRGB, mI, false,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gSRGB, mI, true,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gLinearRGB, mI, true,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPOrigShader(
    srcSize, gLinearRGB, mI, true,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

static SkMatrix mS = SkMatrix::MakeScale(2.7f, 2.7f);
DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gSRGB, mS, false,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gLinearRGB, mS, false,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPOrigShader(
    srcSize, gLinearRGB, mS, false,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gSRGB, mS, true,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gLinearRGB, mS, true,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPOrigShader(
    srcSize, gLinearRGB, mS, true,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

// Repeat
DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gSRGB, mS, false,
    SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gLinearRGB, mS, false,
    SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)

DEF_BENCH(return new SkBitmapFPOrigShader(
    srcSize, gLinearRGB, mS, false,
    SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gSRGB, mS, true,
    SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gLinearRGB, mS, true,
    SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)

DEF_BENCH(return new SkBitmapFPOrigShader(
    srcSize, gLinearRGB, mS, true,
    SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)

static SkMatrix rotate(SkScalar r) {
    SkMatrix m;
    m.setRotate(30);
    return m;
}

static SkMatrix mR = rotate(30);
DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gSRGB, mR, false,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gLinearRGB, mR, false,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPOrigShader(
    srcSize, gLinearRGB, mR, false,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gSRGB, mR, true,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gLinearRGB, mR, true,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

DEF_BENCH(return new SkBitmapFPOrigShader(
    srcSize, gLinearRGB, mR, true,
    SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);)

// Repeat
DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gSRGB, mR, false,
    SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gLinearRGB, mR, false,
    SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)

DEF_BENCH(return new SkBitmapFPOrigShader(
    srcSize, gLinearRGB, mR, false,
    SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gSRGB, mR, true,
    SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)

DEF_BENCH(return new SkBitmapFPGeneral(
    srcSize, gLinearRGB, mR, true,
    SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)

DEF_BENCH(return new SkBitmapFPOrigShader(
    srcSize, gLinearRGB, mR, true,
    SkShader::kRepeat_TileMode, SkShader::kRepeat_TileMode);)
