//
// Copyright 2025 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.
//
// FormatUploadDrawPerfBenchmark:
//   Performance of texture upload and draw using various formats.
//

#include "ANGLEPerfTest.h"
#include "common/unsafe_buffers.h"

#include <array>
#include <iostream>
#include <random>
#include <sstream>

#include "test_utils/gl_raii.h"
#include "util/shader_utils.h"

using namespace angle;

enum class TestedFormat
{
    RGBA8,
    RGB8,
    RGB565,
};

static constexpr std::array<const char *, 3> kTestedFormatString = {
    "rgba8",
    "rgb8",
    "rgb565",
};

template <typename E>
constexpr auto ToUnderlying(E e) noexcept
{
    return static_cast<std::underlying_type_t<E>>(e);
}

namespace
{
struct FormatUploadDrawPerfParams final : public RenderTestParams
{
    FormatUploadDrawPerfParams() { iterationsPerStep = 1; }

    std::string story() const override;

    TestedFormat testedFormat;
};

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

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

    strstr << RenderTestParams::story() << "_" << kTestedFormatString[ToUnderlying(testedFormat)];

    return strstr.str();
}

class FormatUploadDrawPerfBenchmark
    : public ANGLERenderTest,
      public ::testing::WithParamInterface<FormatUploadDrawPerfParams>
{
  public:
    FormatUploadDrawPerfBenchmark();

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

  protected:
    std::vector<uint8_t> mColors;
    GLuint mTexture;
    TestedFormat mTestedFormat;
    uint32_t mTextureSize;
    uint32_t mPixelSize;
    GLuint mFormat;
    GLuint mType;
    GLuint mProgram;
};

FormatUploadDrawPerfBenchmark::FormatUploadDrawPerfBenchmark()
    : ANGLERenderTest("FormatUploadDrawPerf", GetParam())
{
    mTestedFormat = GetParam().testedFormat;
    mTextureSize  = 256;
    switch (mTestedFormat)
    {
        case TestedFormat::RGBA8:
            mFormat    = GL_RGBA;
            mType      = GL_UNSIGNED_BYTE;
            mPixelSize = 4;
            break;
        case TestedFormat::RGB8:
            mFormat    = GL_RGB;
            mType      = GL_UNSIGNED_BYTE;
            mPixelSize = 3;
            break;
        case TestedFormat::RGB565:
            mFormat    = GL_RGB;
            mType      = GL_UNSIGNED_SHORT_5_6_5;
            mPixelSize = 2;
            break;
        default:
            UNREACHABLE();
            break;
    }
}

void FormatUploadDrawPerfBenchmark::initializeBenchmark()
{
    // Initialize texture.
    ASSERT(gl::isPow2(mTextureSize));
    glGenTextures(1, &mTexture);
    glBindTexture(GL_TEXTURE_2D, mTexture);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexImage2D(GL_TEXTURE_2D, 0, mFormat, mTextureSize, mTextureSize, 0, mFormat, mType, nullptr);

    // Initialize color data.
    mColors.resize(mTextureSize * mTextureSize * mPixelSize);
    ANGLE_UNSAFE_TODO(memset(mColors.data(), 0, mTextureSize * mTextureSize * mPixelSize));

    // Set up program.
    std::string vs = R"(#version 300 es
out highp vec2 texcoord;
void main()
{
    gl_Position = vec4(0, 0, 0, 0);
    texcoord = vec2(0, 0);
}
)";
    std::string fs = R"(#version 300 es
uniform highp sampler2D tex;
out highp vec4 color;
in highp vec2 texcoord;
void main()
{
    color = texture(tex, texcoord);
})";

    mProgram = CompileProgram(vs.c_str(), fs.c_str());
    ASSERT_NE(0u, mProgram);
    glUseProgram(mProgram);
}

void FormatUploadDrawPerfBenchmark::destroyBenchmark()
{
    glDeleteTextures(1, &mTexture);
    glDeleteProgram(mProgram);
}

void FormatUploadDrawPerfBenchmark::drawBenchmark()
{
    // Upload and draw many times.
    for (uint32_t i = 0; i < 100; i++)
    {
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mTextureSize, mTextureSize, mFormat, mType,
                        mColors.data());
        glDrawArrays(GL_TRIANGLES, 0, 6);
    }
    ASSERT_GL_NO_ERROR();
}

FormatUploadDrawPerfParams VulkanParams(TestedFormat testedFormat)
{
    FormatUploadDrawPerfParams params;
    params.eglParameters = egl_platform::VULKAN();
    params.majorVersion  = 3;
    params.minorVersion  = 0;
    params.testedFormat  = testedFormat;
    return params;
}

FormatUploadDrawPerfParams OpenGLOrGLESParams(TestedFormat testedFormat)
{
    FormatUploadDrawPerfParams params;
    params.eglParameters = egl_platform::OPENGL_OR_GLES();
    params.majorVersion  = 3;
    params.minorVersion  = 0;
    params.testedFormat  = testedFormat;
    return params;
}

FormatUploadDrawPerfParams MetalParams(TestedFormat testedFormat)
{
    FormatUploadDrawPerfParams params;
    params.eglParameters = egl_platform::METAL();
    params.majorVersion  = 3;
    params.minorVersion  = 0;
    params.testedFormat  = testedFormat;
    return params;
}

FormatUploadDrawPerfParams D3D11Params(TestedFormat testedFormat)
{
    FormatUploadDrawPerfParams params;
    params.eglParameters = egl_platform::D3D11();
    params.majorVersion  = 3;
    params.minorVersion  = 0;
    params.testedFormat  = testedFormat;
    return params;
}
}  // anonymous namespace

// Runs the test to measure the performance of various formats.
TEST_P(FormatUploadDrawPerfBenchmark, Run)
{
    run();
}

using namespace params;

ANGLE_INSTANTIATE_TEST(FormatUploadDrawPerfBenchmark,
                       VulkanParams(TestedFormat::RGBA8),
                       VulkanParams(TestedFormat::RGB8),
                       VulkanParams(TestedFormat::RGB565),
                       OpenGLOrGLESParams(TestedFormat::RGBA8),
                       OpenGLOrGLESParams(TestedFormat::RGB8),
                       OpenGLOrGLESParams(TestedFormat::RGB565),
                       MetalParams(TestedFormat::RGBA8),
                       MetalParams(TestedFormat::RGB8),
                       MetalParams(TestedFormat::RGB565),
                       D3D11Params(TestedFormat::RGBA8),
                       D3D11Params(TestedFormat::RGB8),
                       D3D11Params(TestedFormat::RGB565));
