//
// Copyright 2015 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.
//
// DrawElementsTest:
//   Tests for indexed draws.
//

#include "common/unsafe_buffers.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"

using namespace angle;

namespace
{

class DrawElementsTest : public ANGLETest<>
{
  protected:
    DrawElementsTest() : mProgram(0u)
    {
        setWindowWidth(64);
        setWindowHeight(64);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    ~DrawElementsTest()
    {
        for (GLuint indexBuffer : mIndexBuffers)
        {
            if (indexBuffer != 0)
            {
                glDeleteBuffers(1, &indexBuffer);
            }
        }

        for (GLuint vertexArray : mVertexArrays)
        {
            if (vertexArray != 0)
            {
                glDeleteVertexArrays(1, &vertexArray);
            }
        }

        for (GLuint vertexBuffer : mVertexBuffers)
        {
            if (vertexBuffer != 0)
            {
                glDeleteBuffers(1, &vertexBuffer);
            }
        }

        if (mProgram != 0u)
        {
            glDeleteProgram(mProgram);
        }
    }

    std::vector<GLuint> mIndexBuffers;
    std::vector<GLuint> mVertexArrays;
    std::vector<GLuint> mVertexBuffers;
    GLuint mProgram;
};

class WebGLDrawElementsTest : public DrawElementsTest
{
  public:
    WebGLDrawElementsTest() { setWebGLCompatibilityEnabled(true); }
};

template <typename T, typename U>
std::vector<T> convertIndexBufferWithRestarts(const std::vector<U> &input)
{
    constexpr U inputRestart  = std::numeric_limits<U>::max();
    constexpr T outputRestart = std::numeric_limits<T>::max();
    std::vector<T> output;
    output.reserve(input.size());
    for (auto byte : input)
    {
        output.push_back(byte == inputRestart ? outputRestart : static_cast<T>(byte));
    }
    return output;
}

enum class PrimitiveRestartMode
{
    Disabled,
    Enabled,
    EnabledSplitContent,
};

enum class IndicesMode
{
    Buffer,
    BufferAndOffset,
    ClientSideArray,
};

enum class RestartOption
{
    None,
    AtBegin,
    AtEnd,
    Degenerate,
};

using DrawElementsVariantsTestParams = std::tuple<angle::PlatformParameters,
                                                  GLenum,                // type
                                                  bool,                  // useFlat
                                                  PrimitiveRestartMode,  // primitiveRestartMode
                                                  bool,                  // drawStrip
                                                  IndicesMode,           // indicesMode
                                                  RestartOption,         // restartOption
                                                  bool>;                 // useProvokingVertexFirst

std::string DrawElementsVariantsTestPrint(
    const ::testing::TestParamInfo<DrawElementsVariantsTestParams> &paramsInfo)
{
    const auto &[platform, type, useFlat, primitiveRestartMode, drawStrip, indicesMode,
                 restartOption, useProvokingVertexFirst] = paramsInfo.param;
    std::ostringstream out;
    out << platform << "__"
        << (type == GL_UNSIGNED_BYTE ? "B" : (type == GL_UNSIGNED_SHORT ? "S" : "I"))
        << (useFlat ? "_Flat" : "");
    switch (primitiveRestartMode)
    {
        case PrimitiveRestartMode::Disabled:
            break;
        case PrimitiveRestartMode::Enabled:
            out << "_Restart";
            break;
        case PrimitiveRestartMode::EnabledSplitContent:
            out << "_Split";
            break;
    }
    out << (drawStrip ? "_Strip" : "_Tris");
    switch (indicesMode)
    {
        case IndicesMode::Buffer:
            break;
        case IndicesMode::BufferAndOffset:
            out << "_Offset";
            break;
        case IndicesMode::ClientSideArray:
            out << "_Client";
            break;
    }
    switch (restartOption)
    {
        case RestartOption::None:
            break;
        case RestartOption::AtBegin:
            out << "_AtBegin";
            break;
        case RestartOption::AtEnd:
            out << "_AtEnd";
            break;
        case RestartOption::Degenerate:
            out << "_Degen";
            break;
    }
    out << (useProvokingVertexFirst ? "_First" : "");
    return out.str();
}

class DrawElementsVariantsTest : public ANGLETest<DrawElementsVariantsTestParams>
{
  protected:
    DrawElementsVariantsTest()
    {
        setWindowWidth(64);
        setWindowHeight(64);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    GLenum type() const { return std::get<1>(GetParam()); }
    bool useFlat() const { return std::get<2>(GetParam()); }
    PrimitiveRestartMode primitiveRestartMode() const { return std::get<3>(GetParam()); }
    bool drawStrip() const { return std::get<4>(GetParam()); }
    IndicesMode indicesMode() const { return std::get<5>(GetParam()); }
    RestartOption restartOption() const { return std::get<6>(GetParam()); }
    bool addRestartAtBegin() const { return restartOption() == RestartOption::AtBegin; }
    bool addRestartAtEnd() const { return restartOption() == RestartOption::AtEnd; }
    bool addRestartDegenerate() const { return restartOption() == RestartOption::Degenerate; }
    bool useProvokingVertexFirst() const { return std::get<7>(GetParam()); }

    bool usePrimitiveRestart() const
    {
        return primitiveRestartMode() != PrimitiveRestartMode::Disabled;
    }
    bool splitContent() const
    {
        return primitiveRestartMode() == PrimitiveRestartMode::EnabledSplitContent;
    }
    bool addOffset() const { return indicesMode() == IndicesMode::BufferAndOffset; }
    bool useClientSideArrays() const { return indicesMode() == IndicesMode::ClientSideArray; }
};

// Test no error is generated when using client-side arrays, indices = nullptr and count = 0
TEST_P(DrawElementsTest, ClientSideNullptrArrayZeroCount)
{
    constexpr char kVS[] =
        "attribute vec3 a_pos;\n"
        "void main()\n"
        "{\n"
        "    gl_Position = vec4(a_pos, 1.0);\n"
        "}\n";

    ANGLE_GL_PROGRAM(program, kVS, essl1_shaders::fs::Blue());

    GLint posLocation = glGetAttribLocation(program, "a_pos");
    ASSERT_NE(-1, posLocation);
    glUseProgram(program);

    const auto &vertices = GetQuadVertices();

    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posLocation);
    ASSERT_GL_NO_ERROR();

