//
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// DrawCallPerf:
//   Performance tests for ANGLE draw call overhead.
//

#include "ANGLEPerfTest.h"
#include "DrawCallPerfParams.h"
#include "common/PackedEnums.h"
#include "test_utils/draw_call_perf_utils.h"
#include "util/shader_utils.h"

namespace
{
enum class StateChange
{
    NoChange,
    VertexAttrib,
    VertexBuffer,
    ManyVertexBuffers,
    Texture,
    Program,
    VertexBufferCycle,
    Scissor,
    ManyTextureDraw,
    InvalidEnum,
    EnumCount = InvalidEnum,
};

constexpr size_t kCycleVBOPoolSize  = 200;
constexpr size_t kManyTexturesCount = 8;

struct DrawArraysPerfParams : public DrawCallPerfParams
{
    DrawArraysPerfParams() = default;
    DrawArraysPerfParams(const DrawCallPerfParams &base) : DrawCallPerfParams(base) {}

    std::string story() const override;

    StateChange stateChange = StateChange::NoChange;
};

std::string DrawArraysPerfParams::story() const
{
    std::stringstream strstr;

    strstr << DrawCallPerfParams::story();

    switch (stateChange)
    {
        case StateChange::VertexAttrib:
            strstr << "_attrib_change";
            break;
        case StateChange::VertexBuffer:
            strstr << "_vbo_change";
            break;
        case StateChange::ManyVertexBuffers:
            strstr << "_manyvbos_change";
            break;
        case StateChange::Texture:
            strstr << "_tex_change";
            break;
        case StateChange::Program:
            strstr << "_prog_change";
            break;
        case StateChange::VertexBufferCycle:
            strstr << "_vbo_cycle";
            break;
        case StateChange::Scissor:
            strstr << "_scissor_change";
            break;
        case StateChange::ManyTextureDraw:
            strstr << "_many_tex_draw";
            break;
        default:
            break;
    }

    return strstr.str();
}

std::ostream &operator<<(std::ostream &os, const DrawArraysPerfParams &params)
{
    os << params.backendAndStory().substr(1);
    return os;
}

GLuint CreateSimpleTexture2D()
{
    // Use tightly packed data
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    // Generate a texture object
    GLuint texture;
    glGenTextures(1, &texture);

    // Bind the texture object
    glBindTexture(GL_TEXTURE_2D, texture);

    // Load the texture: 2x2 Image, 3 bytes per pixel (R, G, B)
    constexpr size_t width             = 2;
    constexpr size_t height            = 2;
    GLubyte pixels[width * height * 4] = {
        255, 0,   0,   0,  // Red
        0,   255, 0,   0,  // Green
        0,   0,   255, 0,  // Blue
        255, 255, 0,   0   // Yellow
    };
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);

    // Set the filtering mode
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    return texture;
}

class DrawCallPerfBenchmark : public ANGLERenderTest,
                              public ::testing::WithParamInterface<DrawArraysPerfParams>
{
  public:
    DrawCallPerfBenchmark();

    void initializeBenchmark() override;
    void destroyBenchmark() override;
    void drawBenchmark() override;

  private:
    GLuint mProgram1   = 0;
    GLuint mProgram2   = 0;
    GLuint mProgram3   = 0;
    GLuint mBuffer1    = 0;
    GLuint mBuffer2    = 0;
    GLuint mFBO        = 0;
    GLuint mFBOTexture = 0;
    std::vector<GLuint> mTextures;
    int mNumTris = GetParam().numTris;
    std::vector<GLuint> mVBOPool;
    size_t mCurrentVBO = 0;
};

DrawCallPerfBenchmark::DrawCallPerfBenchmark() : ANGLERenderTest("DrawCallPerf", GetParam()) {}

