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

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_buffers
#endif

#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
{
  protected:
    void runTestInstanced(std::function<void(void)> definePositionBuffer,
                          std::function<void(void)> defineColorBuffer,
                          std::function<void(void)> draw)
    {
        // http://anglebug.com/42265165: Disable D3D11 SDK Layers warnings checks.
        ignoreD3D11SDKLayersWarnings();

        constexpr char kVS[] = R"(#version 300 es
    precision mediump float;
    in vec2 position;
    in vec2 colorIn;
    out vec2 color;
    void main()
    {
        gl_Position = vec4(position, 0, 1);
        if ((gl_InstanceID / 2) % 2 == 1)
        {
            gl_Position.y += 1.0;
        }
        if (gl_InstanceID % 2 == 1)
        {
            gl_Position.x += 1.0;
        }
        color = colorIn;
    })";

        constexpr char kFS[] = R"(#version 300 es
    precision mediump float;
    in vec2 color;
    out vec4 colorOut;
    void main()
    {
        colorOut = vec4(color, 0, 1);
    })";

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

        const GLint posLoc = glGetAttribLocation(program, "position");
        const GLint colLoc = glGetAttribLocation(program, "colorIn");

        // Draw 4 squares.  With a divisor of 2 on color, 2 of them will be one color, two the
        // other.

        GLBuffer position;
        glBindBuffer(GL_ARRAY_BUFFER, position);
        definePositionBuffer();
        glEnableVertexAttribArray(posLoc);
        glVertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);

        GLBuffer color;
        glBindBuffer(GL_ARRAY_BUFFER, color);
        defineColorBuffer();
        glEnableVertexAttribArray(colLoc);
        glVertexAttribPointer(colLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
        glVertexAttribDivisor(colLoc, 2);

        glClear(GL_COLOR_BUFFER_BIT);
        draw();

        // Verify pixels.  The result looks like the following:
        //
        //      +-----------------------+
        //      |                       |
        //      |   +----+     +----+   |
        //      |   |    |     |    |   |  <-- two red squares
        //      |   |    |     |    |   |
        //      |   +----+     +----+   |
        //      |                       |
        //      |                       |
        //      |   +----+     +----+   |
        //      |   |    |     |    |   |  <-- two green squares
        //      |   |    |     |    |   |
        //      |   +----+     +----+   |
        //      |                       |
        //      +-----------------------+
        //            |
        //            V
        //  Black inside and outside the squares
        //
        const int w = getWindowWidth();
        const int h = getWindowHeight();
        // Don't check too close to the lines to account for precision issues.  This is the margin
        // from the middle of the lines.
        const int m = 2;
        const GLColor green(51, 153, 0, 255);

        // Left of squares
        EXPECT_PIXEL_RECT_EQ(0, 0, w / 8 - m, h, GLColor::black);
        // Between squares
        EXPECT_PIXEL_RECT_EQ(w / 2 - w / 8 + m, 0, w / 4 - m * 2, h, GLColor::black);
        // Right of squares
        EXPECT_PIXEL_RECT_EQ(w - w / 8 + m, 0, w / 8 - m, h, GLColor::black);

        // Above squares
        EXPECT_PIXEL_RECT_EQ(0, 0, w, h / 8 - m, GLColor::black);
        // Between squares
        EXPECT_PIXEL_RECT_EQ(0, h / 2 - h / 8 + m, w, h / 4 - m * 2, GLColor::black);
        // Below squares
        EXPECT_PIXEL_RECT_EQ(0, h - h / 8 + m, w, h / 8 - m, GLColor::black);

        // Check the lines of the squares, leaving a margin for precision errors.
        std::vector<GLColor> result(w * h);
        glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, result.data());

        auto checkHorizontalLine = [&result, w](int x, int y, int width, GLColor expect) {
            for (int c = 0; c < width; ++c)
            {
                if (result[y * w + x + c] != expect)
                {
                    return false;
                }
            }
            return true;
        };
        auto checkVerticalLine = [&result, w](int x, int y, int height, GLColor expect) {
            for (int r = 0; r < height; ++r)
            {
                if (result[(y + r) * w + x] != expect)
                {
                    return false;
                }
            }
            return true;
        };

        for (int x : {w / 8, w / 2 - w / 8, w / 2 + w / 8, w - w / 8})
        {
            const int y      = h / 8 + m;
            const int length = h / 4 - m * 2;
            // The line may not exactly land on |x|, check around it too, one of them should be
            // non-black.
            EXPECT_TRUE(checkVerticalLine(x - 1, y, length, GLColor::red) ^
                        checkVerticalLine(x, y, length, GLColor::red) ^
                        checkVerticalLine(x + 1, y, length, GLColor::red));
            EXPECT_TRUE(checkVerticalLine(x - 1, h / 2 + y, length, green) ^
                        checkVerticalLine(x, h / 2 + y, length, green) ^
                        checkVerticalLine(x + 1, h / 2 + y, length, green));
        }
        for (int y : {h / 8, h / 2 - h / 8, h / 2 + h / 8, h - h / 8})
        {
            const int x          = w / 8 + m;
            const int length     = w / 4 - m * 2;
            const GLColor expect = y < h / 2 ? GLColor::red : green;
            EXPECT_PIXEL_RECT_EQ(x, y, length, 1, expect);
            EXPECT_PIXEL_RECT_EQ(w / 2 + x, y, length, 1, expect);

            EXPECT_TRUE(checkHorizontalLine(x, y - 1, length, expect) ^
                        checkHorizontalLine(x, y, length, expect) ^
                        checkHorizontalLine(x, y + 1, length, expect));
            EXPECT_TRUE(checkHorizontalLine(w / 2 + x, y - 1, length, expect) ^
                        checkHorizontalLine(w / 2 + x, y, length, expect) ^
                        checkHorizontalLine(w / 2 + x, y + 1, length, expect));
        }

        ASSERT_GL_NO_ERROR();
    }
};

