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

#include "SkMatrix.h"
#include "SkPoint.h"
#include "SkString.h"

#if SK_SUPPORT_GPU
#include "GLBench.h"
#include "gl/GrGLGLSL.h"
#include "gl/GrGLInterface.h"
#include "gl/GrGLShaderVar.h"
#include "gl/GrGLUtil.h"
#include "glsl/GrGLSLCaps.h"

#include <stdio.h>

/**
 * This is a GL benchmark for comparing the performance of using vec4 or float for coverage in GLSL.
 * The generated shader code from this bench will draw several overlapping circles, one in each
 * stage, to simulate coverage calculations.  The number of circles (i.e. the number of stages) can
 * be set as a parameter.
 */

class GLVec4ScalarBench : public GLBench {
public:
    /*
     * Use float or vec4 as GLSL data type for the output coverage
     */
    enum CoverageSetup {
        kUseScalar_CoverageSetup,
        kUseVec4_CoverageSetup,
    };

    /*
     * numStages determines the number of shader stages before the XP,
     * which consequently determines how many circles are drawn
     */
    GLVec4ScalarBench(CoverageSetup coverageSetup, uint32_t numStages)
        : fCoverageSetup(coverageSetup)
        , fNumStages(numStages)
        , fVboId(0)
        , fProgram(0) {
        fName = NumStagesSetupToStr(coverageSetup, numStages);
    }

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

    void setup(const GrGLContext*) override;
    void glDraw(const int loops, const GrGLContext*) override;
    void teardown(const GrGLInterface*) override;

private:
    void setupSingleVbo(const GrGLInterface*, const SkMatrix*);
    GrGLuint setupShader(const GrGLContext*);


    static SkString NumStagesSetupToStr(CoverageSetup coverageSetup, uint32_t numStages) {
        SkString name("GLVec4ScalarBench");
        switch (coverageSetup) {
            default:
            case kUseScalar_CoverageSetup:
                name.appendf("_scalar_%u_stage", numStages);
                break;
            case kUseVec4_CoverageSetup:
                name.appendf("_vec4_%u_stage", numStages);
                break;
        }
        return name;
    }

    static const GrGLuint kScreenWidth = 800;
    static const GrGLuint kScreenHeight = 600;
    static const uint32_t kNumTriPerDraw = 512;
    static const uint32_t kVerticesPerTri = 3;

    SkString fName;
    CoverageSetup fCoverageSetup;
    uint32_t fNumStages;
    GrGLuint fVboId;
    GrGLuint fProgram;
    GrGLuint fFboTextureId;
};

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