void DrawCallPerfBenchmark::initializeBenchmark()
{
    const auto &params = GetParam();

    if (params.stateChange == StateChange::Texture)
    {
        mProgram1 = SetupSimpleTextureProgram();
        ASSERT_NE(0u, mProgram1);
    }
    else if (params.stateChange == StateChange::ManyTextureDraw)
    {
        mProgram3 = SetupEightTextureProgram();
        ASSERT_NE(0u, mProgram3);
    }
    else if (params.stateChange == StateChange::Program)
    {
        mProgram1 = SetupSimpleTextureProgram();
        mProgram2 = SetupDoubleTextureProgram();
        ASSERT_NE(0u, mProgram1);
        ASSERT_NE(0u, mProgram2);
    }
    else if (params.stateChange == StateChange::ManyVertexBuffers)
    {
        constexpr char kVS[] = R"(attribute vec2 vPosition;
attribute vec2 v0;
attribute vec2 v1;
attribute vec2 v2;
attribute vec2 v3;
const float scale = 0.5;
const float offset = -0.5;

varying vec2 v;

void main()
{
    gl_Position = vec4(vPosition * vec2(scale) + vec2(offset), 0, 1);
    v = (v0 + v1 + v2 + v3) * 0.25;
})";

        constexpr char kFS[] = R"(precision mediump float;
varying vec2 v;
void main()
{
    gl_FragColor = vec4(v, 0, 1);
})";

        mProgram1 = CompileProgram(kVS, kFS);
        ASSERT_NE(0u, mProgram1);
        glBindAttribLocation(mProgram1, 1, "v0");
        glBindAttribLocation(mProgram1, 2, "v1");
        glBindAttribLocation(mProgram1, 3, "v2");
        glBindAttribLocation(mProgram1, 4, "v3");
        glEnableVertexAttribArray(1);
        glEnableVertexAttribArray(2);
        glEnableVertexAttribArray(3);
        glEnableVertexAttribArray(4);
    }
    else if (params.stateChange == StateChange::VertexBufferCycle)
    {
        mProgram1 = SetupSimpleDrawProgram();
        ASSERT_NE(0u, mProgram1);

        for (size_t bufferIndex = 0; bufferIndex < kCycleVBOPoolSize; ++bufferIndex)
        {
            GLuint buffer = Create2DTriangleBuffer(mNumTris, GL_STATIC_DRAW);
            mVBOPool.push_back(buffer);
        }
    }
    else
    {
        mProgram1 = SetupSimpleDrawProgram();
        ASSERT_NE(0u, mProgram1);
    }

    // Re-link program to ensure the attrib bindings are used.
    if (mProgram1)
    {
        glBindAttribLocation(mProgram1, 0, "vPosition");
        glLinkProgram(mProgram1);
        glUseProgram(mProgram1);
    }

    if (mProgram2)
    {
        glBindAttribLocation(mProgram2, 0, "vPosition");
        glLinkProgram(mProgram2);
    }

    if (mProgram3)
    {
        glBindAttribLocation(mProgram3, 0, "vPosition");
        glLinkProgram(mProgram3);
    }

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    mBuffer1 = Create2DTriangleBuffer(mNumTris, GL_STATIC_DRAW);
    mBuffer2 = Create2DTriangleBuffer(mNumTris, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(0);

    // Set the viewport
    glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());

    if (params.surfaceType == SurfaceType::Offscreen)
    {
        CreateColorFBO(getWindow()->getWidth(), getWindow()->getHeight(), &mFBOTexture, &mFBO);
    }

    for (size_t i = 0; i < kManyTexturesCount; ++i)
    {
        mTextures.emplace_back(CreateSimpleTexture2D());
    }

    if (params.stateChange == StateChange::Program)
    {
        // Bind the textures as appropriate, they are not modified during the test.
        GLint program1Tex1Loc = glGetUniformLocation(mProgram1, "tex");
        GLint program2Tex1Loc = glGetUniformLocation(mProgram2, "tex1");
        GLint program2Tex2Loc = glGetUniformLocation(mProgram2, "tex2");

        glUseProgram(mProgram1);
        glUniform1i(program1Tex1Loc, 0);

        glUseProgram(mProgram2);
        glUniform1i(program2Tex1Loc, 0);
        glUniform1i(program2Tex2Loc, 1);
    }

    if (params.stateChange == StateChange::ManyTextureDraw)
    {
        GLint program3TexLocs[kManyTexturesCount];

        for (size_t i = 0; i < mTextures.size(); ++i)
        {
            char stringBuffer[8];
            snprintf(stringBuffer, sizeof(stringBuffer), "tex%zu", i);
            program3TexLocs[i] = glGetUniformLocation(mProgram3, stringBuffer);
        }

        glUseProgram(mProgram3);
        for (size_t i = 0; i < mTextures.size(); ++i)
        {
            glUniform1i(program3TexLocs[i], i);
        }

        for (size_t i = 0; i < mTextures.size(); ++i)
        {
            glActiveTexture(GL_TEXTURE0 + i);
            glBindTexture(GL_TEXTURE_2D, mTextures[i]);
        }
    }

    ASSERT_GL_NO_ERROR();
}