    // "If drawElements is called with a count greater than zero, and no WebGLBuffer is bound to the
    // ELEMENT_ARRAY_BUFFER binding point, an INVALID_OPERATION error is generated."
    glDrawElements(GL_TRIANGLES, 1, GL_UNSIGNED_BYTE, nullptr);
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);

    // count == 0 so it's fine to have no element array buffer bound.
    glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_BYTE, nullptr);
    ASSERT_GL_NO_ERROR();
}

// Test uploading part of an index buffer after deleting a vertex array
// previously used for DrawElements.
TEST_P(DrawElementsTest, DeleteVertexArrayAndUploadIndex)
{
    const auto &vertices = GetIndexedQuadVertices();
    const auto &indices  = GetQuadIndices();

    ANGLE_GL_PROGRAM(programDrawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
    glUseProgram(programDrawRed);

    GLint posLocation = glGetAttribLocation(programDrawRed, essl3_shaders::PositionAttrib());
    ASSERT_NE(-1, posLocation);

    GLuint vertexArray;
    glGenVertexArrays(1, &vertexArray);
    glBindVertexArray(vertexArray);

    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posLocation);

    GLBuffer indexBuffer;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), indices.data(),
                 GL_STATIC_DRAW);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);

    glDeleteVertexArrays(1, &vertexArray);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);

    // Could crash here if the observer binding from the vertex array doesn't get
    // removed on vertex array destruction.
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(indices[0]) * 3, indices.data());

    ASSERT_GL_NO_ERROR();
}

// Test VAO switch is handling cached element array buffer properly along with line loop mode
// switch.
TEST_P(DrawElementsTest, LineLoopTriangles)
{
    const auto &vertices                    = GetIndexedQuadVertices();
    constexpr std::array<GLuint, 6> indices = {{0, 1, 2, 0, 2, 3}};

    ANGLE_GL_PROGRAM(programDrawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
    ANGLE_GL_PROGRAM(programDrawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());

    glUseProgram(programDrawRed);
    GLint posLocation = glGetAttribLocation(programDrawRed, essl3_shaders::PositionAttrib());
    ASSERT_NE(-1, posLocation);

    GLVertexArray vertexArray[2];
    GLBuffer vertexBuffer[2];

    glBindVertexArray(vertexArray[0]);

    GLBuffer indexBuffer;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), indices.data(),
                 GL_STATIC_DRAW);

    for (int i = 0; i < 2; i++)
    {
        glBindVertexArray(ANGLE_UNSAFE_TODO(vertexArray[i]));
        glBindBuffer(GL_ARRAY_BUFFER, ANGLE_UNSAFE_TODO(vertexBuffer[i]));
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
                     GL_STATIC_DRAW);
        glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(posLocation);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    }

    // First draw with VAO0 and line loop mode
    glBindVertexArray(vertexArray[0]);
    glDrawArrays(GL_LINE_LOOP, 0, 4);

    // Switch to VAO1 and draw with triangle mode.
    glBindVertexArray(vertexArray[1]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() - 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);

    // Switch back to VAO0 and draw with triangle mode.
    glUseProgram(programDrawBlue);
    glBindVertexArray(vertexArray[0]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, 0, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() - 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::blue);
    ASSERT_GL_NO_ERROR();
}

// Regression test for using two VAOs, one to draw only GL_LINE_LOOPs, and
// another to draw indexed triangles.
TEST_P(DrawElementsTest, LineLoopTriangles2)
{
    const auto &vertices                    = GetIndexedQuadVertices();
    constexpr std::array<GLuint, 6> indices = {{0, 1, 2, 0, 2, 3}};

    ANGLE_GL_PROGRAM(programDrawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());

    glUseProgram(programDrawRed);
    GLint posLocation = glGetAttribLocation(programDrawRed, essl3_shaders::PositionAttrib());
    ASSERT_NE(-1, posLocation);

    GLVertexArray vertexArray[2];
    GLBuffer vertexBuffer[2];

    GLBuffer indexBuffer;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), indices.data(),
                 GL_STATIC_DRAW);

    for (int i = 0; i < 2; i++)
    {
        glBindVertexArray(ANGLE_UNSAFE_TODO(vertexArray[i]));
        glBindBuffer(GL_ARRAY_BUFFER, ANGLE_UNSAFE_TODO(vertexBuffer[i]));
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
                     GL_STATIC_DRAW);
        glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
        glEnableVertexAttribArray(posLocation);
        if (i != 0)
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    }

    // First draw with VAO0 and line loop mode
    glBindVertexArray(vertexArray[0]);
    glDrawArrays(GL_LINE_LOOP, 0, 4);

    // Switch to VAO1 and draw some indexed triangles
    glBindVertexArray(vertexArray[1]);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);

    // Switch back to VAO0 and do another line loop
    glBindVertexArray(vertexArray[0]);

    // Would crash if the index buffer dirty bit got errantly set on VAO0.
    glDrawArrays(GL_LINE_LOOP, 0, 4);

    ASSERT_GL_NO_ERROR();
}

