//
// Copyright 2021 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.
//
// VertexArrayPerfTest:
//   Performance test for glBindVertexArray.
//

#include <array>

#include "ANGLEPerfTest.h"
#include "DrawCallPerfParams.h"
#include "common/unsafe_buffers.h"
#include "test_utils/gl_raii.h"

using namespace angle;

namespace
{
enum class TestMode
{
    BufferData,
    BindBuffer,
    UpdateBufferData,
};

struct VertexArrayParams final : public RenderTestParams
{
    VertexArrayParams()
    {
        iterationsPerStep = 1;

        // Common default params
        majorVersion = 3;
        minorVersion = 0;
        windowWidth  = 720;
        windowHeight = 720;
    }

    std::string story() const override;

    int numVertexArrays  = 2000;
    int numBuffers       = 5;
    std::array<GLuint, 5> bufferSize = {384, 1028, 192, 384, 192};
    TestMode testMode    = TestMode::BufferData;
};

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

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

    strstr << RenderTestParams::story();

    if (testMode == TestMode::BindBuffer)
    {
        strstr << "_bindbuffer";
    }
    else if (testMode == TestMode::UpdateBufferData)
    {
        strstr << "_updatebufferdata";
    }

    return strstr.str();
}

class VertexArrayBenchmark : public ANGLERenderTest,
                             public ::testing::WithParamInterface<VertexArrayParams>
{
  public:
    VertexArrayBenchmark();

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

    void rebindVertexArray(GLuint vertexArrayID, GLuint bufferID);
    void updateBufferData(GLuint vertexArrayID, GLuint bufferID, GLuint bufferSize);

  private:
    std::vector<GLuint> mBuffers;
    GLuint mProgram       = 0;
    GLint mAttribLocation = 0;
    std::vector<GLuint> mVertexArrays;
};

VertexArrayBenchmark::VertexArrayBenchmark() : ANGLERenderTest("VertexArrayPerf", GetParam())
{
    const auto &params = GetParam();
    if (IsWindows() && IsQualcomm() && params.driver == GLESDriverType::SystemWGL)
    {
        skipTest("anglebug.com/546189136 Fails on Windows ARM64 Qualcomm");
    }
}

void VertexArrayBenchmark::initializeBenchmark()
{
    constexpr char kVS[] = R"(attribute vec4 position;
attribute float in_attrib;
varying float v_attrib;
void main()
{
    v_attrib = in_attrib;
    gl_Position = position;
})";

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

    mProgram = CompileProgram(kVS, kFS);
    ASSERT_NE(0u, mProgram);

    mAttribLocation = glGetAttribLocation(mProgram, "in_attrib");
    ASSERT_NE(mAttribLocation, -1);

    // Generate 5 buffers.
    int numBuffers = GetParam().numBuffers;
    mBuffers.resize(numBuffers, 0);
    glGenBuffers(numBuffers, mBuffers.data());

    int numVertexArrays = GetParam().numVertexArrays;
    mVertexArrays.resize(numVertexArrays, 0);
    glGenVertexArrays(numVertexArrays, mVertexArrays.data());

    // Bind one VBO to all VAOs.
    for (GLuint vertexArray : mVertexArrays)
    {
        rebindVertexArray(vertexArray, mBuffers[0]);
    }

    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, mBuffers[0]);
}

void VertexArrayBenchmark::rebindVertexArray(GLuint vertexArrayID, GLuint bufferID)
{
    // Rebind a vertex array object and a generic vertex attribute inside of it.
    glBindVertexArray(vertexArrayID);
    glBindBuffer(GL_ARRAY_BUFFER, bufferID);
    glEnableVertexAttribArray(mAttribLocation);
    glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
    glVertexAttribDivisor(mAttribLocation, 1);
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void VertexArrayBenchmark::updateBufferData(GLuint vertexArrayID,
                                            GLuint bufferID,
                                            GLuint bufferSize)
{
    glBindVertexArray(vertexArrayID);
    glBindBuffer(GL_ARRAY_BUFFER, bufferID);
    glEnableVertexAttribArray(mAttribLocation);
    glVertexAttribPointer(mAttribLocation, 1, GL_FLOAT, GL_FALSE, 4, nullptr);
    glBufferData(GL_ARRAY_BUFFER, bufferSize, nullptr, GL_STATIC_DRAW);
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}

void VertexArrayBenchmark::destroyBenchmark()
{
    glDeleteProgram(mProgram);
    glDeleteVertexArrays(static_cast<GLsizei>(mVertexArrays.size()), mVertexArrays.data());
    mVertexArrays.clear();
    glDeleteBuffers(static_cast<GLsizei>(mBuffers.size()), mBuffers.data());
    mBuffers.clear();
}

void VertexArrayBenchmark::drawBenchmark()
{
    const VertexArrayParams &params = GetParam();
    if (params.testMode == TestMode::BufferData)
    {
        glBufferData(GL_ARRAY_BUFFER, 128, nullptr, GL_STATIC_DRAW);
    }
    else if (params.testMode == TestMode::UpdateBufferData)
    {
        int bufferSizeIndex = 0;
        for (GLuint vertexArray : mVertexArrays)
        {
            bufferSizeIndex = ((bufferSizeIndex + 1) == 5) ? 0 : (bufferSizeIndex + 1);
            updateBufferData(vertexArray, mBuffers[0], params.bufferSize[bufferSizeIndex]);
        }
    }
    else
    {
        int bufferIndex = 0;
        for (GLuint vertexArray : mVertexArrays)
        {
            bufferIndex = ((bufferIndex + 1) == params.numBuffers) ? 0 : (bufferIndex + 1);
            rebindVertexArray(vertexArray, mBuffers[bufferIndex]);
        }
    }
}

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

VertexArrayParams MetalParams()
{
    VertexArrayParams params;
    params.eglParameters = egl_platform::METAL();
    return params;
}

VertexArrayParams VulkanParams()
{
    VertexArrayParams params;
    params.eglParameters = egl_platform::VULKAN();
    return params;
}

VertexArrayParams VulkanNullParams(TestMode testMode)
{
    VertexArrayParams params;
    params.eglParameters = egl_platform::VULKAN_NULL();
    params.testMode      = testMode;
    return params;
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(VertexArrayBenchmark);
ANGLE_INSTANTIATE_TEST(VertexArrayBenchmark,
                       MetalParams(),
                       VulkanParams(),
                       VulkanNullParams(TestMode::BindBuffer),
                       VulkanNullParams(TestMode::BufferData),
                       VulkanNullParams(TestMode::UpdateBufferData),
                       params::Native(VertexArrayParams()));
}  // namespace