void DrawCallPerfBenchmark::destroyBenchmark()
{
    glDeleteProgram(mProgram1);
    glDeleteProgram(mProgram2);
    glDeleteProgram(mProgram3);
    glDeleteBuffers(1, &mBuffer1);
    glDeleteBuffers(1, &mBuffer2);
    glDeleteTextures(1, &mFBOTexture);
    glDeleteTextures(mTextures.size(), mTextures.data());
    glDeleteFramebuffers(1, &mFBO);

    if (!mVBOPool.empty())
    {
        glDeleteBuffers(mVBOPool.size(), mVBOPool.data());
    }
}

void ClearThenDraw(unsigned int iterations, GLsizei numElements)
{
    glClear(GL_COLOR_BUFFER_BIT);

    for (unsigned int it = 0; it < iterations; it++)
    {
        glDrawArrays(GL_TRIANGLES, 0, numElements);
    }
}

void JustDraw(unsigned int iterations, GLsizei numElements)
{
    for (unsigned int it = 0; it < iterations; it++)
    {
        glDrawArrays(GL_TRIANGLES, 0, numElements);
    }
}

template <int kArrayBufferCount>
void ChangeVertexAttribThenDraw(unsigned int iterations, GLsizei numElements, GLuint buffer)
{
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    for (unsigned int it = 0; it < iterations; it++)
    {
        for (int arrayIndex = 0; arrayIndex < kArrayBufferCount; ++arrayIndex)
        {
            glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, 0);
        }
        glDrawArrays(GL_TRIANGLES, 0, numElements);

        for (int arrayIndex = 0; arrayIndex < kArrayBufferCount; ++arrayIndex)
        {
            glVertexAttribPointer(arrayIndex, 4, GL_UNSIGNED_BYTE, GL_TRUE, 0, 0);
        }
        glDrawArrays(GL_TRIANGLES, 0, numElements);
    }
}
template <int kArrayBufferCount>
void ChangeArrayBuffersThenDraw(unsigned int iterations,
                                GLsizei numElements,
                                GLuint buffer1,
                                GLuint buffer2)
{
    for (unsigned int it = 0; it < iterations; it++)
    {
        glBindBuffer(GL_ARRAY_BUFFER, buffer1);
        for (int arrayIndex = 0; arrayIndex < kArrayBufferCount; ++arrayIndex)
        {
            glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, 0);
        }
        glDrawArrays(GL_TRIANGLES, 0, numElements);

        glBindBuffer(GL_ARRAY_BUFFER, buffer2);
        for (int arrayIndex = 0; arrayIndex < kArrayBufferCount; ++arrayIndex)
        {
            glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, 0);
        }
        glDrawArrays(GL_TRIANGLES, 0, numElements);
    }
}

