//
// 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.
//

#include "test_utils/ANGLETest.h"

#include "test_utils/gl_raii.h"

using namespace angle;

class LineLoopTest : public ANGLETest<>
{
  protected:
    LineLoopTest()
    {
        setWindowWidth(256);
        setWindowHeight(256);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    void testSetUp() override
    {
        mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
        if (mProgram == 0)
        {
            FAIL() << "shader compilation failed.";
        }

        mPositionLocation = glGetAttribLocation(mProgram, essl1_shaders::PositionAttrib());
        mColorLocation    = glGetUniformLocation(mProgram, essl1_shaders::ColorUniform());

        glBlendFunc(GL_ONE, GL_ONE);
        glEnable(GL_BLEND);
        glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

        ASSERT_GL_NO_ERROR();
    }

    void testTearDown() override { glDeleteProgram(mProgram); }

    void checkPixels()
    {
        std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4);
        glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
                     &pixels[0]);

        ASSERT_GL_NO_ERROR();

        for (int y = 0; y < getWindowHeight(); y++)
        {
            for (int x = 0; x < getWindowWidth(); x++)
            {
                const GLubyte *pixel = &pixels[0] + ((y * getWindowWidth() + x) * 4);

                EXPECT_EQ(pixel[0], 0) << "Failed at " << x << ", " << y << std::endl;
                EXPECT_EQ(pixel[1], pixel[2]) << "Failed at " << x << ", " << y << std::endl;
                ASSERT_EQ(pixel[3], 255) << "Failed at " << x << ", " << y << std::endl;
            }
        }
    }

    void preTestUpdateBuffer(GLuint framebuffer, GLuint texture, GLuint buffer, GLsizei size)
    {
        GLsizei uboSize = std::max(size, 16);
        const std::vector<uint32_t> initialData((uboSize + 3) / 4, 0x1234567u);

        glBindTexture(GL_TEXTURE_2D, texture);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);

        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
                               0);

        glBindBuffer(GL_UNIFORM_BUFFER, buffer);
        glBufferData(GL_UNIFORM_BUFFER, uboSize, initialData.data(), GL_DYNAMIC_DRAW);
        glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);

        constexpr char kVerifyUBO[] = R"(#version 300 es
precision mediump float;
uniform block {
    uint data;
} ubo;
out vec4 colorOut;
void main()
{
    if (ubo.data == 0x1234567u)
        colorOut = vec4(0, 1.0, 0, 1.0);
    else
        colorOut = vec4(1.0, 0, 0, 1.0);
})";

        ANGLE_GL_PROGRAM(verifyUbo, essl3_shaders::vs::Simple(), kVerifyUBO);

        glDisable(GL_BLEND);
        drawQuad(verifyUbo, essl3_shaders::PositionAttrib(), 0.5);

        EXPECT_GL_NO_ERROR();

        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }

    void runTestBlend(GLenum indexType, GLuint indexBuffer, const void *indexPtr)
    {
        glClear(GL_COLOR_BUFFER_BIT);

        static const GLfloat loopPositions[] = {0.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f,  0.0f,
                                                0.0f,  0.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f,
                                                -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f};

        static const GLfloat stripPositions[] = {-0.5f, -0.5f, -0.5f, 0.5f,
                                                 0.5f,  0.5f,  0.5f,  -0.5f};
        static const GLushort stripIndices[]  = {1, 0, 3, 2, 1};

        glEnable(GL_BLEND);

        glUseProgram(mProgram);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
        glEnableVertexAttribArray(mPositionLocation);
        glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, loopPositions);
        glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
        glDrawElements(GL_LINE_LOOP, 4, indexType, indexPtr);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, stripPositions);
        glUniform4f(mColorLocation, 0, 1, 0, 1);
        glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_SHORT, stripIndices);

        checkPixels();
    }

    void runTestNoBlend(GLenum indexType, GLuint indexBuffer, const void *indexPtr)
    {
        glClear(GL_COLOR_BUFFER_BIT);

        static const GLfloat loopPositions[] = {0.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f,  0.0f,
                                                0.0f,  0.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f,
                                                -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f};

        static const GLfloat stripPositions[] = {-0.5f, -0.5f, -0.5f, 0.5f,
                                                 0.5f,  0.5f,  0.5f,  -0.5f};
        static const GLushort stripIndices[]  = {1, 0, 3, 2, 1};

        std::vector<GLColor> expectedPixels(getWindowWidth() * getWindowHeight());
        std::vector<GLColor> renderedPixels(getWindowWidth() * getWindowHeight());

        glUseProgram(mProgram);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
        glEnableVertexAttribArray(mPositionLocation);
        glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, loopPositions);
        glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
        glDrawElements(GL_LINE_LOOP, 4, indexType, indexPtr);

        glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
                     renderedPixels.data());

        glClear(GL_COLOR_BUFFER_BIT);

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
        glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, stripPositions);
        glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
        glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_SHORT, stripIndices);

        glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
                     expectedPixels.data());

        for (int y = 0; y < getWindowHeight(); ++y)
        {
            for (int x = 0; x < getWindowWidth(); ++x)
            {
                int idx = y * getWindowWidth() + x;
                EXPECT_EQ(expectedPixels[idx], renderedPixels[idx])
                    << "Expected pixel at " << x << ", " << y << " to be " << expectedPixels[idx]
                    << std::endl;
            }
        }
    }

    GLuint mProgram;
    GLint mPositionLocation;
    GLint mColorLocation;
};