GrGLuint GLVec4ScalarBench::setupShader(const GrGLContext* ctx) {
    const char* version = GrGLGetGLSLVersionDecl(*ctx);

    // this shader draws fNumStages overlapping circles of increasing opacity (coverage) and
    // decreasing size, with the center of each subsequent circle closer to the bottom-right
    // corner of the screen than the previous circle.

    // set up vertex shader; this is a trivial vertex shader that passes through position and color
    GrGLShaderVar aPosition("a_position", kVec2f_GrSLType, GrShaderVar::kAttribute_TypeModifier);
    GrGLShaderVar oPosition("o_position", kVec2f_GrSLType, GrShaderVar::kVaryingOut_TypeModifier);
    GrGLShaderVar aColor("a_color", kVec3f_GrSLType, GrShaderVar::kAttribute_TypeModifier);
    GrGLShaderVar oColor("o_color", kVec3f_GrSLType, GrShaderVar::kVaryingOut_TypeModifier);

    SkString vshaderTxt(version);
    aPosition.appendDecl(*ctx, &vshaderTxt);
    vshaderTxt.append(";\n");
    aColor.appendDecl(*ctx, &vshaderTxt);
    vshaderTxt.append(";\n");
    oPosition.appendDecl(*ctx, &vshaderTxt);
    vshaderTxt.append(";\n");
    oColor.appendDecl(*ctx, &vshaderTxt);
    vshaderTxt.append(";\n");

    vshaderTxt.append(
            "void main()\n"
            "{\n"
            "    gl_Position = vec4(a_position, 0.0, 1.0);\n"
            "    o_position = a_position;\n"
            "    o_color = a_color;\n"
            "}\n");

    const GrGLInterface* gl = ctx->interface();

    // set up fragment shader; this fragment shader will have fNumStages coverage stages plus an
    // XP stage at the end.  Each coverage stage computes the pixel's distance from some hard-
    // coded center and compare that to some hard-coded circle radius to compute a coverage.
    // Then, this coverage is mixed with the coverage from the previous stage and passed to the
    // next stage.
    GrGLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier);
    SkString fshaderTxt(version);
    GrGLAppendGLSLDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, gl->fStandard,
                                                   &fshaderTxt);
    oPosition.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
    oPosition.appendDecl(*ctx, &fshaderTxt);
    fshaderTxt.append(";\n");
    oColor.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
    oColor.appendDecl(*ctx, &fshaderTxt);
    fshaderTxt.append(";\n");

    const char* fsOutName;
    if (ctx->caps()->glslCaps()->mustDeclareFragmentShaderOutput()) {
        oFragColor.appendDecl(*ctx, &fshaderTxt);
        fshaderTxt.append(";\n");
        fsOutName = oFragColor.c_str();
    } else {
        fsOutName = "gl_FragColor";
    }


    fshaderTxt.appendf(
            "void main()\n"
            "{\n"
            "    vec4 outputColor;\n"
            "    %s outputCoverage;\n"
            "    outputColor = vec4(%s, 1.0);\n"
            "    outputCoverage = %s;\n",
            fCoverageSetup == kUseVec4_CoverageSetup ? "vec4" : "float",
            oColor.getName().c_str(),
            fCoverageSetup == kUseVec4_CoverageSetup ? "vec4(1.0)" : "1.0"
            );

    float radius = 1.0f;
    for (uint32_t i = 0; i < fNumStages; i++) {
        float centerX = 1.0f - radius;
        float centerY = 1.0f - radius;
        fshaderTxt.appendf(
            "    {\n"
            "        float d = length(%s - vec2(%f, %f));\n"
            "        float edgeAlpha = clamp(100.0 * (%f - d), 0.0, 1.0);\n"
            "        outputCoverage = 0.5 * outputCoverage + 0.5 * %s;\n"
            "    }\n",
            oPosition.getName().c_str(), centerX, centerY,
            radius,
            fCoverageSetup == kUseVec4_CoverageSetup ? "vec4(edgeAlpha)" : "edgeAlpha"
            );
        radius *= 0.8f;
    }
    fshaderTxt.appendf(
            "    {\n"
            "        %s = outputColor * outputCoverage;\n"
            "    }\n"
            "}\n",
            fsOutName);

    return CreateProgram(gl, vshaderTxt.c_str(), fshaderTxt.c_str());
}

template<typename Func>
static void setup_matrices(int numQuads, Func f) {
    // We draw a really small triangle so we are not fill rate limited
    for (int i = 0 ; i < numQuads; i++) {
        SkMatrix m = SkMatrix::I();
        m.setScale(0.01f, 0.01f);
        f(m);
    }
}

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

struct Vertex {
    SkPoint fPositions;
    GrGLfloat fColors[3];
};

