/*
 * 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/GrGLContext.h"
#include "gl/GrGLInterface.h"
#include "gl/GrGLUtil.h"
#include "glsl/GrGLSL.h"
#include "glsl/GrGLSLCaps.h"
#include "glsl/GrGLSLShaderVar.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(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 GrGLSLCaps* glslCaps = ctx->caps()->glslCaps();
    const char* version = glslCaps->versionDeclString();

    // 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
    GrGLSLShaderVar aPosition("a_position", kVec2f_GrSLType, GrShaderVar::kAttribute_TypeModifier);
    GrGLSLShaderVar oPosition("o_position", kVec2f_GrSLType, GrShaderVar::kVaryingOut_TypeModifier);
    GrGLSLShaderVar aColor("a_color", kVec3f_GrSLType, GrShaderVar::kAttribute_TypeModifier);
    GrGLSLShaderVar oColor("o_color", kVec3f_GrSLType, GrShaderVar::kVaryingOut_TypeModifier);

    SkString vshaderTxt(version);
    aPosition.appendDecl(glslCaps, &vshaderTxt);
    vshaderTxt.append(";\n");
    aColor.appendDecl(glslCaps, &vshaderTxt);
    vshaderTxt.append(";\n");
    oPosition.appendDecl(glslCaps, &vshaderTxt);
    vshaderTxt.append(";\n");
    oColor.appendDecl(glslCaps, &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");

    // 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.
    GrGLSLShaderVar oFragColor("o_FragColor", kVec4f_GrSLType, GrShaderVar::kOut_TypeModifier);
    SkString fshaderTxt(version);
    GrGLSLAppendDefaultFloatPrecisionDeclaration(kDefault_GrSLPrecision, *glslCaps, &fshaderTxt);
    oPosition.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
    oPosition.appendDecl(glslCaps, &fshaderTxt);
    fshaderTxt.append(";\n");
    oColor.setTypeModifier(GrShaderVar::kVaryingIn_TypeModifier);
    oColor.appendDecl(glslCaps, &fshaderTxt);
    fshaderTxt.append(";\n");

    const char* fsOutName;
    if (glslCaps->mustDeclareFragmentShaderOutput()) {
        oFragColor.appendDecl(glslCaps, &fshaderTxt);
        fshaderTxt.append(";\n");
        fsOutName = oFragColor.c_str();
    } else {
        fsOutName = "sk_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(ctx, 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(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