// Line loop test that draws a loop and a strip, blends the colors, and checks they're correct. No
// index buffer is set.
TEST_P(LineLoopTest, LineLoopUByteIndicesBlend)
{
    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    // On Win7, the D3D SDK Layers emits a false warning for these tests.
    // This doesn't occur on Windows 10 (Version 1511) though.
    ignoreD3D11SDKLayersWarnings();

    static const GLubyte indices[] = {0, 7, 6, 9, 8, 0};
    runTestBlend(GL_UNSIGNED_BYTE, 0, indices + 1);
}

// Line loop test that draws a loop and a strip, blends the colors, and checks they're correct. No
// index buffer is set.
TEST_P(LineLoopTest, LineLoopUShortIndicesBlend)
{
    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLushort indices[] = {0, 7, 6, 9, 8, 0};
    runTestBlend(GL_UNSIGNED_SHORT, 0, indices + 1);
}

// Line loop test that draws a loop and a strip, blends the colors, and checks they're correct. No
// index buffer is set.
TEST_P(LineLoopTest, LineLoopUIntIndicesBlend)
{
    if (!IsGLExtensionEnabled("GL_OES_element_index_uint"))
    {
        return;
    }

    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLuint indices[] = {0, 7, 6, 9, 8, 0};
    runTestBlend(GL_UNSIGNED_INT, 0, indices + 1);
}

// Line loop test that draws a loop and a strip, blends the colors, and checks they're correct.
// Index buffer is set.
TEST_P(LineLoopTest, LineLoopUByteIndexBufferBlend)
{
    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLubyte indices[] = {0, 7, 6, 9, 8, 0};

    GLBuffer buf;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    runTestBlend(GL_UNSIGNED_BYTE, buf, reinterpret_cast<const void *>(sizeof(GLubyte)));
}

// Line loop test that draws a loop and a strip, blends the colors, and checks they're correct.
// Index buffer is set.
TEST_P(LineLoopTest, LineLoopUShortIndexBufferBlend)
{
    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLushort indices[] = {0, 7, 6, 9, 8, 0};

    GLBuffer buf;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    runTestBlend(GL_UNSIGNED_SHORT, buf, reinterpret_cast<const void *>(sizeof(GLushort)));
}

// Line loop test that draws a loop and a strip, blends the colors, and checks they're correct.
// Index buffer is set.
TEST_P(LineLoopTest, LineLoopUIntIndexBufferBlend)
{
    if (!IsGLExtensionEnabled("GL_OES_element_index_uint"))
    {
        return;
    }

    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLuint indices[] = {0, 7, 6, 9, 8, 0};

    GLBuffer buf;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    runTestBlend(GL_UNSIGNED_INT, buf, reinterpret_cast<const void *>(sizeof(GLuint)));
}

// Line loop test that draws a loop, reads it, then a strip, reads it, and confirms the pixels are
// the same. No index buffer is set.
TEST_P(LineLoopTest, LineLoopUByteIndicesNoBlend)
{
    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    // On Win7, the D3D SDK Layers emits a false warning for these tests.
    // This doesn't occur on Windows 10 (Version 1511) though.
    ignoreD3D11SDKLayersWarnings();

    static const GLubyte indices[] = {0, 7, 6, 9, 8, 0};
    runTestNoBlend(GL_UNSIGNED_BYTE, 0, indices + 1);
}

// Line loop test that draws a loop, reads it, then a strip, reads it, and confirms the pixels are
// the same. No index buffer is set.
TEST_P(LineLoopTest, LineLoopUShortIndicesNoBlend)
{
    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLushort indices[] = {0, 7, 6, 9, 8, 0};
    runTestNoBlend(GL_UNSIGNED_SHORT, 0, indices + 1);
}

// Line loop test that draws a loop, reads it, then a strip, reads it, and confirms the pixels are
// the same. No index buffer is set.
TEST_P(LineLoopTest, LineLoopUIntIndicesNoBlend)
{
    if (!IsGLExtensionEnabled("GL_OES_element_index_uint"))
    {
        return;
    }

    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLuint indices[] = {0, 7, 6, 9, 8, 0};
    runTestNoBlend(GL_UNSIGNED_INT, 0, indices + 1);
}

// Line loop test that draws a loop, reads it, then a strip, reads it, and confirms the pixels are
// the same. Index buffer is set.
TEST_P(LineLoopTest, LineLoopUByteIndexBufferNoBlend)
{
    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLubyte indices[] = {0, 7, 6, 9, 8, 0};

    GLBuffer buf;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    runTestNoBlend(GL_UNSIGNED_BYTE, buf, reinterpret_cast<const void *>(sizeof(GLubyte)));
}

// Line loop test that draws a loop, reads it, then a strip, reads it, and confirms the pixels are
// the same. Index buffer is set.
TEST_P(LineLoopTest, LineLoopUShortIndexBufferNoBlend)
{
    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLushort indices[] = {0, 7, 6, 9, 8, 0};

    GLBuffer buf;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    runTestNoBlend(GL_UNSIGNED_SHORT, buf, reinterpret_cast<const void *>(sizeof(GLushort)));
}