// Test a state desync that can occur when using a streaming index buffer in GL in concert with
// deleting the applied index buffer.
TEST_P(DrawElementsTest, DeletingAfterStreamingIndexes)
{
    // Init program
    constexpr char kVS[] =
        "attribute vec2 position;\n"
        "attribute vec2 testFlag;\n"
        "varying vec2 v_data;\n"
        "void main() {\n"
        "  gl_Position = vec4(position, 0, 1);\n"
        "  v_data = testFlag;\n"
        "}";

    constexpr char kFS[] =
        "varying highp vec2 v_data;\n"
        "void main() {\n"
        "  gl_FragColor = vec4(v_data, 0, 1);\n"
        "}";

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

    GLint positionLocation = glGetAttribLocation(mProgram, "position");
    ASSERT_NE(-1, positionLocation);

    GLint testFlagLocation = glGetAttribLocation(mProgram, "testFlag");
    ASSERT_NE(-1, testFlagLocation);

    mIndexBuffers.resize(3u);
    glGenBuffers(3, &mIndexBuffers[0]);

    mVertexArrays.resize(2);
    glGenVertexArrays(2, &mVertexArrays[0]);

    mVertexBuffers.resize(2);
    glGenBuffers(2, &mVertexBuffers[0]);

    std::vector<GLuint> indexData[2];
    indexData[0].push_back(0);
    indexData[0].push_back(1);
    indexData[0].push_back(2);
    indexData[0].push_back(2);
    indexData[0].push_back(3);
    indexData[0].push_back(0);

    indexData[1] = indexData[0];
    for (GLuint &item : indexData[1])
    {
        item += 4u;
    }

    std::vector<GLfloat> positionData = {// quad verts
                                         -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
                                         // Repeat position data
                                         -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};

    std::vector<GLfloat> testFlagData = {// red
                                         1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
                                         // green
                                         0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f};

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[0].size(), &indexData[0][0],
                 GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[2]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[0].size(), &indexData[0][0],
                 GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[1].size(), &indexData[1][0],
                 GL_STATIC_DRAW);

    // Initialize first vertex array with second index buffer
    glBindVertexArray(mVertexArrays[0]);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[1]);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],
                 GL_STATIC_DRAW);
    glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
    glEnableVertexAttribArray(positionLocation);

    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * testFlagData.size(), &testFlagData[0],
                 GL_STATIC_DRAW);
    glVertexAttribPointer(testFlagLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
    glEnableVertexAttribArray(testFlagLocation);

    // Initialize second vertex array with first index buffer
    glBindVertexArray(mVertexArrays[1]);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]);

    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[0]);
    glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
    glEnableVertexAttribArray(positionLocation);

    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[1]);
    glVertexAttribPointer(testFlagLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
    glEnableVertexAttribArray(testFlagLocation);

    ASSERT_GL_NO_ERROR();

    glBindVertexArray(mVertexArrays[0]);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    glBindVertexArray(mVertexArrays[1]);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    glBindVertexArray(mVertexArrays[0]);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Trigger the bug here.
    glDeleteBuffers(1, &mIndexBuffers[2]);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    ASSERT_GL_NO_ERROR();
}

// Verify that detaching shaders after linking doesn't break draw calls
TEST_P(DrawElementsTest, DrawWithDetachedShaders)
{
    const auto &vertices = GetIndexedQuadVertices();

    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    GLBuffer indexBuffer;
    const auto &indices = GetQuadIndices();
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), indices.data(),
                 GL_STATIC_DRAW);
    ASSERT_GL_NO_ERROR();

    GLuint vertexShader   = CompileShader(GL_VERTEX_SHADER, essl3_shaders::vs::Simple());
    GLuint fragmentShader = CompileShader(GL_FRAGMENT_SHADER, essl3_shaders::fs::Red());
    ASSERT_NE(0u, vertexShader);
    ASSERT_NE(0u, fragmentShader);

    GLuint program = glCreateProgram();
    glAttachShader(program, vertexShader);
    glAttachShader(program, fragmentShader);

    glLinkProgram(program);

    GLint linkStatus;
    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
    EXPECT_EQ(GL_TRUE, linkStatus);

    glDetachShader(program, vertexShader);
    glDetachShader(program, fragmentShader);
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    ASSERT_GL_NO_ERROR();

    glUseProgram(program);

    GLint posLocation = glGetAttribLocation(program, essl3_shaders::PositionAttrib());
    ASSERT_NE(-1, posLocation);

    GLVertexArray vertexArray;
    glBindVertexArray(vertexArray);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posLocation);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, nullptr);
    ASSERT_GL_NO_ERROR();

    glDeleteProgram(program);
    ASSERT_GL_NO_ERROR();
}