void ChangeTextureThenDraw(unsigned int iterations,
                           GLsizei numElements,
                           GLuint texture1,
                           GLuint texture2)
{
    for (unsigned int it = 0; it < iterations; it++)
    {
        glBindTexture(GL_TEXTURE_2D, texture1);
        glDrawArrays(GL_TRIANGLES, 0, numElements);

        glBindTexture(GL_TEXTURE_2D, texture2);
        glDrawArrays(GL_TRIANGLES, 0, numElements);
    }
}

void ChangeProgramThenDraw(unsigned int iterations,
                           GLsizei numElements,
                           GLuint program1,
                           GLuint program2)
{
    for (unsigned int it = 0; it < iterations; it++)
    {
        glUseProgram(program1);
        glDrawArrays(GL_TRIANGLES, 0, numElements);

        glUseProgram(program2);
        glDrawArrays(GL_TRIANGLES, 0, numElements);
    }
}

void CycleVertexBufferThenDraw(unsigned int iterations,
                               GLsizei numElements,
                               const std::vector<GLuint> &vbos,
                               size_t *currentVBO)
{
    for (unsigned int it = 0; it < iterations; it++)
    {
        GLuint vbo = vbos[*currentVBO];
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);
        glDrawArrays(GL_TRIANGLES, 0, numElements);
        *currentVBO = (*currentVBO + 1) % vbos.size();
    }
}

void ChangeScissorThenDraw(unsigned int iterations,
                           GLsizei numElements,
                           unsigned int windowWidth,
                           unsigned int windowHeight)
{
    // Change scissor as such:
    //
    // - Start with a narrow vertical bar:
    //
    //           Scissor
    //              |
    //              V
    //       +-----+-+-----+
    //       |     | |     | <-- Window
    //       |     | |     |
    //       |     | |     |
    //       |     | |     |
    //       |     | |     |
    //       |     | |     |
    //       +-----+-+-----+
    //
    // - Gradually reduce height and increase width, to end up with a narrow horizontal bar:
    //
    //       +-------------+
    //       |             |
    //       |             |
    //       +-------------+ <-- Scissor
    //       +-------------+
    //       |             |
    //       |             |
    //       +-------------+
    //
    // - If more iterations left, restart, but shift the initial bar left to cover more area:
    //
    //       +---+-+-------+          +-------------+
    //       |   | |       |          |             |
    //       |   | |       |          +-------------+
    //       |   | |       |   --->   |             |
    //       |   | |       |          |             |
    //       |   | |       |          +-------------+
    //       |   | |       |          |             |
    //       +---+-+-------+          +-------------+
    //
    //       +-+-+---------+          +-------------+
    //       | | |         |          +-------------+
    //       | | |         |          |             |
    //       | | |         |   --->   |             |
    //       | | |         |          |             |
    //       | | |         |          |             |
    //       | | |         |          +-------------+
    //       +-+-+---------+          +-------------+

    glEnable(GL_SCISSOR_TEST);

    constexpr unsigned int kScissorStep  = 2;
    unsigned int scissorX                = windowWidth / 2 - 1;
    unsigned int scissorY                = 0;
    unsigned int scissorWidth            = 2;
    unsigned int scissorHeight           = windowHeight;
    unsigned int scissorPatternIteration = 0;

    for (unsigned int it = 0; it < iterations; it++)
    {
        glScissor(scissorX, scissorY, scissorWidth, scissorHeight);
        glDrawArrays(GL_TRIANGLES, 0, numElements);

        if (scissorX < kScissorStep || scissorHeight < kScissorStep * 2)
        {
            ++scissorPatternIteration;
            scissorX      = windowWidth / 2 - 1 - scissorPatternIteration * 2;
            scissorY      = 0;
            scissorWidth  = 2;
            scissorHeight = windowHeight;
        }
        else
        {
            scissorX -= kScissorStep;
            scissorY += kScissorStep;
            scissorWidth += kScissorStep * 2;
            scissorHeight -= kScissorStep * 2;
        }
    }
}