// 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 glDrawArraysInstanced with a line loop and a non-zero divisor.
TEST_P(LineLoopTestES3, LineLoopDrawArraysInstanced)
{
    const int w        = getWindowWidth();
    const int h        = getWindowHeight();
    const float left   = static_cast<float>(w / 8) / (w - 1) * 2.0 - 1.0;
    const float right  = static_cast<float>(w / 2 - w / 8) / (w - 1) * 2.0 - 1.0;
    const float top    = static_cast<float>(h / 8) / (h - 1) * 2.0 - 1.0;
    const float bottom = static_cast<float>(h / 2 - h / 8) / (h - 1) * 2.0 - 1.0;

    const GLfloat kPositions[] = {
        // Top left.  Instances 1 and 3 shift this square to the right.  Instances 2 and 3 shift it
        // down.
        left, top, left, bottom, right, bottom, right, top,
    };
    constexpr GLfloat kColors[] = {
        // Top
        1.0f,
        0.0f,
        // Bottom
        0.2f,
        0.6f,
    };
    runTestInstanced(
        [&kPositions]() {
            glBufferData(GL_ARRAY_BUFFER, sizeof(kPositions), kPositions, GL_STATIC_DRAW);
        },
        [&kColors]() { glBufferData(GL_ARRAY_BUFFER, sizeof(kColors), kColors, GL_STATIC_DRAW); },
        []() { glDrawArraysInstanced(GL_LINE_LOOP, 0, 4, 4); });
}

// Test glDrawArraysInstancedBaseInstance with a line loop and a non-zero divisor.
TEST_P(LineLoopTestES3, LineLoopDrawArraysInstancedBaseInstance)
{
    const bool hasEXT   = IsGLExtensionEnabled("GL_EXT_base_instance");
    const bool hasANGLE = IsGLExtensionEnabled("GL_ANGLE_base_vertex_base_instance");
    ANGLE_SKIP_TEST_IF(!hasEXT && !hasANGLE);

    const int w        = getWindowWidth();
    const int h        = getWindowHeight();
    const float left   = static_cast<float>(w / 8) / (w - 1) * 2.0 - 1.0;
    const float right  = static_cast<float>(w / 2 - w / 8) / (w - 1) * 2.0 - 1.0;
    const float top    = static_cast<float>(h / 8) / (h - 1) * 2.0 - 1.0;
    const float bottom = static_cast<float>(h / 2 - h / 8) / (h - 1) * 2.0 - 1.0;

    const GLfloat kPositions[] = {
        // Top left.  Instances 1 and 3 shift this square to the right.  Instances 2 and 3 shift it
        // down.
        left, top, left, bottom, right, bottom, right, top,
    };
    constexpr GLfloat kColors[] = {
        // 5 unused attributes, skipped by base instance
        // clang-format off
        0.1f, 0.2f,
        0.3f, 0.4f,
        0.5f, 0.6f,
        0.7f, 0.8f,
        0.9f, 0.95f,
        // Top
        1.0f, 0.0f,
        // Bottom
        0.2f, 0.6f,
        // clang-format on
    };
    runTestInstanced(
        [&kPositions]() {
            glBufferData(GL_ARRAY_BUFFER, sizeof(kPositions), kPositions, GL_STATIC_DRAW);
        },
        [&kColors]() { glBufferData(GL_ARRAY_BUFFER, sizeof(kColors), kColors, GL_STATIC_DRAW); },
        [hasEXT]() {
            if (hasEXT)
            {
                glDrawArraysInstancedBaseInstanceEXT(GL_LINE_LOOP, 0, 4, 4, 5);
            }
            else
            {
                glDrawArraysInstancedBaseInstanceANGLE(GL_LINE_LOOP, 0, 4, 4, 5);
            }
        });
}