// Test drawing to part of the indices in an index buffer, and then all of them.
TEST_P(DrawElementsTest, PartOfIndexBufferThenAll)
{
    // Init program
    constexpr char kVS[] =
        "attribute vec2 position;\n"
        "attribute vec2 testFlag;\n"
        "varying vec2 v_data;\n"
        "void main() {\n"
        "  gl_Position = vec4(position, 0, 1);\n"
        "  v_data = testFlag;\n"
        "}";

    constexpr char kFS[] =
        "varying highp vec2 v_data;\n"
        "void main() {\n"
        "  gl_FragColor = vec4(v_data, 0, 1);\n"
        "}";

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

    GLint positionLocation = glGetAttribLocation(mProgram, "position");
    ASSERT_NE(-1, positionLocation);

    GLint testFlagLocation = glGetAttribLocation(mProgram, "testFlag");
    ASSERT_NE(-1, testFlagLocation);

    mIndexBuffers.resize(1);
    glGenBuffers(1, &mIndexBuffers[0]);

    mVertexArrays.resize(1);
    glGenVertexArrays(1, &mVertexArrays[0]);

    mVertexBuffers.resize(2);
    glGenBuffers(2, &mVertexBuffers[0]);

    std::vector<GLubyte> indexData[2];
    indexData[0].push_back(0);
    indexData[0].push_back(1);
    indexData[0].push_back(2);
    indexData[0].push_back(2);
    indexData[0].push_back(3);
    indexData[0].push_back(0);
    indexData[0].push_back(4);
    indexData[0].push_back(5);
    indexData[0].push_back(6);
    indexData[0].push_back(6);
    indexData[0].push_back(7);
    indexData[0].push_back(4);

    // Make a copy:
    indexData[1] = indexData[0];

    std::vector<GLfloat> positionData = {// quad verts
                                         -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f,
                                         // Repeat position data
                                         -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f};

    std::vector<GLfloat> testFlagData = {// red
                                         1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f,
                                         // green
                                         0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f};

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * indexData[0].size(), &indexData[0][0],
                 GL_STATIC_DRAW);

    glBindVertexArray(mVertexArrays[0]);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]);
    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],
                 GL_STATIC_DRAW);
    glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
    glEnableVertexAttribArray(positionLocation);

    glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * testFlagData.size(), &testFlagData[0],
                 GL_STATIC_DRAW);
    glVertexAttribPointer(testFlagLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
    glEnableVertexAttribArray(testFlagLocation);

    ASSERT_GL_NO_ERROR();

    // Draw with just the second set of 6 items, then first 6, and then the entire index buffer
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, reinterpret_cast<const void *>(6));
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Reload the buffer again with a copy of the same data
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * indexData[1].size(), &indexData[1][0],
                 GL_STATIC_DRAW);

    // Draw with just the first 6 indices, and then with the entire index buffer
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

    glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    // Reload the buffer again with a copy of the same data
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * indexData[0].size(), &indexData[0][0],
                 GL_STATIC_DRAW);

    // This time, do not check color between draws (which causes a flush):
    // Draw with just the second set of 6 items, then first 6, and then the entire index buffer
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, reinterpret_cast<const void *>(6));
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, nullptr);
    glDrawElements(GL_TRIANGLES, 12, GL_UNSIGNED_BYTE, nullptr);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    ASSERT_GL_NO_ERROR();
}

// Test that glDrawElements call with different index buffer offsets work as expected
TEST_P(DrawElementsTest, DrawElementsWithDifferentIndexBufferOffsets)
{
    const std::array<Vector3, 4> &vertices = GetIndexedQuadVertices();
    const std::array<GLushort, 6> &indices = GetQuadIndices();

    glClearColor(0.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT);

    ANGLE_GL_PROGRAM(programDrawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
    ANGLE_GL_PROGRAM(programDrawGreen, essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
    ANGLE_GL_PROGRAM(programDrawBlue, essl3_shaders::vs::Simple(), essl3_shaders::fs::Blue());

    glUseProgram(programDrawRed);

    GLuint vertexArray;
    glGenVertexArrays(1, &vertexArray);
    glBindVertexArray(vertexArray);
    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    GLint posLocation = glGetAttribLocation(programDrawRed, essl3_shaders::PositionAttrib());
    ASSERT_NE(-1, posLocation);
    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posLocation);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    // Draw both triangles of quad
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices.data());
    EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 2, GLColor::red);

    glUseProgram(programDrawGreen);

    GLuint vertexArray1;
    glGenVertexArrays(1, &vertexArray1);
    glBindVertexArray(vertexArray1);
    GLBuffer vertexBuffer1;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer1);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    posLocation = glGetAttribLocation(programDrawGreen, essl3_shaders::PositionAttrib());
    ASSERT_NE(-1, posLocation);
    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posLocation);

    GLBuffer indexBuffer;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices[0]) * indices.size(), indices.data(),
                 GL_DYNAMIC_DRAW);

    // Draw right triangle of quad
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, reinterpret_cast<const void *>(6));
    EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 2, GLColor::green);

    glUseProgram(programDrawBlue);

    glBindVertexArray(vertexArray);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    posLocation = glGetAttribLocation(programDrawBlue, essl3_shaders::PositionAttrib());
    ASSERT_NE(-1, posLocation);
    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posLocation);

    // Draw both triangles of quad
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices.data());
    EXPECT_PIXEL_COLOR_EQ(0, 1, GLColor::blue);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 2, GLColor::blue);

    glDeleteVertexArrays(1, &vertexArray);
    glDeleteVertexArrays(1, &vertexArray1);

    ASSERT_GL_NO_ERROR();
}