// Line loop test that draws a loop, reads it, then a strip, reads it, and confirms the pixels are
// the same. Index buffer is set.
TEST_P(LineLoopTest, LineLoopUIntIndexBufferNoBlend)
{
    if (!IsGLExtensionEnabled("GL_OES_element_index_uint"))
    {
        return;
    }

    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLuint indices[] = {0, 7, 6, 9, 8, 0};

    GLBuffer buf;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    runTestNoBlend(GL_UNSIGNED_INT, buf, reinterpret_cast<const void *>(sizeof(GLuint)));
}

// Test that drawing elements between line loop arrays using the same array buffer does not result
// in incorrect rendering.
TEST_P(LineLoopTest, DrawTriangleElementsBetweenArrays)
{
    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLfloat positions[] = {-0.5f, -0.5f, -0.5f, 0.5f,  0.5f,  0.5f,
                                        0.5f,  -0.5f, -0.5f, -0.5f, -0.1f, 0.1f,
                                        -0.1f, -0.1f, 0.1f,  -0.1f, 0.1f,  0.1f};
    static const GLubyte indices[]   = {5, 6, 7, 5, 7, 8};

    GLBuffer arrayBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);

    GLBuffer indexBuffer;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(mProgram);
    glEnableVertexAttribArray(mPositionLocation);
    glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
    glEnable(GL_BLEND);

    glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    glDrawArrays(GL_LINE_LOOP, 0, 4);

    glUniform4f(mColorLocation, 0.0f, 0.0f, 0.0f, 1.0f);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, nullptr);

    glUniform4f(mColorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    glDrawArrays(GL_LINE_LOOP, 0, 4);

    checkPixels();
}

// Tests drawing elements with line loop arrays and drawing elements with line strip arrays and
// confirms the draws are the same.
TEST_P(LineLoopTest, SimpleDrawArrays)
{
    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLfloat positions[] = {-0.5f, -0.5f, -0.5f, 0.5f,  0.5f,  0.5f,
                                        0.5f,  -0.5f, -0.5f, -0.5f, -0.1f, 0.1f,
                                        -0.1f, -0.1f, 0.1f,  -0.1f, 0.1f,  0.1f};

    std::vector<GLColor> expectedPixels(getWindowWidth() * getWindowHeight());
    std::vector<GLColor> renderedPixels(getWindowWidth() * getWindowHeight());

    GLBuffer arrayBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, arrayBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);

    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(mProgram);
    glEnableVertexAttribArray(mPositionLocation);
    glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, nullptr);

    glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    glDrawArrays(GL_LINE_STRIP, 0, 5);
    glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
                 expectedPixels.data());

    glClear(GL_COLOR_BUFFER_BIT);

    glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    glDrawArrays(GL_LINE_LOOP, 0, 4);
    glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
                 renderedPixels.data());

    for (int y = 0; y < getWindowHeight(); ++y)
    {
        for (int x = 0; x < getWindowWidth(); ++x)
        {
            int idx = y * getWindowWidth() + x;
            EXPECT_EQ(expectedPixels[idx], renderedPixels[idx])
                << "Expected pixel at " << x << ", " << y << " to be " << expectedPixels[idx]
                << std::endl;
        }
    }
}

class LineLoopTestES3 : public LineLoopTest
{};

// Test that uploading data to buffer that's in use then using it for line loop elements works.
TEST_P(LineLoopTestES3, UseAsUBOThenUpdateThenLineLoopUByteIndexBuffer)
{
    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLubyte indices[] = {0, 7, 6, 9, 8, 0};

    GLFramebuffer framebuffer;
    GLTexture texture;

    GLBuffer buf;

    preTestUpdateBuffer(framebuffer, texture, buf, sizeof(indices));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(indices), indices);

    runTestBlend(GL_UNSIGNED_BYTE, buf, reinterpret_cast<const void *>(sizeof(GLubyte)));

    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}

// Test that uploading data to buffer that's in use then using it for line loop elements works.
TEST_P(LineLoopTestES3, UseAsUBOThenUpdateThenLineLoopUShortIndexBuffer)
{
    // http://anglebug.com/42264370
    ANGLE_SKIP_TEST_IF(IsVulkan() && IsQualcomm());

    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLushort indices[] = {0, 7, 6, 9, 8, 0};

    GLFramebuffer framebuffer;
    GLTexture texture;

    GLBuffer buf;

    preTestUpdateBuffer(framebuffer, texture, buf, sizeof(indices));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(indices), indices);

    runTestBlend(GL_UNSIGNED_SHORT, buf, reinterpret_cast<const void *>(sizeof(GLushort)));

    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}

// Test that uploading data to buffer that's in use then using it for line loop elements works.
TEST_P(LineLoopTestES3, UseAsUBOThenUpdateThenLineLoopUIntIndexBuffer)
{
    if (!IsGLExtensionEnabled("GL_OES_element_index_uint"))
    {
        return;
    }

    // http://anglebug.com/42264370
    ANGLE_SKIP_TEST_IF(IsVulkan() && IsQualcomm());

    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    static const GLuint indices[] = {0, 7, 6, 9, 8, 0};

    GLFramebuffer framebuffer;
    GLTexture texture;

    GLBuffer buf;

    preTestUpdateBuffer(framebuffer, texture, buf, sizeof(indices));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buf);
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(indices), indices);

    runTestBlend(GL_UNSIGNED_INT, buf, reinterpret_cast<const void *>(sizeof(GLuint)));

    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}