// Test glDrawElementsInstancedBaseVertexBaseInstance with a line loop and a non-zero divisor.
TEST_P(LineLoopTestES3, LineLoopDrawElementsInstancedBaseVertexBaseInstance)
{
    const bool hasEXT   = IsGLExtensionEnabled("GL_EXT_base_instance");
    const bool hasANGLE = IsGLExtensionEnabled("GL_ANGLE_base_vertex_base_instance");
    ANGLE_SKIP_TEST_IF(!hasEXT && !hasANGLE);

    const int w        = getWindowWidth();
    const int h        = getWindowHeight();
    const float left   = static_cast<float>(w / 8) / (w - 1) * 2.0 - 1.0;
    const float right  = static_cast<float>(w / 2 - w / 8) / (w - 1) * 2.0 - 1.0;
    const float top    = static_cast<float>(h / 8) / (h - 1) * 2.0 - 1.0;
    const float bottom = static_cast<float>(h / 2 - h / 8) / (h - 1) * 2.0 - 1.0;

    const GLfloat kPositions[] = {
        // 5 unused vertices, skipped by base vertex
        // clang-format off
        0.1f, 0.4f,
        0.3f, 0.6f,
        0.5f, 0.8f,
        0.7f, 0.6f,
        0.9f, 0.4f,
        // Top left.  Instances 1 and 3 shift this square to the right.  Instances 2 and 3 shift it
        // down.  The 2nd and 3rd vertices are swapped, but are reordered by the index buffer.
        left, top, right, bottom, left, bottom, right, top,
        // clang-format on
    };
    constexpr GLfloat kColors[] = {
        // 9 unused attributes, skipped by base instance.
        // clang-format off
        0.1f, 0.2f,
        0.3f, 0.4f,
        0.5f, 0.6f,
        0.7f, 0.8f,
        0.9f, 0.95f,
        0.85f, 0.75f,
        0.65f, 0.55f,
        0.45f, 0.35f,
        0.25f, 0.15f,
        // Top
        1.0f, 0.0f,
        // Bottom
        0.2f, 0.6f,
        // clang-format on
    };
    constexpr GLint kIndices[] = {
        // The square
        2,
        1,
        3,
        0,
    };

    GLBuffer index;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(kIndices), kIndices, GL_STATIC_DRAW);

    runTestInstanced(
        [&kPositions]() {
            glBufferData(GL_ARRAY_BUFFER, sizeof(kPositions), kPositions, GL_STATIC_DRAW);
        },
        [&kColors]() { glBufferData(GL_ARRAY_BUFFER, sizeof(kColors), kColors, GL_STATIC_DRAW); },
        [hasEXT]() {
            if (hasEXT)
            {
                glDrawElementsInstancedBaseVertexBaseInstanceEXT(GL_LINE_LOOP, 4, GL_UNSIGNED_INT,
                                                                 nullptr, 4, 5, 9);
            }
            else
            {
                glDrawElementsInstancedBaseVertexBaseInstanceANGLE(GL_LINE_LOOP, 4, GL_UNSIGNED_INT,
                                                                   nullptr, 4, 5, 9);
            }
        });
}

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

// Test an edge case in the D3D11 backend where a large index array of GL_UNSIGNED_BYTE
// drawn as a GL_LINE_LOOP is widened to 32-bits internally and overflows.
// Disabled because it slow and triggers an internal error.
TEST_P(LineLoopTestES3, DISABLED_LargeLoopUnsignedByte)
{
    size_t count = 805306368;

    glLinkProgram(mProgram);
    glUseProgram(mProgram);
    ASSERT_GL_NO_ERROR();

    GLBuffer ebo;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, count, nullptr, GL_STATIC_DRAW);
    ASSERT_GL_NO_ERROR();

    glDrawElements(GL_LINE_LOOP, count, GL_UNSIGNED_BYTE, 0);
    EXPECT_GL_ERROR(GL_OUT_OF_MEMORY);
}

// Test an edge case in the D3D11 backend where a large index array of GL_UNSIGNED_BYTE
// drawn as a GL_TRIANGLE_FAN is widened to 32-bits internally and overflows.
// Disabled because it slow and triggers an internal error.
TEST_P(LineLoopTestES3, DISABLED_LargeFanUnsignedByte)
{
    size_t count = 805306368;

    glLinkProgram(mProgram);
    glUseProgram(mProgram);
    ASSERT_GL_NO_ERROR();

    GLBuffer ebo;
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, count, nullptr, GL_STATIC_DRAW);
    ASSERT_GL_NO_ERROR();

    glDrawElements(GL_TRIANGLE_FAN, count, GL_UNSIGNED_BYTE, 0);
    EXPECT_GL_ERROR(GL_OUT_OF_MEMORY);
}

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