// Test one element buffer bind to two vertexArrays and switch vertexArray should draw correctly
TEST_P(DrawElementsTest, TwoVertexArraysWithSameElementBuffer)
{
    glClearColor(0.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT);

    ANGLE_GL_PROGRAM(programDrawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
    glUseProgram(programDrawRed);
    GLint posLocation = glGetAttribLocation(programDrawRed, essl3_shaders::PositionAttrib());
    ASSERT_NE(-1, posLocation);

    GLBuffer vertexBuffer;
    const std::array<Vector3, 4> &vertices = GetIndexedQuadVertices();
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    GLBuffer elementBuffer;
    std::array<GLubyte, 6> zeros;
    size_t elementBufferSize = sizeof(zeros[0]) * zeros.size();
    zeros.fill(0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBufferSize, zeros.data(), GL_DYNAMIC_DRAW);

    // Set up two vertex arrays using same set of buffers. Since initial element buffer all point to
    // the same vertex, it should only draw one point
    GLuint vertexArray[2];
    glGenVertexArrays(2, vertexArray);

    glBindVertexArray(vertexArray[0]);
    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posLocation);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, reinterpret_cast<const void *>(0));

    glBindVertexArray(vertexArray[1]);
    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posLocation);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, reinterpret_cast<const void *>(0));

    // Use vertexArray[0] and update elementBuffer and draw
    const std::array<GLubyte, 6> &indices = {0, 1, 2, 0, 2, 3};
    glBindVertexArray(vertexArray[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBufferSize, indices.data(), GL_DYNAMIC_DRAW);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE, reinterpret_cast<const void *>(0));

    // Use vertexArray[1] and and draw
    glBindVertexArray(vertexArray[1]);
    size_t elementBufferOffset = sizeof(indices[0]) * 3;
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_BYTE,
                   reinterpret_cast<const void *>(elementBufferOffset));

    // We should see both triangles
    EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);

    glDeleteVertexArrays(2, vertexArray);

    ASSERT_GL_NO_ERROR();
}

// Test that drawing with index value a little bit less than or equal to GL_MAX_ELEMENT_INDEX
// should not have error
TEST_P(DrawElementsTest, MaxElementIndex)
{
    constexpr GLuint indicesNumber = 10;
    std::array<GLuint, indicesNumber> indices;
    GLint64 maxIndex = 0;
    GLBuffer vertexBuffer;

    ANGLE_GL_PROGRAM(programDrawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
    glUseProgram(programDrawRed);
    GLint posLocation = glGetAttribLocation(programDrawRed, essl3_shaders::PositionAttrib());
    ASSERT_NE(-1, posLocation);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);

    glEnableVertexAttribArray(posLocation);
    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glVertexAttribDivisor(posLocation, 0xFFFFFFFF);

    glGetInteger64v(GL_MAX_ELEMENT_INDEX, &maxIndex);
    // Draw using index from maxIndex - 9 to maxIndex. Should have no error
    for (GLuint i = 0; i < indicesNumber; ++i)
    {
        indices[i] = static_cast<GLuint>(maxIndex) - (indicesNumber - 1) + i;
    }

    glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(indicesNumber), GL_UNSIGNED_INT,
                   indices.data());
    ASSERT_GL_NO_ERROR();
}

// Test that the offset in the index buffer is forced to be a multiple of the element size
TEST_P(WebGLDrawElementsTest, DrawElementsTypeAlignment)
{
    constexpr char kVS[] =
        "attribute vec3 a_pos;\n"
        "void main()\n"
        "{\n"
        "    gl_Position = vec4(a_pos, 1.0);\n"
        "}\n";

    ANGLE_GL_PROGRAM(program, kVS, essl1_shaders::fs::Blue());

    GLint posLocation = glGetAttribLocation(program, "a_pos");
    ASSERT_NE(-1, posLocation);
    glUseProgram(program);

    const auto &vertices = GetQuadVertices();

    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posLocation);

    GLBuffer indexBuffer;
    const GLubyte indices1[] = {0, 0, 0, 0, 0, 0};
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices1), indices1, GL_STATIC_DRAW);

    ASSERT_GL_NO_ERROR();

    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, nullptr);
    ASSERT_GL_NO_ERROR();

    const GLushort indices2[] = {0, 0, 0, 0, 0, 0};
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices2), indices2, GL_STATIC_DRAW);

    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, reinterpret_cast<const void *>(1));
    EXPECT_GL_ERROR(GL_INVALID_OPERATION);
}

// Test that subsequent UNSIGNED_BYTE primitive restart draws work without problems.
// At the time of writing, Metal backend would use incorrect internal offset and
// fail the draw with validation.
TEST_P(DrawElementsTest, DrawElementsUintByteBytePrimitiveRestart)
{
    glClearColor(1.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT);
    const char kVS[] = R"(#version 300 es
in vec4 a_position;
void main()
{
    gl_Position = a_position;
    gl_PointSize = 2.0;
})";
    ANGLE_GL_PROGRAM(mProgram, kVS, essl3_shaders::fs::Green());
    glUseProgram(mProgram);

    GLBuffer vertexBuffer;
    std::array<GLfloat, 3> vertices{-1.0f, -1.0f, 0.5f};
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    GLint posLocation = glGetAttribLocation(mProgram, essl3_shaders::PositionAttrib());
    ASSERT_NE(-1, posLocation);
    glEnableVertexAttribArray(posLocation);
    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    GLubyte indices[4] = {0xff, 0xff, 0, 0};
    GLBuffer elementBuffer;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    ASSERT_GL_NO_ERROR();

    glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
    glDrawElements(GL_POINTS, 1, GL_UNSIGNED_SHORT, nullptr);
    ASSERT_GL_NO_ERROR();
    glDrawElements(GL_POINTS, 4, GL_UNSIGNED_BYTE, nullptr);
    ASSERT_GL_NO_ERROR();
    glDrawElements(GL_POINTS, 4, GL_UNSIGNED_BYTE, nullptr);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    EXPECT_PIXEL_RECT_EQ(1, 1, getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
    ASSERT_GL_NO_ERROR();
}

