//
// Copyright (c) 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.
//
// TexSubImageBenchmark:
//   Performace test for ANGLE texture updates.
//

#include <sstream>

#include "ANGLEPerfTest.h"
#include "shader_utils.h"

using namespace angle;

namespace
{

struct TexSubImageParams final : public RenderTestParams
{
    TexSubImageParams()
    {
        // Common default parameters
        majorVersion = 2;
        minorVersion = 0;
        windowWidth  = 512;
        windowHeight = 512;

        imageWidth     = 1024;
        imageHeight    = 1024;
        subImageWidth  = 64;
        subImageHeight = 64;
        iterations     = 9;
    }

    std::string suffix() const override;

    // Static parameters
    int imageWidth;
    int imageHeight;
    int subImageWidth;
    int subImageHeight;
    unsigned int iterations;
};

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

class TexSubImageBenchmark : public ANGLERenderTest,
                             public ::testing::WithParamInterface<TexSubImageParams>
{
  public:
    TexSubImageBenchmark();

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

  private:
    GLuint createTexture();

    // Handle to a program object
    GLuint mProgram;

    // Attribute locations
    GLint mPositionLoc;
    GLint mTexCoordLoc;

    // Sampler location
    GLint mSamplerLoc;

    // Texture handle
    GLuint mTexture;

    // Buffer handle
    GLuint mVertexBuffer;
    GLuint mIndexBuffer;

    GLubyte *mPixels;
};

std::string TexSubImageParams::suffix() const
{
    // TODO(jmadill)
    return RenderTestParams::suffix();
}

TexSubImageBenchmark::TexSubImageBenchmark()
    : ANGLERenderTest("TexSubImage", GetParam()),
      mProgram(0),
      mPositionLoc(-1),
      mTexCoordLoc(-1),
      mSamplerLoc(-1),
      mTexture(0),
      mVertexBuffer(0),
      mIndexBuffer(0),
      mPixels(nullptr)
{
}

GLuint TexSubImageBenchmark::createTexture()
{
    const auto &params = GetParam();

    assert(params.iterations > 0);

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

    glTexStorage2DEXT(GL_TEXTURE_2D, 1, GL_RGBA8, params.imageWidth, params.imageHeight);

    // 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;
}

void TexSubImageBenchmark::initializeBenchmark()
{
    const auto &params = GetParam();

    const std::string vs = SHADER_SOURCE(attribute vec4 a_position; attribute vec2 a_texCoord;
                                         varying vec2 v_texCoord; void main() {
                                             gl_Position = a_position;
                                             v_texCoord  = a_texCoord;
                                         });

    const std::string fs =
        SHADER_SOURCE(precision mediump float; varying vec2 v_texCoord; uniform sampler2D s_texture;
                      void main() { gl_FragColor = texture2D(s_texture, v_texCoord); });

    mProgram = CompileProgram(vs, fs);
    ASSERT_NE(0u, mProgram);

    // Get the attribute locations
    mPositionLoc = glGetAttribLocation(mProgram, "a_position");
    mTexCoordLoc = glGetAttribLocation(mProgram, "a_texCoord");

    // Get the sampler location
    mSamplerLoc = glGetUniformLocation(mProgram, "s_texture");

    // Build the vertex buffer
    GLfloat vertices[] = {
        -0.5f, 0.5f,  0.0f,  // Position 0
        0.0f,  0.0f,         // TexCoord 0
        -0.5f, -0.5f, 0.0f,  // Position 1
        0.0f,  1.0f,         // TexCoord 1
        0.5f,  -0.5f, 0.0f,  // Position 2
        1.0f,  1.0f,         // TexCoord 2
        0.5f,  0.5f,  0.0f,  // Position 3
        1.0f,  0.0f          // TexCoord 3
    };

    glGenBuffers(1, &mVertexBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    GLushort indices[] = {0, 1, 2, 0, 2, 3};
    glGenBuffers(1, &mIndexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    // Load the texture
    mTexture = createTexture();

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    mPixels = new GLubyte[params.subImageWidth * params.subImageHeight * 4];

    // Fill the pixels structure with random data:
    for (int y = 0; y < params.subImageHeight; ++y)
    {
        for (int x = 0; x < params.subImageWidth; ++x)
        {
            int offset          = (x + (y * params.subImageWidth)) * 4;
            mPixels[offset + 0] = rand() % 255;  // Red
            mPixels[offset + 1] = rand() % 255;  // Green
            mPixels[offset + 2] = rand() % 255;  // Blue
            mPixels[offset + 3] = 255;           // Alpha
        }
    }

    ASSERT_GL_NO_ERROR();
}

void TexSubImageBenchmark::destroyBenchmark()
{
    glDeleteProgram(mProgram);
    glDeleteBuffers(1, &mVertexBuffer);
    glDeleteBuffers(1, &mIndexBuffer);
    glDeleteTextures(1, &mTexture);
    delete[] mPixels;
}

void TexSubImageBenchmark::drawBenchmark()
{
    // Set the viewport
    glViewport(0, 0, getWindow()->getWidth(), getWindow()->getHeight());

    // Clear the color buffer
    glClear(GL_COLOR_BUFFER_BIT);

    // Use the program object
    glUseProgram(mProgram);

    // Bind the buffers
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffer);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);

    // Load the vertex position
    glVertexAttribPointer(mPositionLoc, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
    // Load the texture coordinate
    glVertexAttribPointer(mTexCoordLoc, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat),
                          reinterpret_cast<void *>(3 * sizeof(GLfloat)));

    glEnableVertexAttribArray(mPositionLoc);
    glEnableVertexAttribArray(mTexCoordLoc);

    // Bind the texture
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, mTexture);

    // Set the texture sampler to texture unit to 0
    glUniform1i(mSamplerLoc, 0);

    ASSERT_GL_NO_ERROR();

    const auto &params = GetParam();

    for (unsigned int iteration = 0; iteration < params.iterations; ++iteration)
    {
        glTexSubImage2D(GL_TEXTURE_2D, 0, rand() % (params.imageWidth - params.subImageWidth),
                        rand() % (params.imageHeight - params.subImageHeight), params.subImageWidth,
                        params.subImageHeight, GL_RGBA, GL_UNSIGNED_BYTE, mPixels);

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
    }

    ASSERT_GL_NO_ERROR();
}

TexSubImageParams D3D11Params()
{
    TexSubImageParams params;
    params.eglParameters = egl_platform::D3D11();
    return params;
}

TexSubImageParams D3D9Params()
{
    TexSubImageParams params;
    params.eglParameters = egl_platform::D3D9();
    return params;
}

TexSubImageParams OpenGLParams()
{
    TexSubImageParams params;
    params.eglParameters = egl_platform::OPENGL();
    return params;
}

}  // namespace

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

ANGLE_INSTANTIATE_TEST(TexSubImageBenchmark, D3D11Params(), D3D9Params(), OpenGLParams());