// Test that two indirect draws using glDrawArraysIndirect with GL_LINE_LOOP mode
// and different vertex ranges work correctly.
TEST_P(LineLoopIndirectTest, TwoIndirectDrawsInDifferentIndirectBuffer)
{
    // EXT_geometry_shader allows transform feedback to work with draw indirect.
    // Otherwise, INVALID_OPERATION will be generated.
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));

    GLVertexArray vertexArray;
    GLBuffer vertexBuffer, xfbBuffer, indirectBuffer[2];
    const std::vector<GLfloat> vertices = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
    const std::vector<GLfloat> expected = {
        2.0, 1.0, 4.0,  4.0,  4.0,  4.0,  6.0,  9.0,  6.0,  9.0,  8.0,  16.0, 8.0,  16.0,
        2.0, 1.0, 10.0, 25.0, 12.0, 36.0, 12.0, 36.0, 14.0, 49.0, 14.0, 49.0, 10.0, 25.0};
    constexpr char kVS[] = R"(#version 300 es
in float in_val;
out float out_val;
out float out_val2;

void main()
{
    out_val = in_val * 2.0;
    out_val2 = in_val * in_val;
    gl_Position = vec4(in_val);
})";

    constexpr char kFS[] = R"(#version 300 es
precision highp float;
in float out_val;
in float out_val2;
out vec4 fragColor;
void main()
{
    fragColor = vec4(1.0);
})";

    ANGLE_GL_PROGRAM(program, kVS, kFS);

    std::vector<const char *> varyings = {"out_val", "out_val2"};
    glTransformFeedbackVaryings(program, static_cast<GLsizei>(varyings.size()), varyings.data(),
                                GL_INTERLEAVED_ATTRIBS);
    glLinkProgram(program);
    glUseProgram(program);
    ASSERT_GL_NO_ERROR();

    glBindVertexArray(vertexArray);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.data(),
                 GL_STATIC_DRAW);
    ASSERT_GL_NO_ERROR();

    GLuint pos = glGetAttribLocation(program, "in_val");
    glEnableVertexAttribArray(pos);
    glVertexAttribPointer(pos, 1, GL_FLOAT, GL_FALSE, 0, 0);
    ASSERT_GL_NO_ERROR();

    std::vector<GLfloat> initialData(expected.size(), 0.0);
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfbBuffer);
    glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, expected.size() * sizeof(GLfloat),
                 initialData.data(), GL_STATIC_READ);
    glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, xfbBuffer);
    ASSERT_GL_NO_ERROR();

    glBeginTransformFeedback(GL_LINES);
    ASSERT_GL_NO_ERROR();

    DrawCommand indirectDrawArgs1 = {};
    indirectDrawArgs1.count       = 4;
    indirectDrawArgs1.firstIndex  = 0;
    indirectDrawArgs1.primCount   = 1;
    DrawCommand indirectDrawArgs2 = {};
    indirectDrawArgs2.count       = 3;
    indirectDrawArgs2.firstIndex  = 4;
    indirectDrawArgs2.primCount   = 1;

    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuffer[0]);
    glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand), &indirectDrawArgs1, GL_STATIC_DRAW);
    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuffer[1]);
    glBufferData(GL_DRAW_INDIRECT_BUFFER, sizeof(DrawCommand), &indirectDrawArgs2, GL_STATIC_DRAW);
    ASSERT_GL_NO_ERROR();

    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuffer[0]);
    glDrawArraysIndirect(GL_LINE_LOOP, nullptr);
    ASSERT_GL_NO_ERROR();
    glBindBuffer(GL_DRAW_INDIRECT_BUFFER, indirectBuffer[1]);
    glDrawArraysIndirect(GL_LINE_LOOP, nullptr);
    ASSERT_GL_NO_ERROR();

    glEndTransformFeedback();
    glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, xfbBuffer);
    GLfloat *mapped = (GLfloat *)glMapBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, 0,
                                                  expected.size() * sizeof(float), GL_MAP_READ_BIT);
    ASSERT_GL_NO_ERROR();
    for (size_t i = 0; i < expected.size(); i++)
    {
        EXPECT_EQ(mapped[i], expected[i]);
    }
}
ANGLE_INSTANTIATE_TEST_ES2_AND(LineLoopTest,
                               ES2_OPENGLES().enable(Feature::ForcePassthroughShaders));
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),
    ES3_WEBGPU());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(LineLoopIndirectTest);
ANGLE_INSTANTIATE_TEST_ES31(LineLoopIndirectTest);

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(LineLoopPrimitiveRestartXfbTest);
ANGLE_INSTANTIATE_TEST_ES32(LineLoopPrimitiveRestartXfbTest);