// Tests an edge case with a very large line loop element count.
// Disabled because it is slow and triggers an internal error.
TEST_P(LineLoopTest, DISABLED_DrawArraysWithLargeCount)
{
    constexpr char kVS[] = "void main() { gl_Position = vec4(0); }";
    constexpr char kFS[] = "void main() { gl_FragColor = vec4(0, 1, 0, 1); }";

    ANGLE_GL_PROGRAM(program, kVS, kFS);
    glUseProgram(program);
    glDrawArrays(GL_LINE_LOOP, 0, 0x3FFFFFFE);
    EXPECT_GL_ERROR(GL_OUT_OF_MEMORY);

    glDrawArrays(GL_LINE_LOOP, 0, 0x1FFFFFFE);
    EXPECT_GL_NO_ERROR();
}

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

TEST_P(LineLoopPrimitiveRestartTest, LineLoopWithPrimitiveRestart)
{
    constexpr char kVS[] = R"(#version 300 es
in vec2 a_position;
// x,y = offset, z = scale
in vec3 a_transform;

invariant gl_Position;
void main()
{
    vec2 v_position = a_transform.z * a_position + a_transform.xy;
    gl_Position = vec4(v_position, 0.0, 1.0);
})";

    constexpr char kFS[] = R"(#version 300 es
precision highp float;
layout (location=0) out vec4 fragColor;
void main()
{
    fragColor = vec4(1.0, 0.0, 0.0, 1.0);
})";

    ANGLE_GL_PROGRAM(program, kVS, kFS);
    glBindAttribLocation(program, 0, "a_position");
    glBindAttribLocation(program, 1, "a_transform");
    glLinkProgram(program);
    glUseProgram(program);
    ASSERT_GL_NO_ERROR();

    // clang-format off
    constexpr GLfloat vertices[] = {
        0.1, 0.1, -0.1, 0.1, -0.1, -0.1, 0.1, -0.1,
        0.1, 0.1, -0.1, 0.1, -0.1, -0.1, 0.1, -0.1,
        0.1, 0.1, -0.1, 0.1, -0.1, -0.1, 0.1, -0.1,
        0.1, 0.1, -0.1, 0.1, -0.1, -0.1, 0.1, -0.1,
    };

    constexpr GLfloat transform[] = {
        // first loop transform
        0, 0, 9,
        0, 0, 9,
        0, 0, 9,
        0, 0, 9,
        // second loop transform
        0.2, 0.1, 2,
        0.2, 0.1, 2,
        0.2, 0.1, 2,
        0.2, 0.1, 2,
        // third loop transform
        0.5, -0.2, 3,
        0.5, -0.2, 3,
        0.5, -0.2, 3,
        0.5, -0.2, 3,
        // forth loop transform
        -0.8, -0.5, 1,
        -0.8, -0.5, 1,
        -0.8, -0.5, 1,
        -0.8, -0.5, 1,
    };

    constexpr GLushort lineloopAsStripIndices[] = {
        // first strip
        0, 1, 2, 3, 0,
        // second strip
        4, 5, 6, 7, 4,
        // third strip
        8, 9, 10, 11, 8,
        // forth strip
        12, 13, 14, 15, 12 };

    constexpr GLushort lineloopWithRestartIndices[] = {
        // first loop
        0, 1, 2, 3, 0xffff,
        // second loop
        4, 5, 6, 7, 0xffff,
        // third loop
        8, 9, 10, 11, 0xffff,
        // forth loop
        12, 13, 14, 15,
    };
    // clang-format on

    std::vector<GLColor> expectedPixels(getWindowWidth() * getWindowHeight());
    std::vector<GLColor> renderedPixels(getWindowWidth() * getWindowHeight());

    // Draw in non-primitive restart way
    glClear(GL_COLOR_BUFFER_BIT);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    for (int loop = 0; loop < 4; ++loop)
    {
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices + 8 * loop);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, transform + 12 * loop);

        glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_SHORT, lineloopAsStripIndices);
    }

    glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
                 expectedPixels.data());
    ASSERT_GL_NO_ERROR();

    // Draw line loop with primitive restart:
    glClear(GL_COLOR_BUFFER_BIT);

    GLBuffer vertexBuffer[2];
    GLBuffer indexBuffer;

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(lineloopWithRestartIndices),
                 lineloopWithRestartIndices, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(transform), transform, GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

    glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);

    glClear(GL_COLOR_BUFFER_BIT);
    glDrawElements(GL_LINE_LOOP, ArraySize(lineloopWithRestartIndices), GL_UNSIGNED_SHORT, 0);

    glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
                 renderedPixels.data());

    for (int y = 0; y < getWindowHeight(); ++y)
    {
        for (int x = 0; x < getWindowWidth(); ++x)
        {
            int idx = y * getWindowWidth() + x;
            EXPECT_EQ(expectedPixels[idx], renderedPixels[idx])
                << "Expected pixel at " << x << ", " << y << " to be " << expectedPixels[idx]
                << std::endl;
        }
    }
}

