//
// 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 <array>

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

using namespace angle;

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())
{
    const auto &params = GetParam();
    if (IsPixel6() && params.eglParameters.renderer == EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE &&
        params.surfaceType == SurfaceType::Offscreen &&
        (params.stateChange == StateChange::VertexAttrib ||
         params.stateChange == StateChange::Program))
    {
        skipTest("https://issuetracker.google.com/issues/298407224 Fails on Pixel 6 GLES");
    }

    if (IsWindows() && IsQualcomm() && params.driver == GLESDriverType::SystemWGL)
    {
        skipTest("anglebug.com/546189136 Fails on Windows ARM64 Qualcomm");
    }
}

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)
    {
        std::array<GLint, kManyTexturesCount> program3TexLocs;

        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
