/*
 * Copyright 2014 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/SkPaint.h"
#include "include/core/SkString.h"
#include "include/core/SkVertices.h"
#include "include/effects/SkGradientShader.h"
#include "src/utils/SkPatchUtils.h"

/**
 * This bench measures the rendering time of the call SkCanvas::drawPatch with different types of
 * input patches (regular case, with loops, a square, with a big difference between "parallel"
 * sides). This bench also tests the different combination of optional parameters for the function
 * (passing texture coordinates and colors, only textures coordinates, only colors or none).
 * Finally, it applies a scale to test if the size affects the rendering time.
 */

class PatchBench : public Benchmark {

public:

    enum VertexMode {
        kNone_VertexMode,
        kColors_VertexMode,
        kTexCoords_VertexMode,
        kBoth_VertexMode
    };

    PatchBench(SkPoint scale, VertexMode vertexMode)
    : fScale(scale)
    , fVertexMode(vertexMode) { }

    // to add name of specific class override this method
    virtual void appendName(SkString* name) {
        name->append("normal");
    }

    // to make other type of patches override this method
    virtual void setCubics() {
        const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
            //top points
            {100,100},{150,50},{250,150}, {300,100},
            //right points
            {350, 150},{250,200},
            //bottom points
            {300,300},{250,250},{150,350},{100,300},
            //left points
            {50,250},{150,50}
        };
        memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
    }

    virtual void setColors() {
        const SkColor colors[SkPatchUtils::kNumCorners] = {
            SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorCYAN
        };
        memcpy(fColors, colors, SkPatchUtils::kNumCorners * sizeof(SkColor));
    }

    virtual void setTexCoords() {
        const SkPoint texCoords[SkPatchUtils::kNumCorners] = {
            {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f,1.0f}, {0.0f, 1.0f}
        };
        memcpy(fTexCoords, texCoords, SkPatchUtils::kNumCorners * sizeof(SkPoint));
    }

    // override this method to change the shader
    virtual sk_sp<SkShader> createShader() {
        const SkColor colors[] = {
            SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE,
            SK_ColorMAGENTA, SK_ColorBLUE, SK_ColorYELLOW,
        };
        const SkPoint pts[] = { { 200.f / 4.f, 0.f }, { 3.f * 200.f / 4, 200.f } };

        return SkGradientShader::MakeLinear(pts, colors, nullptr, SK_ARRAY_COUNT(colors),
                                            SkTileMode::kMirror);
    }

protected:
    const char* onGetName() override {
        SkString vertexMode;
        switch (fVertexMode) {
            case kNone_VertexMode:
                vertexMode.set("meshlines");
                break;
            case kColors_VertexMode:
                vertexMode.set("colors");
                break;
            case kTexCoords_VertexMode:
                vertexMode.set("texs");
                break;
            case kBoth_VertexMode:
                vertexMode.set("colors_texs");
                break;
            default:
                break;
        }
        SkString type;
        this->appendName(&type);
        fName.printf("patch_%s_%s_%fx%f", type.c_str(), vertexMode.c_str(),
                    fScale.x(), fScale.y());
        return fName.c_str();
    }

    void onDelayedSetup() override {
        this->setCubics();
        this->setColors();
        this->setTexCoords();
        this->setupPaint(&fPaint);
        switch (fVertexMode) {
            case kTexCoords_VertexMode:
            case kBoth_VertexMode:
                fPaint.setShader(this->createShader());
                break;
            default:
                fPaint.setShader(nullptr);
                break;
        }
    }

    void onDraw(int loops, SkCanvas* canvas) override {
        canvas->scale(fScale.x(), fScale.y());
        for (int i = 0; i < loops; i++) {
            switch (fVertexMode) {
                case kNone_VertexMode:
                    canvas->drawPatch(fCubics, nullptr, nullptr, fPaint);
                    break;
                case kColors_VertexMode:
                    canvas->drawPatch(fCubics, fColors, nullptr, fPaint);
                    break;
                case kTexCoords_VertexMode:
                    canvas->drawPatch(fCubics, nullptr, fTexCoords, fPaint);
                    break;
                case kBoth_VertexMode:
                    canvas->drawPatch(fCubics, fColors, fTexCoords, fPaint);
                    break;
                default:
                    break;
            }
        }
    }

    SkPaint     fPaint;
    SkString    fName;
    SkVector    fScale;
    SkPoint     fCubics[12];
    SkPoint     fTexCoords[4];
    SkColor     fColors[4];
    VertexMode  fVertexMode;

    using INHERITED = Benchmark;
};