// Tests that drawing an element buffer with primitive restart indices only
// does not crash.
TEST_P(LineLoopPrimitiveRestartTest, PrimitiveRestartRestartOnlyIndicesNoCrash)
{
    constexpr char kVS[] = "void main() { gl_Position = vec4(0); }";
    constexpr char kFS[] = "void main() { gl_FragColor = vec4(0, 1, 0, 1); }";
    ANGLE_GL_PROGRAM(program, kVS, kFS);
    glUseProgram(program);
    ASSERT_GL_NO_ERROR();
    std::vector<GLshort> indices(0x1000, static_cast<GLshort>(0xFFFFF));
    GLBuffer indexBuffer;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(indices[0]), &indices[0],
                 GL_STATIC_DRAW);
    glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
    glDrawElements(GL_LINE_LOOP, 0x800, GL_UNSIGNED_SHORT, 0);
    ASSERT_GL_NO_ERROR();
}

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

// Test that it works when there is only one vertex before or after restart index.
TEST_P(LineLoopPrimitiveRestartXfbTest, OneVertexBeforeRestartIndex)
{
    constexpr char kVS[] = R"(#version 300 es
in vec2 a_position;
// x,y = offset, z = scale
in vec3 a_transform;
out float out_float;

invariant gl_Position;
void main()
{
    vec2 v_position = a_transform.z * a_position + a_transform.xy;
    out_float = a_position.x;
    gl_Position = vec4(v_position, 0.0, 1.0);
})";

    constexpr char kFS[] = R"(#version 300 es
precision highp float;
layout (location=0) out vec4 fragColor;
void main()
{
    fragColor = vec4(1.0, 0.0, 0.0, 1.0);
})";

    ANGLE_GL_PROGRAM(program, kVS, kFS);
    glBindAttribLocation(program, 0, "a_position");
    glBindAttribLocation(program, 1, "a_transform");
    const char *varyings[] = {"out_float"};
    glTransformFeedbackVaryings(program, 1, varyings, GL_INTERLEAVED_ATTRIBS);
    glLinkProgram(program);
    glUseProgram(program);
    ASSERT_GL_NO_ERROR();

    // clang-format off
    constexpr GLfloat vertices[] = {
        0.1, 0.1, -0.1, 0.1, -0.1, -0.1, 0.1, -0.1,
        0.4, 0.1, -0.5, 0.1, -0.6, -0.1, 0.7, -0.1,
        0.8, 0.1, -0.9, 0.1, -1.0, -0.1, 1.1, -0.1,
        0.1, 0.1, -0.1, 0.1, -0.1, -0.1, 0.1, -0.1,
    };

    constexpr GLfloat transform[] = {
        // first loop transform
        0, 0, 9,
        0, 0, 9,
        0, 0, 9,
        0, 0, 9,
        // second loop transform
        0.2, 0.1, 2,
        0.2, 0.1, 2,
        0.2, 0.1, 2,
        0.2, 0.1, 2,
        // third loop transform
        0.5, -0.2, 3,
        0.5, -0.2, 3,
        0.5, -0.2, 3,
        0.5, -0.2, 3,
        // forth loop transform
        -0.8, -0.5, 1,
        -0.8, -0.5, 1,
        -0.8, -0.5, 1,
        -0.8, -0.5, 1,
    };

    constexpr GLushort lineloopAsStripIndices[] = {
        // first strip
        0, 1, 2, 3, 0,
        // second strip
        4, 5, 6, 7, 4,
        // third strip
        8, 9, 10, 11, 8,
        // forth strip
        12, 13, 14, 15, 12 };

    constexpr GLushort lineloopWithRestartIndices[] = {
        // first loop
        0, 0xffff,
        4, 5, 6, 7, 0xffff,
        8, 9, 10, 11, 0xffff,
        15,
    };
    // clang-format on

    std::vector<GLColor> expectedPixels(getWindowWidth() * getWindowHeight());
    std::vector<GLColor> renderedPixels(getWindowWidth() * getWindowHeight());

    // Draw in non-primitive restart way
    glClear(GL_COLOR_BUFFER_BIT);

    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);

    for (int loop = 1; loop < 3; ++loop)
    {
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices + 8 * loop);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, transform + 12 * loop);

        glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_SHORT, lineloopAsStripIndices);
    }

    glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
                 expectedPixels.data());
    ASSERT_GL_NO_ERROR();

    // Draw line loop with primitive restart:
    glClear(GL_COLOR_BUFFER_BIT);

    GLBuffer vertexBuffer[2];
    GLBuffer indexBuffer;

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(lineloopWithRestartIndices),
                 lineloopWithRestartIndices, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, 0);

    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[1]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(transform), transform, GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, 0);

    // For xfb
    const GLfloat expected[16] = {0.4, -0.5, -0.5, -0.6, -0.6, 0.7, 0.7, 0.4,
                                  0.8, -0.9, -0.9, -1.0, -1.0, 1.1, 1.1, 0.8};
    unsigned expected_count    = sizeof(expected) / sizeof(expected[0]);
    GLuint xfbBuffer;
    glGenBuffers(1, &xfbBuffer);
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfbBuffer);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, sizeof(expected), nullptr, GL_STATIC_READ);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfbBuffer);

    glBeginTransformFeedback(GL_LINES);
    glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);

    glClear(GL_COLOR_BUFFER_BIT);
    glDrawElements(GL_LINE_LOOP, ArraySize(lineloopWithRestartIndices), GL_UNSIGNED_SHORT, 0);
    glDisable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
    glEndTransformFeedback();

    glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
                 renderedPixels.data());

    for (int y = 0; y < getWindowHeight(); ++y)
    {
        for (int x = 0; x < getWindowWidth(); ++x)
        {
            int idx = y * getWindowWidth() + x;
            EXPECT_EQ(expectedPixels[idx], renderedPixels[idx])
                << "Expected pixel at " << x << ", " << y << " to be " << expectedPixels[idx]
                << std::endl;
        }
    }

    GLfloat *mappedBufferData = nullptr;
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfbBuffer);
    mappedBufferData = (GLfloat *)glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
                                                   sizeof(expected), GL_MAP_READ_BIT);
    if (mappedBufferData != nullptr)
    {
        for (unsigned j = 0; j < expected_count; j++)
        {
            EXPECT_EQ(mappedBufferData[j], expected[j])
                << "Expected pixel at " << j << " to be " << expected[j] << std::endl;
        }
    }

    ASSERT_GL_NO_ERROR();
}