void DrawWithEightTextures(unsigned int iterations,
                           GLsizei numElements,
                           std::vector<GLuint> textures)
{
    for (unsigned int it = 0; it < iterations; it++)
    {
        for (size_t i = 0; i < textures.size(); ++i)
        {
            glActiveTexture(GL_TEXTURE0 + i);
            size_t index = (it + i) % textures.size();
            glBindTexture(GL_TEXTURE_2D, textures[index]);
        }

        glDrawArrays(GL_TRIANGLES, 0, numElements);
    }
}

void DrawCallPerfBenchmark::drawBenchmark()
{
    // This workaround fixes a huge queue of graphics commands accumulating on the GL
    // back-end. The GL back-end doesn't have a proper NULL device at the moment.
    // TODO(jmadill): Remove this when/if we ever get a proper OpenGL NULL device.
    const auto &eglParams = GetParam().eglParameters;
    const auto &params    = GetParam();
    GLsizei numElements   = static_cast<GLsizei>(3 * mNumTris);

    switch (params.stateChange)
    {
        case StateChange::VertexAttrib:
            ChangeVertexAttribThenDraw<1>(params.iterationsPerStep, numElements, mBuffer1);
            break;
        case StateChange::VertexBuffer:
            ChangeArrayBuffersThenDraw<1>(params.iterationsPerStep, numElements, mBuffer1,
                                          mBuffer2);
            break;
        case StateChange::ManyVertexBuffers:
            ChangeArrayBuffersThenDraw<5>(params.iterationsPerStep, numElements, mBuffer1,
                                          mBuffer2);
            break;
        case StateChange::Texture:
            ChangeTextureThenDraw(params.iterationsPerStep, numElements, mTextures[0],
                                  mTextures[1]);
            break;
        case StateChange::Program:
            ChangeProgramThenDraw(params.iterationsPerStep, numElements, mProgram1, mProgram2);
            break;
        case StateChange::NoChange:
            if (eglParams.deviceType != EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE ||
                (eglParams.renderer != EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE &&
                 eglParams.renderer != EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE))
            {
                ClearThenDraw(params.iterationsPerStep, numElements);
            }
            else
            {
                JustDraw(params.iterationsPerStep, numElements);
            }
            break;
        case StateChange::VertexBufferCycle:
            CycleVertexBufferThenDraw(params.iterationsPerStep, numElements, mVBOPool,
                                      &mCurrentVBO);
            break;
        case StateChange::Scissor:
            ChangeScissorThenDraw(params.iterationsPerStep, numElements, getWindow()->getWidth(),
                                  getWindow()->getHeight());
            break;
        case StateChange::ManyTextureDraw:
            glUseProgram(mProgram3);
            DrawWithEightTextures(params.iterationsPerStep, numElements, mTextures);
            break;
        case StateChange::InvalidEnum:
            ADD_FAILURE() << "Invalid state change.";
            break;
    }

    ASSERT_GL_NO_ERROR();
}

TEST_P(DrawCallPerfBenchmark, Run)
{
    run();
}

using namespace params;

DrawArraysPerfParams CombineStateChange(const DrawArraysPerfParams &in, StateChange stateChange)
{
    DrawArraysPerfParams out = in;
    out.stateChange          = stateChange;

    // Crank up iteration count to ensure we cycle through all VBs before a swap.
    if (stateChange == StateChange::VertexBufferCycle)
    {
        out.iterationsPerStep = kCycleVBOPoolSize * 2;
    }

    return out;
}

using P = DrawArraysPerfParams;

std::vector<P> gTestsWithStateChange =
    CombineWithValues({P()}, angle::AllEnums<StateChange>(), CombineStateChange);
std::vector<P> gTestsWithRenderer =
    CombineWithFuncs(gTestsWithStateChange, {D3D11<P>, GL<P>, Vulkan<P>, WGL<P>});
std::vector<P> gTestsWithDevice =
    CombineWithFuncs(gTestsWithRenderer, {Passthrough<P>, Offscreen<P>, NullDevice<P>});

ANGLE_INSTANTIATE_TEST_ARRAY(DrawCallPerfBenchmark, gTestsWithDevice);

}  // anonymous namespace
