/*
 * 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)
        , fVaoId(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 fVaoId;
    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();
    fFboTextureId = SetupFramebuffer(gl, kScreenWidth, kScreenHeight);

    fProgram = this->setupShader(ctx);

    GR_GL_CALL(gl, GenVertexArrays(1, &fVaoId));
    GR_GL_CALL(gl, BindVertexArray(fVaoId));

    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));
    GR_GL_CALL(gl, BindVertexArray(fVaoId));
}

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, BindVertexArray(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));
    GR_GL_CALL(gl, DeleteVertexArrays(1, &fVaoId));
}

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

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