class LineLoopIndirectTest : public LineLoopTest
{
  protected:
    struct DrawCommand
    {
        GLuint count;
        GLuint primCount;
        GLuint firstIndex;
        GLint baseVertex;
        GLuint reservedMustBeZero;
    };

    void initUpdateBuffers(GLuint vertexArray,
                           GLuint vertexBuffer,
                           GLuint indexBuffer,
                           const void *positions,
                           uint32_t positionsSize,
                           const void *indices,
                           uint32_t indicesSize)
    {
        glBindVertexArray(vertexArray);
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);

        glBufferData(GL_ARRAY_BUFFER, positionsSize, positions, GL_STATIC_DRAW);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesSize, indices, GL_STATIC_DRAW);
    }

    void preTestUBOAndInitUpdateBuffers(GLuint vertexArray,
                                        GLuint vertexBuffer,
                                        GLuint indexBuffer,
                                        const void *positions,
                                        GLsizei positionsSize,
                                        const void *indices,
                                        GLsizei indicesSize,
                                        GLuint arrayUpdateFbo,
                                        GLuint arrayUpdateTexture,
                                        GLuint elementUpdateFbo,
                                        GLuint elementUpdateTexture)
    {
        preTestUpdateBuffer(arrayUpdateFbo, arrayUpdateTexture, vertexBuffer, positionsSize);
        preTestUpdateBuffer(elementUpdateFbo, elementUpdateTexture, indexBuffer, indicesSize);

        glBindVertexArray(vertexArray);
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);

        glBufferSubData(GL_ARRAY_BUFFER, 0, positionsSize, positions);
        glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, indicesSize, indices);
    }

    void initIndirectBuffer(GLuint indirectBuffer, GLuint firstIndex)
    {
        DrawCommand indirectData = {};
        indirectData.count       = 4;
        indirectData.firstIndex  = firstIndex;
        indirectData.primCount   = 1;

        glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuffer);
        glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand), &indirectData, GL_STATIC_DRAW);
        ASSERT_GL_NO_ERROR();
    }

    void setVertexAttribs(const void *positions)
    {
        glEnableVertexAttribArray(mPositionLocation);
        glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, positions);
        ASSERT_GL_NO_ERROR();
    }

    static constexpr GLfloat kLoopPositions[]  = {0.0f,  0.0f, 0.0f, 0.0f, 0.0f, 0.0f,  0.0f,
                                                  0.0f,  0.0f, 0.0f, 0.0f, 0.0f, -0.5f, -0.5f,
                                                  -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f};
    static constexpr GLfloat kStripPositions[] = {-0.5f, -0.5f, -0.5f, 0.5f,
                                                  0.5f,  0.5f,  0.5f,  -0.5f};
    static constexpr GLubyte kStripIndices[]   = {1, 0, 3, 2, 1};
};

// Test that drawing a line loop using an index buffer of unsigned bytes works.
TEST_P(LineLoopIndirectTest, UByteIndexIndirectBuffer)
{
    // Old drivers buggy with optimized ConvertIndexIndirectLineLoop shader.
    // http://anglebug.com/40096699
    ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());

    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    // Start at index 1.
    GLuint firstIndex       = 1;
    const GLubyte indices[] = {0, 7, 6, 9, 8, 0};

    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(mProgram);
    ASSERT_GL_NO_ERROR();

    GLVertexArray vertexArray;
    GLBuffer vertexBuffer;
    GLBuffer indexBuffer;

    initUpdateBuffers(vertexArray, vertexBuffer, indexBuffer, kLoopPositions,
                      sizeof(kLoopPositions), indices, sizeof(indices));

    GLBuffer indirectBuffer;
    initIndirectBuffer(indirectBuffer, firstIndex);

    glEnable(GL_BLEND);
    setVertexAttribs(nullptr);
    glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_BYTE, nullptr);
    ASSERT_GL_NO_ERROR();

    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    setVertexAttribs(kStripPositions);
    glUniform4f(mColorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, kStripIndices);
    ASSERT_GL_NO_ERROR();

    checkPixels();
}