void GLVec4ScalarBench::setupSingleVbo(const GrGLInterface* gl, const SkMatrix* viewMatrices) {
    // triangles drawn will alternate between the top-right half of the screen and the bottom-left
    // half of the screen
    Vertex vertices[kVerticesPerTri * kNumTriPerDraw];
    for (uint32_t i = 0; i < kNumTriPerDraw; i++) {
        Vertex* v = &vertices[i * kVerticesPerTri];
        if (i % 2 == 0) {
            v[0].fPositions.set(-1.0f, -1.0f);
            v[1].fPositions.set( 1.0f, -1.0f);
            v[2].fPositions.set( 1.0f,  1.0f);
        } else {
            v[0].fPositions.set(-1.0f, -1.0f);
            v[1].fPositions.set( 1.0f, 1.0f);
            v[2].fPositions.set( -1.0f, 1.0f);
        }
        SkPoint* position = reinterpret_cast<SkPoint*>(v);
        viewMatrices[i].mapPointsWithStride(position, sizeof(Vertex), kVerticesPerTri);

        GrGLfloat color[3] = {1.0f, 0.0f, 1.0f};
        for (uint32_t j = 0; j < kVerticesPerTri; j++) {
            v->fColors[0] = color[0];
            v->fColors[1] = color[1];
            v->fColors[2] = color[2];
            v++;
        }
    }

    GR_GL_CALL(gl, GenBuffers(1, &fVboId));
    GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, fVboId));
    GR_GL_CALL(gl, EnableVertexAttribArray(0));
    GR_GL_CALL(gl, EnableVertexAttribArray(1));
    GR_GL_CALL(gl, VertexAttribPointer(0, 2, GR_GL_FLOAT, GR_GL_FALSE, sizeof(Vertex),
                                       (GrGLvoid*)0));
    GR_GL_CALL(gl, VertexAttribPointer(1, 3, GR_GL_FLOAT, GR_GL_FALSE, sizeof(Vertex),
                                       (GrGLvoid*)(sizeof(SkPoint))));
    GR_GL_CALL(gl, BufferData(GR_GL_ARRAY_BUFFER, sizeof(vertices), vertices, GR_GL_STATIC_DRAW));
}

void GLVec4ScalarBench::setup(const GrGLContext* ctx) {
    const GrGLInterface* gl = ctx->interface();
    if (!gl) {
        SkFAIL("GL interface is nullptr in setup()!\n");
    }
    fFboTextureId = SetupFramebuffer(gl, kScreenWidth, kScreenHeight);

    fProgram = this->setupShader(ctx);

    int index = 0;
    SkMatrix viewMatrices[kNumTriPerDraw];
    setup_matrices(kNumTriPerDraw, [&index, &viewMatrices](const SkMatrix& m) {
        viewMatrices[index++] = m;
    });
    this->setupSingleVbo(gl, viewMatrices);

    GR_GL_CALL(gl, UseProgram(fProgram));
}

void GLVec4ScalarBench::glDraw(const int loops, const GrGLContext* ctx) {
    const GrGLInterface* gl = ctx->interface();

    for (int i = 0; i < loops; i++) {
        GR_GL_CALL(gl, DrawArrays(GR_GL_TRIANGLES, 0, kVerticesPerTri * kNumTriPerDraw));
    }

// using -w when running nanobench will not produce correct images;
// changing this to #if 1 will write the correct images to the Skia folder.
#if 0
    SkString filename("out");
    filename.appendf("_%s.png", this->getName());
    DumpImage(gl, kScreenWidth, kScreenHeight, filename.c_str());
#endif
}

void GLVec4ScalarBench::teardown(const GrGLInterface* gl) {
    GR_GL_CALL(gl, BindBuffer(GR_GL_ARRAY_BUFFER, 0));
    GR_GL_CALL(gl, BindTexture(GR_GL_TEXTURE_2D, 0));
    GR_GL_CALL(gl, BindFramebuffer(GR_GL_FRAMEBUFFER, 0));
    GR_GL_CALL(gl, DeleteTextures(1, &fFboTextureId));
    GR_GL_CALL(gl, DeleteProgram(fProgram));
    GR_GL_CALL(gl, DeleteBuffers(1, &fVboId));
}

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

DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseScalar_CoverageSetup, 1) )
DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseVec4_CoverageSetup, 1) )
DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseScalar_CoverageSetup, 2) )
DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseVec4_CoverageSetup, 2) )
DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseScalar_CoverageSetup, 4) )
DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseVec4_CoverageSetup, 4) )
DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseScalar_CoverageSetup, 6) )
DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseVec4_CoverageSetup, 6) )
DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseScalar_CoverageSetup, 8) )
DEF_BENCH( return new GLVec4ScalarBench(GLVec4ScalarBench::kUseVec4_CoverageSetup, 8) )

#endif
