//
// 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,
    Uniform,
    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;
        case StateChange::Uniform:
            strstr << "_uniform";
            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 if (params.stateChange == StateChange::Uniform)
    {
        constexpr char kVS[] = R"(attribute vec2 vPosition;
void main()
{
    gl_Position = vec4(vPosition, 0, 1);
})";

        constexpr char kFS[] = R"(precision mediump float;
uniform vec4 uni;
void main()
{
    gl_FragColor = uni;
})";

        mProgram1 = CompileProgram(kVS, kFS);
        ASSERT_NE(0u, mProgram1);
    }
    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 UpdateUniformThenDraw(unsigned int iterations, GLsizei numElements)
{
    for (unsigned int it = 0; it < iterations; it++)
    {
        float f = static_cast<float>(it) / static_cast<float>(iterations);
        glUniform4f(0, f, f + 0.1f, f + 0.2f, f + 0.3f);
        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::Uniform:
            UpdateUniformThenDraw(params.iterationsPerStep, numElements);
            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>, Metal<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