// Test that drawing a line loop using an index buffer of unsigned short values works.
TEST_P(LineLoopIndirectTest, UShortIndexIndirectBuffer)
{
    // Old drivers buggy with optimized ConvertIndexIndirectLineLoop shader.
    // http://anglebug.com/40096699
    ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());

    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    // Start at index 1.
    GLuint firstIndex        = 1;
    const GLushort indices[] = {0, 7, 6, 9, 8, 0};

    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(mProgram);
    ASSERT_GL_NO_ERROR();

    GLVertexArray vertexArray;
    GLBuffer vertexBuffer;
    GLBuffer indexBuffer;

    initUpdateBuffers(vertexArray, vertexBuffer, indexBuffer, kLoopPositions,
                      sizeof(kLoopPositions), indices, sizeof(indices));

    GLBuffer indirectBuffer;
    initIndirectBuffer(indirectBuffer, firstIndex);

    glEnable(GL_BLEND);
    setVertexAttribs(nullptr);
    glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_SHORT, nullptr);
    ASSERT_GL_NO_ERROR();

    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    setVertexAttribs(kStripPositions);
    glUniform4f(mColorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, kStripIndices);
    ASSERT_GL_NO_ERROR();

    checkPixels();
}

// Test that uploading data to buffer that's in use then using it for line loop elements works.
TEST_P(LineLoopIndirectTest, UseAsUBOThenUpdateThenUByteIndexIndirectBuffer)
{
    // http://anglebug.com/42264370
    ANGLE_SKIP_TEST_IF(IsVulkan() && IsQualcomm());

    // Old drivers buggy with optimized ConvertIndexIndirectLineLoop shader.
    // http://anglebug.com/40096699
    ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());

    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    // Start at index 1.
    GLuint firstIndex       = 1;
    const GLubyte indices[] = {0, 7, 6, 9, 8, 0};

    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(mProgram);
    ASSERT_GL_NO_ERROR();

    GLVertexArray vertexArray;
    GLFramebuffer arrayUpdateFbo, elementUpdateFbo;
    GLTexture arrayUpdateTex, elementUpdateTex;
    GLBuffer vertexBuffer;
    GLBuffer indexBuffer;

    preTestUBOAndInitUpdateBuffers(vertexArray, vertexBuffer, indexBuffer, kLoopPositions,
                                   sizeof(kLoopPositions), indices, sizeof(indices), arrayUpdateFbo,
                                   arrayUpdateTex, elementUpdateFbo, elementUpdateTex);

    GLBuffer indirectBuffer;
    initIndirectBuffer(indirectBuffer, firstIndex);

    glEnable(GL_BLEND);
    setVertexAttribs(nullptr);
    glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_BYTE, nullptr);
    ASSERT_GL_NO_ERROR();

    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    setVertexAttribs(kStripPositions);
    glUniform4f(mColorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, kStripIndices);
    ASSERT_GL_NO_ERROR();

    checkPixels();

    glBindFramebuffer(GL_FRAMEBUFFER, arrayUpdateFbo);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    glBindFramebuffer(GL_FRAMEBUFFER, elementUpdateFbo);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}

// Test that uploading data to buffer that's in use then using it for line loop elements works.
TEST_P(LineLoopIndirectTest, UseAsUBOThenUpdateThenUShortIndexIndirectBuffer)
{
    // http://anglebug.com/42264370
    ANGLE_SKIP_TEST_IF(IsVulkan() && IsQualcomm());

    // Old drivers buggy with optimized ConvertIndexIndirectLineLoop shader.
    // http://anglebug.com/40096699
    ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());

    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    // Start at index 1.
    GLuint firstIndex       = 1;
    const GLshort indices[] = {0, 7, 6, 9, 8, 0};

    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(mProgram);
    ASSERT_GL_NO_ERROR();

    GLVertexArray vertexArray;
    GLFramebuffer arrayUpdateFbo, elementUpdateFbo;
    GLTexture arrayUpdateTex, elementUpdateTex;
    GLBuffer vertexBuffer;
    GLBuffer indexBuffer;

    preTestUBOAndInitUpdateBuffers(vertexArray, vertexBuffer, indexBuffer, kLoopPositions,
                                   sizeof(kLoopPositions), indices, sizeof(indices), arrayUpdateFbo,
                                   arrayUpdateTex, elementUpdateFbo, elementUpdateTex);

    GLBuffer indirectBuffer;
    initIndirectBuffer(indirectBuffer, firstIndex);

    glEnable(GL_BLEND);
    setVertexAttribs(nullptr);
    glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_SHORT, nullptr);
    ASSERT_GL_NO_ERROR();

    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    setVertexAttribs(kStripPositions);
    glUniform4f(mColorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, kStripIndices);
    ASSERT_GL_NO_ERROR();

    checkPixels();

    glBindFramebuffer(GL_FRAMEBUFFER, arrayUpdateFbo);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);

    glBindFramebuffer(GL_FRAMEBUFFER, elementUpdateFbo);
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}

// Test that two indirect draws drawing lineloop and sharing same index buffer works.
TEST_P(LineLoopIndirectTest, TwoIndirectDrawsShareIndexBuffer)
{
    // http://anglebug.com/42264370
    ANGLE_SKIP_TEST_IF(IsVulkan() && IsQualcomm());

    // Old drivers buggy with optimized ConvertIndexIndirectLineLoop shader.
    // http://anglebug.com/40096699
    ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());

    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    // Start at index 1.
    GLuint firstIndex        = 1;
    const GLushort indices[] = {0, 7, 6, 9, 8, 0};

    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(mProgram);
    ASSERT_GL_NO_ERROR();

    GLVertexArray vertexArray;
    GLBuffer vertexBuffer;
    GLBuffer indexBuffer;

    initUpdateBuffers(vertexArray, vertexBuffer, indexBuffer, kLoopPositions,
                      sizeof(kLoopPositions), indices, sizeof(indices));

    GLBuffer indirectBuffer;
    initIndirectBuffer(indirectBuffer, firstIndex);

    glEnable(GL_BLEND);
    setVertexAttribs(nullptr);
    glUniform4f(mColorLocation, 0.0f, 0.0f, 1.0f, 1.0f);
    glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_SHORT, nullptr);
    ASSERT_GL_NO_ERROR();
    glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_SHORT, nullptr);
    ASSERT_GL_NO_ERROR();

    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    setVertexAttribs(kStripPositions);
    glUniform4f(mColorLocation, 0.0f, 1.0f, 0.0f, 1.0f);
    glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, kStripIndices);
    ASSERT_GL_NO_ERROR();

    checkPixels();
}