class SquarePatchBench : public PatchBench {
public:
    SquarePatchBench(SkPoint scale, VertexMode vertexMode)
    : INHERITED(scale, vertexMode) { }

    void appendName(SkString* name) override {
        name->append("square");
    }

    void setCubics() override {
        const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
            //top points
            {100,100},{150,100},{250,100}, {300,100},
            //right points
            {300, 150},{300,250},
            //bottom points
            {300,300},{250,300},{150,300},{100,300},
            //left points
            {100,250},{100,150}
        };
        memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
    }
private:
    using INHERITED = PatchBench;
};

class LODDiffPatchBench : public PatchBench {
public:
    LODDiffPatchBench(SkPoint scale, VertexMode vertexMode)
    : INHERITED(scale, vertexMode) { }

    void appendName(SkString* name) override {
        name->append("LOD_Diff");
    }

    void setCubics() override {
        const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
            //top points
            {100,175},{150,100},{250,100}, {300,0},
            //right points
            {300, 150},{300,250},
            //bottom points
            {300,400},{250,300},{150,300},{100,225},
            //left points
            {100,215},{100,185}
        };
        memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
    }
private:
    using INHERITED = PatchBench;
};

class LoopPatchBench : public PatchBench {
public:
    LoopPatchBench(SkPoint scale, VertexMode vertexMode)
    : INHERITED(scale, vertexMode) { }

    void appendName(SkString* name) override {
        name->append("loop");
    }

    void setCubics() override {
        const SkPoint points[SkPatchUtils::kNumCtrlPts] = {
            //top points
            {100,100},{300,200},{100,200}, {300,100},
            //right points
            {380, 400},{380,0},
            //bottom points
            {300,300},{250,250},{30,200},{100,300},
            //left points
            {140,325},{150,150}
        };
        memcpy(fCubics, points, SkPatchUtils::kNumCtrlPts * sizeof(SkPoint));
    }
private:
    using INHERITED = PatchBench;
};

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

DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kNone_VertexMode); )
DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kColors_VertexMode); )
DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kTexCoords_VertexMode); )
DEF_BENCH( return new PatchBench(SkVector::Make(0.1f, 0.1f), PatchBench::kBoth_VertexMode); )
DEF_BENCH( return new PatchBench(SkVector::Make(1.f, 1.0f), PatchBench::kNone_VertexMode); )
DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kColors_VertexMode); )
DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kTexCoords_VertexMode); )
DEF_BENCH( return new PatchBench(SkVector::Make(1.0f, 1.0f), PatchBench::kBoth_VertexMode); )
DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kNone_VertexMode); )
DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kColors_VertexMode); )
DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kTexCoords_VertexMode); )
DEF_BENCH( return new PatchBench(SkVector::Make(3.0f, 3.0f), PatchBench::kBoth_VertexMode); )

DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
                                       PatchBench::kNone_VertexMode); )
DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
                                       PatchBench::kColors_VertexMode); )
DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
                                       PatchBench::kTexCoords_VertexMode); )
DEF_BENCH( return new SquarePatchBench(SkVector::Make(0.1f, 0.1f),
                                       PatchBench::kBoth_VertexMode); )
DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.f, 1.0f),
                                       PatchBench::kNone_VertexMode); )
DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
                                       PatchBench::kColors_VertexMode); )
DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
                                       PatchBench::kTexCoords_VertexMode); )
DEF_BENCH( return new SquarePatchBench(SkVector::Make(1.0f, 1.0f),
                                       PatchBench::kBoth_VertexMode); )
DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
                                       PatchBench::kNone_VertexMode); )
DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
                                       PatchBench::kColors_VertexMode); )
DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
                                       PatchBench::kTexCoords_VertexMode); )
DEF_BENCH( return new SquarePatchBench(SkVector::Make(3.0f, 3.0f),
                                       PatchBench::kBoth_VertexMode); )

DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
                                       PatchBench::kNone_VertexMode); )
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
                                       PatchBench::kColors_VertexMode); )
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
                                       PatchBench::kTexCoords_VertexMode); )
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(0.1f, 0.1f),
                                       PatchBench::kBoth_VertexMode); )
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.f, 1.0f),
                                       PatchBench::kNone_VertexMode); )
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
                                       PatchBench::kColors_VertexMode); )
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
                                       PatchBench::kTexCoords_VertexMode); )
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(1.0f, 1.0f),
                                       PatchBench::kBoth_VertexMode); )
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
                                       PatchBench::kNone_VertexMode); )
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
                                       PatchBench::kColors_VertexMode); )
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
                                       PatchBench::kTexCoords_VertexMode); )
DEF_BENCH( return new LODDiffPatchBench(SkVector::Make(3.0f, 3.0f),
                                       PatchBench::kBoth_VertexMode); )

DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
                                        PatchBench::kNone_VertexMode); )
DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
                                        PatchBench::kColors_VertexMode); )
DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
                                        PatchBench::kTexCoords_VertexMode); )
DEF_BENCH( return new LoopPatchBench(SkVector::Make(0.1f, 0.1f),
                                        PatchBench::kBoth_VertexMode); )
DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.f, 1.0f),
                                        PatchBench::kNone_VertexMode); )
DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
                                        PatchBench::kColors_VertexMode); )
DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
                                        PatchBench::kTexCoords_VertexMode); )
DEF_BENCH( return new LoopPatchBench(SkVector::Make(1.0f, 1.0f),
                                        PatchBench::kBoth_VertexMode); )
DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
                                        PatchBench::kNone_VertexMode); )
DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
                                        PatchBench::kColors_VertexMode); )
DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
                                        PatchBench::kTexCoords_VertexMode); )
DEF_BENCH( return new LoopPatchBench(SkVector::Make(3.0f, 3.0f),
                                        PatchBench::kBoth_VertexMode); )

//////////////////////////////////////////////
#include "src/utils/SkPatchUtils.h"

class PatchUtilsBench : public Benchmark {
    SkString    fName;
    const bool  fLinearInterp;
public:
    PatchUtilsBench(bool linearInterp) : fLinearInterp(linearInterp) {
        fName.printf("patchutils_%s", linearInterp ? "linear" : "legacy");
    }

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

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

    void onDraw(int loops, SkCanvas*) override {
        const SkColor colors[] = { 0xFF000000, 0xFF00FF00, 0xFF0000FF, 0xFFFF0000 };
        const SkPoint pts[] = {
            { 0, 0 }, { 10, 0 }, { 20, 0 }, { 30, 0 },
            { 30,10}, { 30,20 }, { 30,30 }, { 20,30 },
            { 10,30}, { 0, 30 }, { 0, 20 }, { 0, 10 },
        };
        const SkPoint tex[] = {
            { 0, 0 }, { 10, 0 }, { 10, 10 }, { 0, 10 },
        };

        auto cs = fLinearInterp ? SkColorSpace::MakeSRGBLinear() : nullptr;
        for (int i = 0; i < 100*loops; ++i) {
            SkPatchUtils::MakeVertices(pts, colors, tex, 20, 20, cs.get());
        }
    }
};
DEF_BENCH( return new PatchUtilsBench(false); )
DEF_BENCH( return new PatchUtilsBench(true); )