// Tests various draw element parameter, vertex buffer contents variants.
// Does not yet test using GL_BYTE 0xFF, GL_SHORT 0xFFFF with primitive restart off.
TEST_P(DrawElementsVariantsTest, Draw)
{
    const bool hasProvokingVertexExt = IsGLExtensionEnabled("GL_ANGLE_provoking_vertex");
    ANGLE_SKIP_TEST_IF(useProvokingVertexFirst() && !hasProvokingVertexExt);

    glClearColor(1.f, 0.f, 0.f, 1.f);

    constexpr char kFlatVS[] = R"(#version 300 es
flat out float p;
in vec4 a_position;
in float a_vertexMark;
void main()
{
    p = a_vertexMark;
    gl_Position = a_position;
})";

    constexpr char kFlatFS[] = R"(#version 300 es
precision highp float;
flat in highp float p;
out vec4 my_FragColor;
void main()
{
    if (p >= 0.5)
        my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
    else
        my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
})";
    GLProgram program;
    if (useFlat())
    {
        program.makeRaster(kFlatVS, kFlatFS);
    }
    else
    {
        program.makeRaster(essl3_shaders::vs::Simple(), essl3_shaders::fs::Green());
    }
    ASSERT_GL_NO_ERROR();
    glUseProgram(program);

    GLBuffer vertexBuffer;
    std::array<GLfloat, 12> vertices = {
        -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
    };
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    // First vertex convention, triangle strip {0,1,2,3}: 0, 1 are provoking.
    GLBuffer markFirstConventionStrip;
    std::array<GLfloat, 4> markFirstStripData = {1.0f, 1.0f, 0.0f, 0.0f};
    glBindBuffer(GL_ARRAY_BUFFER, markFirstConventionStrip);
    glBufferData(GL_ARRAY_BUFFER, sizeof(markFirstStripData), markFirstStripData.data(),
                 GL_STATIC_DRAW);

    // First vertex convention, triangle strip {0,1,2,0xff,2,1,3} and triangles {0,1,2,2,1,3}:
    // 0, 2 are provoking.
    GLBuffer markFirstConventionTriangles;
    std::array<GLfloat, 4> markFirstTriData = {1.0f, 0.0f, 1.0f, 0.0f};
    glBindBuffer(GL_ARRAY_BUFFER, markFirstConventionTriangles);
    glBufferData(GL_ARRAY_BUFFER, sizeof(markFirstTriData), markFirstTriData.data(),
                 GL_STATIC_DRAW);

    // Last vertex convention: triangle strip {0,1,2,3} and triangles {0,1,2,2,1,3}: 2, 3 are
    // provoking.
    GLBuffer markLastConvention;
    std::array<GLfloat, 4> markLastData = {0.0f, 0.0f, 1.0f, 1.0f};
    glBindBuffer(GL_ARRAY_BUFFER, markLastConvention);
    glBufferData(GL_ARRAY_BUFFER, sizeof(markLastData), markLastData.data(), GL_STATIC_DRAW);

    GLubyte contentStrip[]     = {0, 1, 2, 3};
    GLubyte contentTriangles[] = {0, 1, 2, 2, 1, 3};
    GLubyte contentSplit[]     = {0, 1, 2, 0xff, 2, 1, 3};

    if (usePrimitiveRestart())
    {
        glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
    }
    if (useProvokingVertexFirst())
    {
        glProvokingVertexANGLE(GL_FIRST_VERTEX_CONVENTION_ANGLE);
    }

    GLint posLocation = glGetAttribLocation(program, essl3_shaders::PositionAttrib());
    ASSERT_NE(-1, posLocation);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glEnableVertexAttribArray(posLocation);
    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);

    if (useFlat())
    {
        GLint markLocation = glGetAttribLocation(program, "a_vertexMark");
        ASSERT_NE(-1, markLocation);
        if (!useProvokingVertexFirst())
        {
            glBindBuffer(GL_ARRAY_BUFFER, markLastConvention);
        }
        else if (drawStrip() && !splitContent())
        {
            glBindBuffer(GL_ARRAY_BUFFER, markFirstConventionStrip);
        }
        else
        {
            glBindBuffer(GL_ARRAY_BUFFER, markFirstConventionTriangles);
        }
        glEnableVertexAttribArray(markLocation);
        glVertexAttribPointer(markLocation, 1, GL_FLOAT, GL_FALSE, 0, 0);
    }

    std::vector<GLubyte> byteIndices;
    GLsizei contentStartCount = 0;
    uintptr_t offset          = 0;
    if (addOffset())
    {
        byteIndices.push_back(0);
    }
    if (addRestartAtBegin())
    {
        byteIndices.push_back(0xff);
    }
    if (addRestartDegenerate())
    {
        byteIndices.push_back(0);
        byteIndices.push_back(0xff);
    }
    contentStartCount = byteIndices.size();
    if (splitContent())
    {
        byteIndices.insert(byteIndices.end(), std::begin(contentSplit), std::end(contentSplit));
    }
    else if (drawStrip())
    {
        byteIndices.insert(byteIndices.end(), std::begin(contentStrip), std::end(contentStrip));
    }
    else
    {
        byteIndices.insert(byteIndices.end(), std::begin(contentTriangles),
                           std::end(contentTriangles));
    }
    if (addRestartAtEnd())
    {
        byteIndices.push_back(0xff);
    }

    // Prepare typed index data for both buffer and client-side paths.
    std::vector<GLushort> shortIndices;
    std::vector<GLuint> intIndices;
    if (type() == GL_UNSIGNED_SHORT)
    {
        shortIndices = convertIndexBufferWithRestarts<GLushort>(byteIndices);
    }
    else if (type() == GL_UNSIGNED_INT)
    {
        intIndices = convertIndexBufferWithRestarts<GLuint>(byteIndices);
    }

    GLBuffer elementBuffer;
    const void *indices = nullptr;
    if (useClientSideArrays())
    {
        ASSERT_FALSE(addOffset());
        if (type() == GL_UNSIGNED_BYTE)
        {
            indices = byteIndices.data();
        }
        else if (type() == GL_UNSIGNED_SHORT)
        {
            indices = shortIndices.data();
        }
        else
        {
            indices = intIndices.data();
        }
    }
    else
    {
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
        if (type() == GL_UNSIGNED_BYTE)
        {
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, byteIndices.size(), byteIndices.data(),
                         GL_STATIC_DRAW);
            if (addOffset())
            {
                offset = 1;
            }
        }
        else if (type() == GL_UNSIGNED_SHORT)
        {
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, 2 * shortIndices.size(), shortIndices.data(),
                         GL_STATIC_DRAW);
            if (addOffset())
            {
                offset = 2;
            }
        }
        else
        {
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, 4 * intIndices.size(), intIndices.data(),
                         GL_STATIC_DRAW);
            if (addOffset())
            {
                offset = 4;
            }
        }
        indices = reinterpret_cast<const void *>(offset);
    }
    ASSERT_GL_NO_ERROR();

    glClear(GL_COLOR_BUFFER_BIT);

    GLenum mode   = drawStrip() ? GL_TRIANGLE_STRIP : GL_TRIANGLES;
    GLsizei count = byteIndices.size() - (addOffset() ? 1 : 0);
    glDrawElements(mode, count, type(), indices);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
    ASSERT_GL_NO_ERROR();

    // Test drawing again to verify caching behavior and buffer regeneration.
    glClear(GL_COLOR_BUFFER_BIT);
    glDrawElements(mode, count, type(), indices);
    glDrawElements(mode, count, type(), indices);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() - 1, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::green);
    ASSERT_GL_NO_ERROR();

    // Test drawing again with a subrange, to check that possibly cached ranges
    // are cropped correctly. Draw only one triangle.
    glClear(GL_COLOR_BUFFER_BIT);
    count = contentStartCount + 3 - (addOffset() ? 1 : 0);
    glDrawElements(mode, count, type(), indices);
    ASSERT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, 0, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(0, getWindowHeight() - 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);
    ASSERT_GL_NO_ERROR();
}