// Test that one indirect line-loop followed by one non-line-loop draw that share the same index
// buffer works.
TEST_P(LineLoopIndirectTest, IndirectAndElementDrawsShareIndexBuffer)
{
    // http://anglebug.com/42264370
    ANGLE_SKIP_TEST_IF(IsVulkan() && IsQualcomm());

    // Old drivers buggy with optimized ConvertIndexIndirectLineLoop shader.
    // http://anglebug.com/40096699
    ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsVulkan());

    // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
    ignoreD3D11SDKLayersWarnings();

    GLuint firstIndex                    = 10;
    static const GLubyte indices[]       = {0, 6, 9, 8, 7, 6, 0, 0, 9, 1, 2, 3, 4, 1, 0};
    static const GLfloat loopPositions[] = {0.0f,  0.0f, 0.5f,  0.0f, 0.0f, 0.5f,  -0.5f,
                                            0.0f,  0.0f, -0.5f, 0.0f, 0.0f, -0.5f, -0.5f,
                                            -0.5f, 0.5f, 0.5f,  0.5f, 0.5f, -0.5f};

    glClear(GL_COLOR_BUFFER_BIT);
    glUseProgram(mProgram);
    ASSERT_GL_NO_ERROR();

    GLVertexArray vertexArray;
    GLBuffer vertexBuffer;
    GLBuffer indexBuffer;

    initUpdateBuffers(vertexArray, vertexBuffer, indexBuffer, loopPositions, sizeof(loopPositions),
                      indices, sizeof(indices));

    GLBuffer indirectBuffer;
    initIndirectBuffer(indirectBuffer, firstIndex);

    glEnable(GL_BLEND);
    setVertexAttribs(nullptr);
    glUniform4f(mColorLocation, 1.0f, 0.0f, 1.0f, 1.0f);

    glViewport(0, 0, getWindowWidth() / 2, getWindowHeight());
    glDrawElementsIndirect(GL_LINE_LOOP, GL_UNSIGNED_BYTE, nullptr);
    ASSERT_GL_NO_ERROR();

    glViewport(getWindowWidth() / 2, 0, getWindowWidth() / 2, getWindowHeight());
    glUniform4f(mColorLocation, 0.0, 1.0, 1.0, 1.0);
    glDrawElements(GL_LINE_STRIP, 5, GL_UNSIGNED_BYTE, reinterpret_cast<const void *>(1));
    ASSERT_GL_NO_ERROR();

    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    // Check pixels.
    std::vector<GLubyte> pixels(getWindowWidth() * getWindowHeight() * 4);
    glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE, &pixels[0]);
    ASSERT_GL_NO_ERROR();

    for (int y = 0; y < getWindowHeight(); y++)
    {
        for (int x = 0; x < getWindowWidth() / 2; x++)
        {
            const GLubyte *pixel = &pixels[0] + ((y * getWindowWidth() + x) * 4);

            EXPECT_TRUE(pixel[0] == pixel[2]) << "Failed at " << x << ", " << y << std::endl;
            EXPECT_TRUE(pixel[1] == 0) << "Failed at " << x << ", " << y << std::endl;
            ASSERT_EQ(pixel[3], 255) << "Failed at " << x << ", " << y << std::endl;
        }
        for (int x = getWindowWidth() / 2; x < getWindowWidth(); x++)
        {
            const GLubyte *pixel = &pixels[0] + ((y * getWindowWidth() + x) * 4);

            EXPECT_TRUE(pixel[0] == 0) << "Failed at " << x << ", " << y << std::endl;
            EXPECT_TRUE(pixel[1] == pixel[2]) << "Failed at " << x << ", " << y << std::endl;
            ASSERT_EQ(pixel[3], 255) << "Failed at " << x << ", " << y << std::endl;
        }
    }
}

ANGLE_INSTANTIATE_TEST_ES2_AND(LineLoopTest, ES2_WEBGPU());
ANGLE_INSTANTIATE_TEST_ES3(LineLoopTestES3);

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(LineLoopPrimitiveRestartTest);
ANGLE_INSTANTIATE_TEST_ES3_AND(
    LineLoopPrimitiveRestartTest,
    ES3_METAL().enable(Feature::ForceBufferGPUStorage),
    ES3_METAL().disable(Feature::HasExplicitMemBarrier).disable(Feature::HasCheapRenderPass));

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(LineLoopIndirectTest);
ANGLE_INSTANTIATE_TEST_ES31(LineLoopIndirectTest);

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(LineLoopPrimitiveRestartXfbTest);
ANGLE_INSTANTIATE_TEST_ES32(LineLoopPrimitiveRestartXfbTest);
