//
// 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 "ANGLEPerfTest.h"
#include "DrawCallPerfParams.h"
#include "test_utils/gl_raii.h"

using namespace angle;

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

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 = 1000;
    int numBuffers      = 5;
    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";
    }

    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);

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

VertexArrayBenchmark::VertexArrayBenchmark() : ANGLERenderTest("VertexArrayPerf", GetParam()) {}

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::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
    {
        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 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,
                       VulkanParams(),
                       VulkanNullParams(TestMode::BindBuffer),
                       VulkanNullParams(TestMode::BufferData),
                       params::Native(VertexArrayParams()));
}  // namespace