class WebGLDrawElementsTest3 : public WebGLDrawElementsTest
{};
// Test one element buffer bind to two vertexArrays and switch vertexArray should draw correctly.
// With WebGL, we will go through element buffer range validation check which will catch bugs if the
// cached index range is incorrect.
TEST_P(WebGLDrawElementsTest3, TwoVertexArraysWithSameElementBuffer)
{
    glClearColor(0.f, 0.f, 0.f, 1.f);
    glClear(GL_COLOR_BUFFER_BIT);

    ANGLE_GL_PROGRAM(programDrawRed, essl3_shaders::vs::Simple(), essl3_shaders::fs::Red());
    glUseProgram(programDrawRed);
    GLint posLocation = glGetAttribLocation(programDrawRed, essl3_shaders::PositionAttrib());
    ASSERT_NE(-1, posLocation);

    GLBuffer vertexBuffer;
    const std::array<Vector3, 4> &vertices = GetIndexedQuadVertices();
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices[0]) * vertices.size(), vertices.data(),
                 GL_STATIC_DRAW);

    GLBuffer elementBuffer;
    std::array<GLuint, 6> invalidIndexData;
    size_t elementBufferSize = sizeof(invalidIndexData[0]) * invalidIndexData.size();
    invalidIndexData.fill(0xffffffff);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBufferSize, invalidIndexData.data(),
                 GL_DYNAMIC_DRAW);

    // Set up two vertex arrays using same set of buffers. Since initial element buffer all point to
    // 0xffffffff, which exceed max index range, it should generate GL_INVALID_OPERATION.
    GLuint vertexArray[2];
    glGenVertexArrays(2, vertexArray);

    glBindVertexArray(vertexArray[0]);
    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posLocation);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, reinterpret_cast<const void *>(0));

    glBindVertexArray(vertexArray[1]);
    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posLocation);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBuffer);
    size_t elementBufferOffset1 = sizeof(invalidIndexData[0]) * 3;
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT,
                   reinterpret_cast<const void *>(elementBufferOffset1));

    // This should alsop clear the context error code.
    ASSERT_TRUE(glGetError() == GL_INVALID_OPERATION);

    // Use vertexArray[0] and update elementBuffer and draw
    const std::array<GLuint, 6> &indices = {0, 1, 2, 0, 2, 3};
    glBindVertexArray(vertexArray[0]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBufferSize, indices.data(), GL_DYNAMIC_DRAW);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, reinterpret_cast<const void *>(0));

    // Use vertexArray[1] and and draw
    glBindVertexArray(vertexArray[1]);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT,
                   reinterpret_cast<const void *>(elementBufferOffset1));
    ASSERT_TRUE(glGetError() == GL_NO_ERROR);

    // We should see both triangles
    EXPECT_PIXEL_COLOR_EQ(1, 1, GLColor::red);
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() - 1, getWindowHeight() - 1, GLColor::red);

    glDeleteVertexArrays(2, vertexArray);

    ASSERT_GL_NO_ERROR();
}

// Test that uploading a large index buffer (> 1MB) via glBufferSubData
// does not corrupt the data in the chunks after the first 1MB.
// This is a regression test for a bug in Metal backend where the offset
// was not applied to the source pointer when chunking the upload.
TEST_P(DrawElementsTest, LargeIndexBufferSubData)
{
    // We want the buffer size to be slightly larger than 1MB.
    // 1MB = 1024 * 1024 = 1,048,576 bytes.
    // With GL_UNSIGNED_INT (4 bytes), 1MB is 262,144 indices.
    // We use 263,168 indices (1,052,672 bytes).
    constexpr size_t kIndexCount = 263168;
    constexpr size_t kBufferSize = kIndexCount * sizeof(GLuint);

    // Staging buffer chunk size is 1MB.
    // First chunk: indices 0 to 262143.
    // Second chunk: indices 262144 to 263167.

    // Prepare indices.
    // We want to draw a triangle using the last 3 indices in the buffer.
    // These indices will point to green vertices.
    // The indices at the start of the buffer will point to red vertices.
    std::vector<GLuint> indices(kIndexCount, 0);
    // Start of buffer: points to red vertices (0, 1, 2)
    indices[0] = 0;
    indices[1] = 1;
    indices[2] = 2;
    // End of buffer: points to green vertices (3, 4, 5)
    indices[kIndexCount - 3] = 3;
    indices[kIndexCount - 2] = 4;
    indices[kIndexCount - 1] = 5;

    // Vertices with position and color.
    struct Vertex
    {
        float position[3];
        GLubyte color[4];
    };

    const std::vector<Vertex> vertices = {
        // Red triangle
        {{-1.0f, -1.0f, 0.0f}, {255, 0, 0, 255}},
        {{3.0f, -1.0f, 0.0f}, {255, 0, 0, 255}},
        {{-1.0f, 3.0f, 0.0f}, {255, 0, 0, 255}},
        // Green triangle
        {{-1.0f, -1.0f, 0.0f}, {0, 255, 0, 255}},
        {{3.0f, -1.0f, 0.0f}, {0, 255, 0, 255}},
        {{-1.0f, 3.0f, 0.0f}, {0, 255, 0, 255}},
    };

    // Shader program
    const char *kVS =
        "attribute vec3 a_position;\n"
        "attribute vec4 a_color;\n"
        "varying vec4 v_color;\n"
        "void main()\n"
        "{\n"
        "    gl_Position = vec4(a_position, 1.0);\n"
        "    v_color = a_color;\n"
        "}\n";
    const char *kFS =
        "precision mediump float;\n"
        "varying vec4 v_color;\n"
        "void main()\n"
        "{\n"
        "    gl_FragColor = v_color;\n"
        "}\n";

    ANGLE_GL_PROGRAM(program, kVS, kFS);
    glUseProgram(program);

    GLint posLocation   = glGetAttribLocation(program, "a_position");
    GLint colorLocation = glGetAttribLocation(program, "a_color");
    ASSERT_NE(-1, posLocation);
    ASSERT_NE(-1, colorLocation);

    GLVertexArray vao;
    glBindVertexArray(vao);

    GLBuffer vertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(),
                 GL_STATIC_DRAW);

    glVertexAttribPointer(posLocation, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
                          reinterpret_cast<const void *>(offsetof(Vertex, position)));
    glEnableVertexAttribArray(posLocation);
    glVertexAttribPointer(colorLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex),
                          reinterpret_cast<const void *>(offsetof(Vertex, color)));
    glEnableVertexAttribArray(colorLocation);

    GLBuffer indexBuffer;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    // Allocate
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, kBufferSize, nullptr, GL_STATIC_DRAW);
    // Upload > 1MB
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, kBufferSize, indices.data());

    ASSERT_GL_NO_ERROR();

    // Draw using the indices at the end of the buffer.
    // Offset in bytes: (kIndexCount - 3) * sizeof(GLuint)
    size_t drawOffset = (kIndexCount - 3) * sizeof(GLuint);
    glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, reinterpret_cast<const void *>(drawOffset));

    ASSERT_GL_NO_ERROR();

    // If the bug is present, the indices at the end were copied from the start (which point to
    // red). If fixed, they point to green.
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::green);
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrawElementsTest);
ANGLE_INSTANTIATE_TEST_ES3(DrawElementsTest);

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(DrawElementsVariantsTest);

ANGLE_INSTANTIATE_TEST_VARIANTS_COMBINE_7(
    NoRestart,
    DrawElementsVariantsTest,
    DrawElementsVariantsTestPrint,
    testing::Values(GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT),
    testing::Bool(),                                  // useFlat
    testing::Values(PrimitiveRestartMode::Disabled),  // primitiveRestartMode
    testing::Bool(),                                  // drawStrip
    testing::Values(IndicesMode::Buffer,
                    IndicesMode::BufferAndOffset,
                    IndicesMode::ClientSideArray),
    testing::Values(RestartOption::None),  // restartOption
    testing::Bool(),                       // useProvokingVertexFirst
    ANGLE_ALL_TEST_PLATFORMS_ES3);

ANGLE_INSTANTIATE_TEST_VARIANTS_COMBINE_7(
    Restart,
    DrawElementsVariantsTest,
    DrawElementsVariantsTestPrint,
    testing::Values(GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_UNSIGNED_INT),
    testing::Bool(),  // useFlat
    testing::Values(PrimitiveRestartMode::Enabled, PrimitiveRestartMode::EnabledSplitContent),
    testing::Bool(),  // drawStrip
    testing::Values(IndicesMode::Buffer,
                    IndicesMode::BufferAndOffset,
                    IndicesMode::ClientSideArray),
    testing::Values(RestartOption::None,
                    RestartOption::AtBegin,
                    RestartOption::AtEnd,
                    RestartOption::Degenerate),
    testing::Bool(),  // useProvokingVertexFirst
    ANGLE_ALL_TEST_PLATFORMS_ES3);

ANGLE_INSTANTIATE_TEST_ES2(WebGLDrawElementsTest);
ANGLE_INSTANTIATE_TEST_ES3(WebGLDrawElementsTest3);
}  // namespace
