//
// Copyright 2018 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.
//
// MulithreadingTest.cpp : Tests of multithreaded rendering
//

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_buffers
#endif

#include "test_utils/ANGLETest.h"
#include "test_utils/MultiThreadSteps.h"
#include "test_utils/gl_raii.h"
#include "util/EGLWindow.h"
#include "util/test_utils.h"

#include <atomic>
#include <mutex>
#include <thread>

namespace angle
{

class MultithreadingTest : public ANGLETest<>
{
  public:
    static constexpr uint32_t kSize = 512;

  protected:
    MultithreadingTest()
    {
        setWindowWidth(kSize);
        setWindowHeight(kSize);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
        setPbuffer(true);
    }

    bool hasFenceSyncExtension() const
    {
        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_fence_sync");
    }
    bool hasWaitSyncExtension() const
    {
        return hasFenceSyncExtension() &&
               IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(), "EGL_KHR_wait_sync");
    }
    bool hasGLSyncExtension() const { return IsGLExtensionEnabled("GL_OES_EGL_sync"); }

    EGLContext createMultithreadedContext(EGLWindow *window, EGLContext shareCtx)
    {
        EGLint attribs[] = {EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE, mVirtualizationGroup++,
                            EGL_NONE};
        if (!IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
                                          "EGL_ANGLE_context_virtualization"))
        {
            attribs[0] = EGL_NONE;
        }

        return window->createContext(shareCtx, attribs);
    }

    void runMultithreadedGLTest(
        std::function<void(EGLSurface surface, size_t threadIndex)> testBody,
        size_t threadCount)
    {
        std::mutex mutex;

        EGLWindow *window = getEGLWindow();
        EGLDisplay dpy    = window->getDisplay();
        EGLConfig config  = window->getConfig();

        constexpr EGLint kPBufferSize = 256;

        std::vector<std::thread> threads(threadCount);
        for (size_t threadIdx = 0; threadIdx < threadCount; threadIdx++)
        {
            threads[threadIdx] = std::thread([&, threadIdx]() {
                EGLSurface surface = EGL_NO_SURFACE;
                EGLContext ctx     = EGL_NO_CONTEXT;

                {
                    std::lock_guard<decltype(mutex)> lock(mutex);

                    // Initialize the pbuffer and context
                    EGLint pbufferAttributes[] = {
                        EGL_WIDTH, kPBufferSize, EGL_HEIGHT, kPBufferSize, EGL_NONE, EGL_NONE,
                    };
                    surface = eglCreatePbufferSurface(dpy, config, pbufferAttributes);
                    EXPECT_EGL_SUCCESS();

                    ctx = createMultithreadedContext(window, EGL_NO_CONTEXT);
                    EXPECT_NE(EGL_NO_CONTEXT, ctx);

                    EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, ctx));
                    EXPECT_EGL_SUCCESS();
                }

                testBody(surface, threadIdx);

                {
                    std::lock_guard<decltype(mutex)> lock(mutex);

                    // Clean up
                    EXPECT_EGL_TRUE(
                        eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
                    EXPECT_EGL_SUCCESS();

                    eglDestroySurface(dpy, surface);
                    eglDestroyContext(dpy, ctx);
                }
            });
        }

        for (std::thread &thread : threads)
        {
            thread.join();
        }
    }

    std::atomic<EGLint> mVirtualizationGroup;
};

class MultithreadingTestES3 : public MultithreadingTest
{
  public:
    void textureThreadFunction(bool useDraw);
    void mainThreadDraw(bool useDraw);

  protected:
    MultithreadingTestES3()
        : mTexture2D(0), mExitThread(false), mMainThreadSyncObj(NULL), mSecondThreadSyncObj(NULL)
    {
        setWindowWidth(kSize);
        setWindowHeight(kSize);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    GLuint create2DTexture()
    {
        GLuint texture2D;
        glGenTextures(1, &texture2D);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture2D);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);
        EXPECT_GL_NO_ERROR();
        return texture2D;
    }

    void testSetUp() override { mTexture2D = create2DTexture(); }

    void testTearDown() override
    {
        if (mTexture2D)
        {
            glDeleteTextures(1, &mTexture2D);
        }
    }

    enum class FenceTest
    {
        ClientWait,
        ServerWait,
        GetStatus,
    };
    enum class FlushMethod
    {
        Flush,
        Finish,
    };
    void testFenceWithOpenRenderPass(FenceTest test, FlushMethod flushMethod);

    enum class DrawOrder
    {
        Before,
        After,
    };
    void testFramebufferFetch(DrawOrder drawOrder);

    std::mutex mMutex;
    GLuint mTexture2D;
    std::atomic<bool> mExitThread;
    std::atomic<bool> mDrawGreen;  // Toggle drawing green or red
    std::atomic<GLsync> mMainThreadSyncObj;
    std::atomic<GLsync> mSecondThreadSyncObj;
};

// Test that it's possible to make one context current on different threads
TEST_P(MultithreadingTest, MakeCurrentSingleContext)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    std::mutex mutex;

    EGLWindow *window  = getEGLWindow();
    EGLDisplay dpy     = window->getDisplay();
    EGLContext ctx     = window->getContext();
    EGLSurface surface = window->getSurface();

    EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    EXPECT_EGL_SUCCESS();

    constexpr size_t kThreadCount = 16;
    std::array<std::thread, kThreadCount> threads;
    for (std::thread &thread : threads)
    {
        thread = std::thread([&]() {
            std::lock_guard<decltype(mutex)> lock(mutex);

            EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, ctx));
            EXPECT_EGL_SUCCESS();

            EXPECT_EGL_TRUE(eglSwapBuffers(dpy, surface));
            EXPECT_EGL_SUCCESS();

            EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
            EXPECT_EGL_SUCCESS();
        });
    }

    for (std::thread &thread : threads)
    {
        thread.join();
    }

    EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, ctx));
    EXPECT_EGL_SUCCESS();
}

// Test that multiple threads can clear and readback pixels successfully at the same time
TEST_P(MultithreadingTest, MultiContextClear)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    auto testBody = [](EGLSurface surface, size_t thread) {
        constexpr size_t kIterationsPerThread = 32;
        for (size_t iteration = 0; iteration < kIterationsPerThread; iteration++)
        {
            // Base the clear color on the thread and iteration indexes so every clear color is
            // unique
            const GLColor color(static_cast<GLubyte>(thread % 255),
                                static_cast<GLubyte>(iteration % 255), 0, 255);
            const angle::Vector4 floatColor = color.toNormalizedVector();

            glClearColor(floatColor[0], floatColor[1], floatColor[2], floatColor[3]);
            EXPECT_GL_NO_ERROR();

            glClear(GL_COLOR_BUFFER_BIT);
            EXPECT_GL_NO_ERROR();

            EXPECT_PIXEL_COLOR_EQ(0, 0, color);
        }
    };
    runMultithreadedGLTest(testBody, 72);
}

// Verify that threads can interleave eglDestroyContext and draw calls without
// any crashes.
TEST_P(MultithreadingTest, MultiContextDeleteDraw)
{
    // Skip this test on non-D3D11 backends, as it has the potential to time-out
    // and this test was originally intended to catch a crash on the D3D11 backend.
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!IsD3D11());

    EGLWindow *window = getEGLWindow();
    EGLDisplay dpy    = window->getDisplay();
    EGLConfig config  = window->getConfig();

    std::thread t1 = std::thread([&]() {
        // 5000 is chosen here as it reliably reproduces the former crash.
        for (int i = 0; i < 5000; i++)
        {
            EGLContext ctx1 = createMultithreadedContext(window, EGL_NO_CONTEXT);
            EGLContext ctx2 = createMultithreadedContext(window, EGL_NO_CONTEXT);

            EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx2));
            EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx1));

            EXPECT_EGL_TRUE(eglDestroyContext(dpy, ctx2));
            EXPECT_EGL_TRUE(eglDestroyContext(dpy, ctx1));

            // Clean up
            EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        }
    });

    std::thread t2 = std::thread([&]() {
        EGLint pbufferAttributes[] = {
            EGL_WIDTH, 256, EGL_HEIGHT, 256, EGL_NONE, EGL_NONE,
        };

        EGLSurface surface = eglCreatePbufferSurface(dpy, config, pbufferAttributes);
        EXPECT_EGL_SUCCESS();

        auto ctx = createMultithreadedContext(window, EGL_NO_CONTEXT);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, ctx));

        constexpr size_t kIterationsPerThread = 512;
        constexpr size_t kDrawsPerIteration   = 512;

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
        glUseProgram(program);

        GLint colorLocation = glGetUniformLocation(program, essl1_shaders::ColorUniform());

        auto quadVertices = GetQuadVertices();

        GLBuffer vertexBuffer;
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 6, quadVertices.data(), GL_STATIC_DRAW);

        GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
        glEnableVertexAttribArray(positionLocation);
        glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
        for (size_t iteration = 0; iteration < kIterationsPerThread; iteration++)
        {
            const GLColor color(static_cast<GLubyte>(15151 % 255),
                                static_cast<GLubyte>(iteration % 255), 0, 255);
            const angle::Vector4 floatColor = color.toNormalizedVector();
            glUniform4fv(colorLocation, 1, floatColor.data());
            for (size_t draw = 0; draw < kDrawsPerIteration; draw++)
            {
                EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, ctx));
                glDrawArrays(GL_TRIANGLES, 0, 6);
            }
        }

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    });

    t1.join();
    t2.join();
}

// Test that multiple threads can draw and readback pixels successfully at the same time
TEST_P(MultithreadingTest, MultiContextDraw)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    ANGLE_SKIP_TEST_IF(isSwiftshader());

    auto testBody = [](EGLSurface surface, size_t thread) {
        constexpr size_t kIterationsPerThread = 32;
        constexpr size_t kDrawsPerIteration   = 500;

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
        glUseProgram(program);

        GLint colorLocation = glGetUniformLocation(program, essl1_shaders::ColorUniform());

        auto quadVertices = GetQuadVertices();

        GLBuffer vertexBuffer;
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 6, quadVertices.data(), GL_STATIC_DRAW);

        GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
        glEnableVertexAttribArray(positionLocation);
        glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);

        for (size_t iteration = 0; iteration < kIterationsPerThread; iteration++)
        {
            // Base the clear color on the thread and iteration indexes so every clear color is
            // unique
            const GLColor color(static_cast<GLubyte>(thread % 255),
                                static_cast<GLubyte>(iteration % 255), 0, 255);
            const angle::Vector4 floatColor = color.toNormalizedVector();
            glUniform4fv(colorLocation, 1, floatColor.data());

            for (size_t draw = 0; draw < kDrawsPerIteration; draw++)
            {
                glDrawArrays(GL_TRIANGLES, 0, 6);
            }

            EXPECT_PIXEL_COLOR_EQ(0, 0, color);
        }
    };
    runMultithreadedGLTest(testBody, 4);
}

// Test that multiple threads can draw and read back pixels correctly.
// Using eglSwapBuffers stresses race conditions around use of QueueSerials.
TEST_P(MultithreadingTest, MultiContextDrawWithSwapBuffers)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    // http://anglebug.com/42263666
    ANGLE_SKIP_TEST_IF(IsAndroid() && IsOpenGLES());

    EGLWindow *window = getEGLWindow();
    EGLDisplay dpy    = window->getDisplay();

    auto testBody = [dpy](EGLSurface surface, size_t thread) {
        constexpr size_t kIterationsPerThread = 100;
        constexpr size_t kDrawsPerIteration   = 10;

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
        glUseProgram(program);

        GLint colorLocation = glGetUniformLocation(program, essl1_shaders::ColorUniform());

        auto quadVertices = GetQuadVertices();

        GLBuffer vertexBuffer;
        glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
        glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 6, quadVertices.data(), GL_STATIC_DRAW);

        GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
        glEnableVertexAttribArray(positionLocation);
        glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);

        for (size_t iteration = 0; iteration < kIterationsPerThread; iteration++)
        {
            // Base the clear color on the thread and iteration indexes so every clear color is
            // unique
            const GLColor color(static_cast<GLubyte>(thread % 255),
                                static_cast<GLubyte>(iteration % 255), 0, 255);
            const angle::Vector4 floatColor = color.toNormalizedVector();
            glUniform4fv(colorLocation, 1, floatColor.data());

            for (size_t draw = 0; draw < kDrawsPerIteration; draw++)
            {
                glDrawArrays(GL_TRIANGLES, 0, 6);
            }

            EXPECT_EGL_TRUE(eglSwapBuffers(dpy, surface));
            EXPECT_EGL_SUCCESS();

            EXPECT_PIXEL_COLOR_EQ(0, 0, color);
        }
    };
    runMultithreadedGLTest(testBody, 32);
}

// Test that ANGLE handles multiple threads creating and destroying resources (vertex buffer in this
// case).
TEST_P(MultithreadingTest, MultiContextCreateAndDeleteResources)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    EGLWindow *window = getEGLWindow();
    EGLDisplay dpy    = window->getDisplay();

    auto testBody = [dpy](EGLSurface surface, size_t thread) {
        constexpr size_t kIterationsPerThread = 32;
        constexpr size_t kDrawsPerIteration   = 1;

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
        glUseProgram(program);

        GLint colorLocation = glGetUniformLocation(program, essl1_shaders::ColorUniform());

        auto quadVertices = GetQuadVertices();

        for (size_t iteration = 0; iteration < kIterationsPerThread; iteration++)
        {
            GLBuffer vertexBuffer;
            glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
            glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 6, quadVertices.data(),
                         GL_STATIC_DRAW);

            GLint positionLocation = glGetAttribLocation(program, essl1_shaders::PositionAttrib());
            glEnableVertexAttribArray(positionLocation);
            glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);

            // Base the clear color on the thread and iteration indexes so every clear color is
            // unique
            const GLColor color(static_cast<GLubyte>(thread % 255),
                                static_cast<GLubyte>(iteration % 255), 0, 255);
            const angle::Vector4 floatColor = color.toNormalizedVector();
            glUniform4fv(colorLocation, 1, floatColor.data());

            for (size_t draw = 0; draw < kDrawsPerIteration; draw++)
            {
                glDrawArrays(GL_TRIANGLES, 0, 6);
            }

            EXPECT_EGL_TRUE(eglSwapBuffers(dpy, surface));
            EXPECT_EGL_SUCCESS();

            EXPECT_PIXEL_COLOR_EQ(0, 0, color);
        }
        glFinish();
    };
    runMultithreadedGLTest(testBody, 32);
}

// Test that changing sampler parameters of textures in unrelated share groups is thread-safe.
// Regression test for a bug in the Vulkan backend where the VkSampler cache was not thread-safe.
TEST_P(MultithreadingTestES3, MultiContextTextureSampleParameters)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    constexpr size_t kThreadCount = 16;
    std::atomic<uint32_t> barrier(0);

    auto testBody = [this, &barrier](EGLSurface surface, size_t thread) {
        constexpr size_t kIterationsPerThread = 32;

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
        glUseProgram(program);
        glUseProgram(program);
        GLint textureUniformLocation =
            glGetUniformLocation(program, angle::essl1_shaders::Texture2DUniform());
        ASSERT_NE(textureUniformLocation, -1);
        glUniform1i(textureUniformLocation, 0);
        glActiveTexture(GL_TEXTURE0);

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

        barrier++;
        while (barrier < kThreadCount)
        {
        }

        for (size_t iteration = 0; iteration < kIterationsPerThread; iteration++)
        {
            // Change the sampling parameters of the texture.
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
                            iteration % 2 == 0 ? GL_LINEAR : GL_NEAREST);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
                            iteration % 3 == 0 ? GL_LINEAR : GL_NEAREST);

            // Make sure the texture is synced.
            drawQuad(program, essl1_shaders::PositionAttrib(), 0);
            EXPECT_GL_NO_ERROR();
        }
        glFinish();
    };

    runMultithreadedGLTest(testBody, 16);
}

// Test that multiple threads can create contexts at the same time.
TEST_P(MultithreadingTest, MultiCreateContext)
{
    // Supported by CGL, GLX, and WGL (https://anglebug.com/42263324)
    // Not supported on Ozone (https://crbug.com/1103009)
    ANGLE_SKIP_TEST_IF(!(IsWindows() || IsLinux() || IsMac()) || IsOzone());

    EGLWindow *window  = getEGLWindow();
    EGLDisplay dpy     = window->getDisplay();
    EGLContext ctx     = window->getContext();
    EGLSurface surface = window->getSurface();

    // Un-makeCurrent the test window's context
    EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    EXPECT_EGL_SUCCESS();

    constexpr size_t kThreadCount = 16;
    std::atomic<uint32_t> barrier(0);
    std::vector<std::thread> threads(kThreadCount);
    std::vector<EGLContext> contexts(kThreadCount);
    for (size_t threadIdx = 0; threadIdx < kThreadCount; threadIdx++)
    {
        threads[threadIdx] = std::thread([&, threadIdx]() {
            contexts[threadIdx] = EGL_NO_CONTEXT;
            {
                contexts[threadIdx] = createMultithreadedContext(window, EGL_NO_CONTEXT);
                EXPECT_NE(EGL_NO_CONTEXT, contexts[threadIdx]);

                barrier++;
            }

            while (barrier < kThreadCount)
            {
            }

            {
                EXPECT_TRUE(eglDestroyContext(dpy, contexts[threadIdx]));
            }
        });
    }

    for (std::thread &thread : threads)
    {
        thread.join();
    }

    // Re-make current the test window's context for teardown.
    EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, ctx));
    EXPECT_EGL_SUCCESS();
}

// Create multiple shared context and draw with shared vertex buffer simutanously
TEST_P(MultithreadingTest, CreateMultiSharedContextAndDraw)
{
    // Supported by CGL, GLX, and WGL (https://anglebug.com/42263324)
    // Not supported on Ozone (https://crbug.com/1103009)
    ANGLE_SKIP_TEST_IF(!(IsWindows() || IsLinux() || IsMac()) || IsOzone());
    EGLWindow *window             = getEGLWindow();
    EGLDisplay dpy                = window->getDisplay();
    EGLConfig config              = window->getConfig();
    constexpr EGLint kPBufferSize = 256;

    // Initialize the pbuffer and context
    EGLint pbufferAttributes[] = {
        EGL_WIDTH, kPBufferSize, EGL_HEIGHT, kPBufferSize, EGL_NONE, EGL_NONE,
    };
    EGLSurface sharedSurface = eglCreatePbufferSurface(dpy, config, pbufferAttributes);
    EXPECT_EGL_SUCCESS();
    EGLContext sharedCtx = createMultithreadedContext(window, EGL_NO_CONTEXT);
    EXPECT_NE(EGL_NO_CONTEXT, sharedCtx);
    EXPECT_EGL_TRUE(eglMakeCurrent(dpy, sharedSurface, sharedSurface, sharedCtx));
    EXPECT_EGL_SUCCESS();

    // Create a shared vertextBuffer
    auto quadVertices = GetQuadVertices();
    GLBuffer sharedVertexBuffer;
    glBindBuffer(GL_ARRAY_BUFFER, sharedVertexBuffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 3 * 6, quadVertices.data(), GL_STATIC_DRAW);
    ASSERT_GL_NO_ERROR();

    // Now draw with the buffer and verify
    {
        ANGLE_GL_PROGRAM(sharedProgram, essl1_shaders::vs::Simple(),
                         essl1_shaders::fs::UniformColor());
        glUseProgram(sharedProgram);
        GLint colorLocation = glGetUniformLocation(sharedProgram, essl1_shaders::ColorUniform());
        GLint positionLocation =
            glGetAttribLocation(sharedProgram, essl1_shaders::PositionAttrib());
        glEnableVertexAttribArray(positionLocation);
        glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);
        const GLColor color(0, 0, 0, 255);
        const angle::Vector4 floatColor = color.toNormalizedVector();
        glUniform4fv(colorLocation, 1, floatColor.data());
        glDrawArrays(GL_TRIANGLES, 0, 6);
        EXPECT_PIXEL_COLOR_EQ(0, 0, color);
    }

    // Create shared context in their own threads and draw with the shared vertex buffer at the same
    // time.
    size_t threadCount                    = 16;
    constexpr size_t kIterationsPerThread = 3;
    constexpr size_t kDrawsPerIteration   = 50;
    std::vector<std::thread> threads(threadCount);
    std::atomic<uint32_t> numOfContextsCreated(0);
    std::mutex mutex;
    for (size_t threadIdx = 0; threadIdx < threadCount; threadIdx++)
    {
        threads[threadIdx] = std::thread([&, threadIdx]() {
            EGLSurface surface = EGL_NO_SURFACE;
            EGLContext ctx     = EGL_NO_CONTEXT;

            {
                std::lock_guard<decltype(mutex)> lock(mutex);
                // Initialize the pbuffer and context
                surface = eglCreatePbufferSurface(dpy, config, pbufferAttributes);
                EXPECT_EGL_SUCCESS();
                ctx = createMultithreadedContext(window, /*EGL_NO_CONTEXT*/ sharedCtx);
                EXPECT_NE(EGL_NO_CONTEXT, ctx);
                EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, ctx));
                EXPECT_EGL_SUCCESS();
                numOfContextsCreated++;
            }

            // Wait for all contexts created.
            while (numOfContextsCreated < threadCount)
            {
            }

            // Now draw with shared vertex buffer
            {
                ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(),
                                 essl1_shaders::fs::UniformColor());
                glUseProgram(program);

                GLint colorLocation = glGetUniformLocation(program, essl1_shaders::ColorUniform());
                GLint positionLocation =
                    glGetAttribLocation(program, essl1_shaders::PositionAttrib());

                // Use sharedVertexBuffer
                glBindBuffer(GL_ARRAY_BUFFER, sharedVertexBuffer);
                glEnableVertexAttribArray(positionLocation);
                glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, 0);

                for (size_t iteration = 0; iteration < kIterationsPerThread; iteration++)
                {
                    // Base the clear color on the thread and iteration indexes so every clear color
                    // is unique
                    const GLColor color(static_cast<GLubyte>(threadIdx % 255),
                                        static_cast<GLubyte>(iteration % 255), 0, 255);
                    const angle::Vector4 floatColor = color.toNormalizedVector();
                    glUniform4fv(colorLocation, 1, floatColor.data());

                    for (size_t draw = 0; draw < kDrawsPerIteration; draw++)
                    {
                        glDrawArrays(GL_TRIANGLES, 0, 6);
                    }

                    EXPECT_PIXEL_COLOR_EQ(0, 0, color);
                }
            }

            // tear down shared context
            {
                std::lock_guard<decltype(mutex)> lock(mutex);
                EXPECT_EGL_TRUE(
                    eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
                EXPECT_EGL_SUCCESS();
                eglDestroySurface(dpy, surface);
                eglDestroyContext(dpy, ctx);
            }
        });
    }

    for (std::thread &thread : threads)
    {
        thread.join();
    }

    eglDestroySurface(dpy, sharedSurface);
    eglDestroyContext(dpy, sharedCtx);

    // Re-make current the test window's context for teardown.
    EXPECT_EGL_TRUE(
        eglMakeCurrent(dpy, window->getSurface(), window->getSurface(), window->getContext()));
    EXPECT_EGL_SUCCESS();
}

// Producer/Consumer test using EGLImages and EGLSyncs
TEST_P(MultithreadingTest, EGLImageProduceConsume)
{
    EGLWindow *window  = getEGLWindow();
    EGLDisplay dpy     = window->getDisplay();
    EGLContext rootCtx = window->getContext();

    ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(dpy, "EGL_KHR_image"));
    ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(dpy, "EGL_KHR_gl_texture_2D_image"));
    ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(dpy, "EGL_KHR_fence_sync"));

    struct sharedImage
    {
        EGLImage image;
        EGLSync sync;
        GLuint rootTexture;
    };

    std::mutex mutex;
    std::vector<sharedImage> waitingForProduce;
    std::vector<sharedImage> waitingForConsume;

    constexpr size_t kNumImages = 10;
    for (size_t i = 0; i < kNumImages; i++)
    {
        GLuint texture;
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);

        sharedImage img;
        img.image       = eglCreateImageKHR(dpy, rootCtx, EGL_GL_TEXTURE_2D_KHR,
                                            reinterpret_cast<EGLClientBuffer>(texture), nullptr);
        img.sync        = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr);
        img.rootTexture = texture;

        waitingForProduce.push_back(std::move(img));
    }

    constexpr size_t kIterations = 10000;

    std::thread producerThread([&]() {
        EGLContext ctx = createMultithreadedContext(window, EGL_NO_CONTEXT);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx));

        {
            ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(),
                             essl1_shaders::fs::UniformColor());
            glUseProgram(drawColor);
            GLint colorUniformLocation =
                glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
            ASSERT_NE(colorUniformLocation, -1);

            size_t iteration = 0;
            while (iteration < kIterations)
            {
                sharedImage img;
                {
                    std::lock_guard<decltype(mutex)> lock(mutex);
                    if (waitingForProduce.empty())
                    {
                        continue;
                    }
                    img = std::move(waitingForProduce.back());
                    waitingForProduce.pop_back();
                }

                eglWaitSync(dpy, img.sync, 0);
                EXPECT_EGL_SUCCESS();

                eglDestroySync(dpy, img.sync);

                GLTexture texture;
                glBindTexture(GL_TEXTURE_2D, texture);
                glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, img.image);
                EXPECT_GL_NO_ERROR();

                GLFramebuffer fbo;
                glBindFramebuffer(GL_FRAMEBUFFER, fbo);
                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
                                       0);

                glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
                glClear(GL_COLOR_BUFFER_BIT);

                glUniform4f(colorUniformLocation, float(iteration) / kIterations, 0.0f, 0.0f, 1.0f);
                drawQuad(drawColor, essl1_shaders::PositionAttrib(), 0);

                glBindTexture(GL_TEXTURE_2D, 0);
                glBindFramebuffer(GL_FRAMEBUFFER, 0);

                img.sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr);
                EXPECT_EGL_SUCCESS();
                glFlush();

                {
                    std::lock_guard<decltype(mutex)> lock(mutex);
                    waitingForConsume.insert(waitingForConsume.begin(), std::move(img));
                }

                iteration++;
            }
        }

        eglDestroyContext(dpy, ctx);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    });

    std::thread consumerThread([&]() {
        EGLContext ctx = createMultithreadedContext(window, EGL_NO_CONTEXT);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx));

        {
            ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(),
                             essl1_shaders::fs::Texture2D());
            glUseProgram(drawTexture);
            GLint textureUniformLocation =
                glGetUniformLocation(drawTexture, angle::essl1_shaders::Texture2DUniform());
            ASSERT_NE(textureUniformLocation, -1);
            glUniform1i(textureUniformLocation, 0);
            glActiveTexture(GL_TEXTURE0);

            GLTexture backbufferTexture;
            glBindTexture(GL_TEXTURE_2D, backbufferTexture);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                         nullptr);

            GLFramebuffer fbo;
            glBindFramebuffer(GL_FRAMEBUFFER, fbo);
            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
                                   backbufferTexture, 0);

            size_t iteration = 0;
            while (iteration < kIterations)
            {
                sharedImage img;
                {
                    std::lock_guard<decltype(mutex)> lock(mutex);
                    if (waitingForConsume.empty())
                    {
                        continue;
                    }
                    img = std::move(waitingForConsume.back());
                    waitingForConsume.pop_back();
                }

                eglWaitSync(dpy, img.sync, 0);
                EXPECT_EGL_SUCCESS();
                eglDestroySync(dpy, img.sync);

                GLTexture texture;
                glBindTexture(GL_TEXTURE_2D, texture);
                glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, img.image);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
                glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

                drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0);
                EXPECT_GL_NO_ERROR();

                glBindTexture(GL_TEXTURE_2D, 0);

                img.sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr);
                EXPECT_EGL_SUCCESS();
                glFlush();

                {
                    std::lock_guard<decltype(mutex)> lock(mutex);
                    waitingForProduce.insert(waitingForProduce.begin(), std::move(img));
                }

                iteration++;
            }
        }
        eglDestroyContext(dpy, ctx);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    });

    producerThread.join();
    consumerThread.join();

    // Clean up
    {
        for (auto &img : waitingForProduce)
        {
            eglDestroyImageKHR(dpy, img.image);
            eglDestroySync(dpy, img.sync);
            glDeleteTextures(1, &img.rootTexture);
        }
        for (auto &img : waitingForConsume)
        {
            eglDestroyImageKHR(dpy, img.image);
            eglDestroySync(dpy, img.sync);
            glDeleteTextures(1, &img.rootTexture);
        }
    }
}

void MultithreadingTestES3::textureThreadFunction(bool useDraw)
{
    EGLWindow *window  = getEGLWindow();
    EGLDisplay dpy     = window->getDisplay();
    EGLConfig config   = window->getConfig();
    EGLSurface surface = EGL_NO_SURFACE;
    EGLContext ctx     = EGL_NO_CONTEXT;

    // Initialize the pbuffer and context
    EGLint pbufferAttributes[] = {
        EGL_WIDTH, kSize, EGL_HEIGHT, kSize, EGL_NONE, EGL_NONE,
    };
    surface = eglCreatePbufferSurface(dpy, config, pbufferAttributes);
    EXPECT_EGL_SUCCESS();
    EXPECT_NE(EGL_NO_SURFACE, surface);

    ctx = createMultithreadedContext(window, window->getContext());
    EXPECT_NE(EGL_NO_CONTEXT, ctx);

    EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, ctx));
    EXPECT_EGL_SUCCESS();

    std::vector<GLColor> greenColor(kSize * kSize, GLColor::green);
    std::vector<GLColor> redColor(kSize * kSize, GLColor::red);
    ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

    glBindTexture(GL_TEXTURE_2D, mTexture2D);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    ASSERT_GL_NO_ERROR();

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture2D, 0);
    ASSERT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

    mSecondThreadSyncObj = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
    ASSERT_GL_NO_ERROR();

    // Draw something
    while (!mExitThread)
    {
        if (mMainThreadSyncObj == nullptr)
        {
            angle::Sleep(0);
        }

        std::lock_guard<decltype(mMutex)> lock(mMutex);

        if (mMainThreadSyncObj != nullptr)
        {
            glWaitSync(mMainThreadSyncObj, 0, GL_TIMEOUT_IGNORED);
            ASSERT_GL_NO_ERROR();
            glDeleteSync(mMainThreadSyncObj);
            ASSERT_GL_NO_ERROR();
            mMainThreadSyncObj = nullptr;
        }
        else
        {
            continue;
        }

        mDrawGreen = !mDrawGreen;

        glBindTexture(GL_TEXTURE_2D, mTexture2D);
        ASSERT_GL_NO_ERROR();

        if (mDrawGreen)
        {
            if (useDraw)
            {
                glBindFramebuffer(GL_FRAMEBUFFER, fbo);
                drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.0f);
            }
            else
            {
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                             greenColor.data());
            }
            ASSERT_GL_NO_ERROR();
        }
        else
        {
            if (useDraw)
            {
                glBindFramebuffer(GL_FRAMEBUFFER, fbo);
                drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.0f);
            }
            else
            {
                glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kSize, kSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                             redColor.data());
            }
            ASSERT_GL_NO_ERROR();
        }

        ASSERT_EQ(mSecondThreadSyncObj.load(), nullptr);
        mSecondThreadSyncObj = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        ASSERT_GL_NO_ERROR();
    }

    // Clean up
    EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    EXPECT_EGL_SUCCESS();

    eglDestroySurface(dpy, surface);
    eglDestroyContext(dpy, ctx);
}

// Test fence sync with multiple threads drawing
void MultithreadingTestES3::mainThreadDraw(bool useDraw)
{
    EGLWindow *window  = getEGLWindow();
    EGLDisplay dpy     = window->getDisplay();
    EGLContext ctx     = window->getContext();
    EGLSurface surface = window->getSurface();
    // Use odd numbers so we bounce between red and green in the final image
    constexpr int kNumIterations = 5;
    constexpr int kNumDraws      = 5;

    mDrawGreen = false;

    std::thread textureThread(&MultithreadingTestES3::textureThreadFunction, this, true);

    ANGLE_GL_PROGRAM(texProgram, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());

    for (int iterations = 0; iterations < kNumIterations; ++iterations)
    {
        GLColor expectedDrawColor;

        for (int draws = 0; draws < kNumDraws;)
        {
            if (mSecondThreadSyncObj == nullptr)
            {
                angle::Sleep(0);
            }

            std::lock_guard<decltype(mMutex)> lock(mMutex);

            if (mSecondThreadSyncObj != nullptr)
            {
                glWaitSync(mSecondThreadSyncObj, 0, GL_TIMEOUT_IGNORED);
                ASSERT_GL_NO_ERROR();
                glDeleteSync(mSecondThreadSyncObj);
                ASSERT_GL_NO_ERROR();
                mSecondThreadSyncObj = nullptr;
            }
            else
            {
                continue;
            }

            glBindFramebuffer(GL_FRAMEBUFFER, 0);
            glBindTexture(GL_TEXTURE_2D, mTexture2D);
            glUseProgram(texProgram);
            drawQuad(texProgram, essl1_shaders::PositionAttrib(), 0.0f);

            // mDrawGreen will be changed by the background thread past mMainThreadSyncObj
            // as it will start drawing the next color to fbo. This shouldn't affect
            // pixels of the current frame so save the expected color before unblocking the thread
            expectedDrawColor = mDrawGreen ? GLColor::green : GLColor::red;

            ASSERT_EQ(mMainThreadSyncObj.load(), nullptr);
            mMainThreadSyncObj = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
            ASSERT_GL_NO_ERROR();

            ++draws;
        }

        ASSERT_GL_NO_ERROR();
        EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, expectedDrawColor);

        swapBuffers();
    }

    mExitThread = true;
    textureThread.join();

    // Re-make current the test window's context for teardown.
    EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, ctx));
    EXPECT_EGL_SUCCESS();
}

// Test that glFenceSync/glWaitSync works correctly with multithreading.
// Main thread: Samples from the shared texture to draw to the default FBO.
// Secondary (Texture) thread: Draws to the shared texture, which the Main thread samples from.
// The overall execution flow is:
// Main Thread:
// 1. Wait for the mSecondThreadSyncObj fence object to be created.
//    - This fence object is used by synchronize access to the shared texture by indicating that the
//    Secondary thread's draws to the texture have all completed and it's now safe to sample from
//    it.
// 2. Once the fence is created, add a glWaitSync(mSecondThreadSyncObj) to the command stream and
//    then delete it.
// 3. Draw, sampling from the shared texture.
// 4. Create a new mMainThreadSyncObj.
//    - This fence object is used to synchronize access to the shared texture by indicating that the
//    Main thread's draws are no longer sampling from the texture, so it's now safe for the
//    Secondary thread to draw to it again with a new color.
// Secondary (Texture) Thread:
// 1. Wait for the mMainThreadSyncObj fence object to be created.
// 2. Once the fence is created, add a glWaitSync(mMainThreadSyncObj) to the command stream and then
//    delete it.
// 3. Draw/Fill the texture.
// 4. Create a new mSecondThreadSyncObj.
//
// These threads loop for the specified number of iterations, drawing/sampling the shared texture
// with the necessary glFlush()s and occasional eglSwapBuffers() to mimic a real multithreaded GLES
// application.
TEST_P(MultithreadingTestES3, MultithreadFenceDraw)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    // Have the secondary thread use glDrawArrays()
    mainThreadDraw(true);
}

// Same as MultithreadFenceDraw, but with the secondary thread using glTexImage2D rather than
// glDrawArrays.
TEST_P(MultithreadingTestES3, MultithreadFenceTexImage)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    // Have the secondary thread use glTexImage2D()
    mainThreadDraw(false);
}

// Test that waiting on a sync object that hasn't been flushed and without a current context returns
// TIMEOUT_EXPIRED or CONDITION_SATISFIED, but doesn't generate an error or crash.
TEST_P(MultithreadingTest, NoFlushNoContextReturnsTimeout)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());

    std::mutex mutex;

    EGLWindow *window = getEGLWindow();
    EGLDisplay dpy    = window->getDisplay();

    glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    EGLSyncKHR sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr);
    EXPECT_NE(sync, EGL_NO_SYNC_KHR);

    std::thread thread = std::thread([&]() {
        std::lock_guard<decltype(mutex)> lock(mutex);
        // Make sure there is no active context on this thread.
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_SUCCESS();
        // Don't wait forever to make sure the test terminates
        constexpr GLuint64 kTimeout = 1'000'000'000;  // 1 second
        int result                  = eglClientWaitSyncKHR(dpy, sync, 0, kTimeout);
        // We typically expect to get back TIMEOUT_EXPIRED since the sync object was never flushed.
        // However, the OpenGL ES backend returns CONDITION_SATISFIED, which is also a passing
        // result.
        ASSERT_TRUE(result == EGL_TIMEOUT_EXPIRED_KHR || result == EGL_CONDITION_SATISFIED_KHR);
    });

    thread.join();

    EXPECT_EGL_TRUE(eglDestroySyncKHR(dpy, sync));
}

// Test that waiting on sync object that hasn't been flushed yet, but is later flushed by another
// thread, correctly returns when the fence is signalled without a timeout.
TEST_P(MultithreadingTest, CreateFenceThreadAClientWaitSyncThreadBDelayedFlush)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());

    EGLSyncKHR sync = EGL_NO_SYNC_KHR;

    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0Clear,
        Thread1CreateFence,
        Thread0ClientWaitSync,
        Thread1Flush,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Start));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Do work.
        glClearColor(1.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);

        // Wait for thread 1 to clear.
        threadSynchronization.nextStep(Step::Thread0Clear);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1CreateFence));

        // Wait on the sync object, but do *not* flush it, since the other thread will flush.
        constexpr GLuint64 kTimeout = 2'000'000'000;  // 2 seconds
        threadSynchronization.nextStep(Step::Thread0ClientWaitSync);
        ASSERT_EQ(EGL_CONDITION_SATISFIED_KHR, eglClientWaitSyncKHR(dpy, sync, 0, kTimeout));

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        // Wait for thread 0 to clear.
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Clear));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Do work.
        glClearColor(0.0, 1.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);

        sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr);
        EXPECT_NE(sync, EGL_NO_SYNC_KHR);

        // Wait for the thread 0 to eglClientWaitSyncKHR().
        threadSynchronization.nextStep(Step::Thread1CreateFence);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0ClientWaitSync));

        // Wait a little to give thread 1 time to wait on the sync object before flushing it.
        angle::Sleep(500);
        glFlush();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Finish);
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Test that thread B can wait on thread A's sync before thread A flushes it, and wakes up after
// that.
void MultithreadingTestES3::testFenceWithOpenRenderPass(FenceTest test, FlushMethod flushMethod)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());

    constexpr uint32_t kWidth  = 100;
    constexpr uint32_t kHeight = 200;

    GLsync sync    = 0;
    GLuint texture = 0;

    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0CreateFence,
        Thread1WaitFence,
        Thread0Finish,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Start));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Create a shared texture to test synchronization
        GLTexture color;
        texture = color;

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

        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

        // Draw to shared texture.
        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        // Issue a fence.  A render pass is currently open, so the fence is not actually submitted
        // in the Vulkan backend.
        sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        ASSERT_NE(sync, nullptr);

        // Wait for thread 1 to wait on it.
        threadSynchronization.nextStep(Step::Thread0CreateFence);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1WaitFence));

        // Wait a little to give thread 1 time to wait on the sync object before flushing it.
        angle::Sleep(500);
        switch (flushMethod)
        {
            case FlushMethod::Flush:
                glFlush();
                break;
            case FlushMethod::Finish:
                glFinish();
                break;
        }

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Thread0Finish);
        threadSynchronization.waitForStep(Step::Finish);
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Wait for thread 0 to create the fence object.
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0CreateFence));

        // Test access to the fence object
        threadSynchronization.nextStep(Step::Thread1WaitFence);

        constexpr GLuint64 kTimeout = 2'000'000'000;  // 2 seconds
        GLenum result               = GL_CONDITION_SATISFIED;
        switch (test)
        {
            case FenceTest::ClientWait:
                result = glClientWaitSync(sync, 0, kTimeout);
                break;
            case FenceTest::ServerWait:
                glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
                break;
            case FenceTest::GetStatus:
            {
                GLint value;
                glGetSynciv(sync, GL_SYNC_STATUS, 1, nullptr, &value);
                if (value != GL_SIGNALED)
                {
                    result = glClientWaitSync(sync, 0, kTimeout);
                }
                break;
            }
        }
        ASSERT_TRUE(result == GL_CONDITION_SATISFIED || result == GL_ALREADY_SIGNALED);

        // Verify the shared texture is drawn to.
        glBindTexture(GL_TEXTURE_2D, texture);

        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Finish));
        threadSynchronization.nextStep(Step::Finish);
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Test that thread B can wait on thread A's sync before thread A flushes it, and wakes up after
// that.
TEST_P(MultithreadingTestES3, ThreadBClientWaitBeforeThreadASyncFlush)
{
    testFenceWithOpenRenderPass(FenceTest::ClientWait, FlushMethod::Flush);
}

// Test that thread B can wait on thread A's sync before thread A flushes it, and wakes up after
// that.
TEST_P(MultithreadingTestES3, ThreadBServerWaitBeforeThreadASyncFlush)
{
    testFenceWithOpenRenderPass(FenceTest::ServerWait, FlushMethod::Flush);
}

// Test that thread B can wait on thread A's sync before thread A flushes it, and wakes up after
// that.
TEST_P(MultithreadingTestES3, ThreadBGetStatusBeforeThreadASyncFlush)
{
    testFenceWithOpenRenderPass(FenceTest::GetStatus, FlushMethod::Flush);
}

// Test that thread B can wait on thread A's sync before thread A flushes it, and wakes up after
// that.
TEST_P(MultithreadingTestES3, ThreadBClientWaitBeforeThreadASyncFinish)
{
    testFenceWithOpenRenderPass(FenceTest::ClientWait, FlushMethod::Finish);
}

// Test that thread B can wait on thread A's sync before thread A flushes it, and wakes up after
// that.
TEST_P(MultithreadingTestES3, ThreadBServerWaitBeforeThreadASyncFinish)
{
    testFenceWithOpenRenderPass(FenceTest::ServerWait, FlushMethod::Finish);
}

// Test that thread B can wait on thread A's sync before thread A flushes it, and wakes up after
// that.
TEST_P(MultithreadingTestES3, ThreadBGetStatusBeforeThreadASyncFinish)
{
    testFenceWithOpenRenderPass(FenceTest::GetStatus, FlushMethod::Finish);
}

// Test the following scenario:
//
// - Thread A opens a render pass, and flushes it.  In the Vulkan backend, this may make the flush
//   deferred.
// - Thread B opens a render pass and creates a fence.  In the Vulkan backend, this also defers the
//   flush.
// - Thread C waits on fence
//
// In the Vulkan backend, submission of the fence is implied by thread C's wait, and thread A may
// also be flushed as collateral.  If the fence's serial is updated based on thread A's submission,
// synchronization between B and C would be broken.
TEST_P(MultithreadingTestES3, ThreadCWaitBeforeThreadBSyncFinish)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());

    constexpr uint32_t kWidth  = 100;
    constexpr uint32_t kHeight = 200;

    GLsync sync    = 0;
    GLuint texture = 0;

    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0DrawAndFlush,
        Thread1CreateFence,
        Thread2WaitFence,
        Thread2Finished,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Start));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Open a render pass and flush it.
        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
        glFlush();
        ASSERT_GL_NO_ERROR();

        threadSynchronization.nextStep(Step::Thread0DrawAndFlush);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Wait for thread 0 to set up
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0DrawAndFlush));

        // Create a shared texture to test synchronization
        GLTexture color;
        texture = color;

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

        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

        // Draw to shared texture.
        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        // Issue a fence.  A render pass is currently open, so the fence is not actually submitted
        // in the Vulkan backend.
        sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        ASSERT_NE(sync, nullptr);

        // Wait for thread 1 to wait on it.
        threadSynchronization.nextStep(Step::Thread1CreateFence);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread2WaitFence));

        // Wait a little to give thread 1 time to wait on the sync object before flushing it.
        angle::Sleep(500);
        glFlush();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Thread2Finished);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
    };

    auto thread2 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Wait for thread 0 to create the fence object.
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1CreateFence));

        // Test access to the fence object
        threadSynchronization.nextStep(Step::Thread2WaitFence);

        constexpr GLuint64 kTimeout = 2'000'000'000;  // 2 seconds
        GLenum result               = glClientWaitSync(sync, 0, kTimeout);
        ASSERT_TRUE(result == GL_CONDITION_SATISFIED || result == GL_ALREADY_SIGNALED);

        // Verify the shared texture is drawn to.
        glBindTexture(GL_TEXTURE_2D, texture);

        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

        EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::red);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread2Finished));
        threadSynchronization.nextStep(Step::Finish);
    };

    std::array<LockStepThreadFunc, 3> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
        std::move(thread2),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Test that having commands recorded but not submitted on one thread using a texture, does not
// interfere with similar commands on another thread using the same texture.  Regression test for a
// bug in the Vulkan backend where the first thread would batch updates to a descriptor set not
// visible to the other thread, while the other thread picks up the (unupdated) descriptor set from
// a shared cache.
TEST_P(MultithreadingTestES3, UnsynchronizedTextureReads)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());

    GLsync sync    = 0;
    GLuint texture = 0;

    constexpr GLubyte kInitialData[4] = {127, 63, 191, 255};

    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0CreateTextureAndDraw,
        Thread1DrawAndFlush,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Start));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Create a texture, and record a command that draws into it.
        GLTexture color;
        texture = color;

        glBindTexture(GL_TEXTURE_2D, texture);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kInitialData);

        sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        ASSERT_NE(sync, nullptr);

        ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(),
                         essl1_shaders::fs::Texture2D());
        drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.0f);

        // Don't flush yet; this leaves the descriptor set updates to the texture pending in the
        // Vulkan backend.
        threadSynchronization.nextStep(Step::Thread0CreateTextureAndDraw);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1DrawAndFlush));

        // Flush after thread 1
        EXPECT_PIXEL_COLOR_NEAR(
            0, 0, GLColor(kInitialData[0], kInitialData[1], kInitialData[2], kInitialData[3]), 1);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Finish);
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Wait for thread 0 to set up
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0CreateTextureAndDraw));

        // Synchronize with the texture upload (but not the concurrent read)
        glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);

        // Draw with the same texture, in the same way as thread 0.  This ensures that the
        // descriptor sets used in the Vulkan backend are identical.
        glBindTexture(GL_TEXTURE_2D, texture);
        ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(),
                         essl1_shaders::fs::Texture2D());
        drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.0f);

        // Flush
        EXPECT_PIXEL_COLOR_NEAR(
            0, 0, GLColor(kInitialData[0], kInitialData[1], kInitialData[2], kInitialData[3]), 1);

        threadSynchronization.nextStep(Step::Thread1DrawAndFlush);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Similar to UnsynchronizedTextureReads, but the texture update is done through framebuffer write.
TEST_P(MultithreadingTestES3, UnsynchronizedTextureReads2)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());

    GLsync sync    = 0;
    GLuint texture = 0;

    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0CreateTextureAndDraw,
        Thread1DrawAndFlush,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Start));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Create a texture, and record a command that draws into it.
        GLTexture color;
        texture = color;

        glBindTexture(GL_TEXTURE_2D, texture);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

        glClearColor(1, 0, 0, 1);
        glClear(GL_COLOR_BUFFER_BIT);
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
        glBindFramebuffer(GL_FRAMEBUFFER, 0);

        sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        ASSERT_NE(sync, nullptr);

        ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(),
                         essl1_shaders::fs::Texture2D());
        drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.0f);

        // Don't flush yet; this leaves the descriptor set updates to the texture pending in the
        // Vulkan backend.
        threadSynchronization.nextStep(Step::Thread0CreateTextureAndDraw);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1DrawAndFlush));

        // Flush after thread 1
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Finish);
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Wait for thread 0 to set up
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0CreateTextureAndDraw));

        // Synchronize with the texture update (but not the concurrent read)
        glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);

        // Draw with the same texture, in the same way as thread 0.  This ensures that the
        // descriptor sets used in the Vulkan backend are identical.
        glBindTexture(GL_TEXTURE_2D, texture);
        ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(),
                         essl1_shaders::fs::Texture2D());
        drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.0f);

        // Flush
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

        threadSynchronization.nextStep(Step::Thread1DrawAndFlush);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Similar to UnsynchronizedTextureReads, but the texture is used once.  This is because
// UnsynchronizedTextureRead hits a different bug than it intends to test.  This test makes sure the
// image is put in the right layout, by using it together with another texture (i.e. a different
// descriptor set).
TEST_P(MultithreadingTestES3, UnsynchronizedTextureReads3)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    constexpr GLubyte kInitialData[4] = {127, 63, 191, 255};

    GLuint texture = 0;

    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0CreateTextureAndDraw,
        Thread1DrawAndFlush,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Start));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Create a texture, and record a command that draws into it.
        GLTexture color;
        texture = color;

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kInitialData);

        glActiveTexture(GL_TEXTURE1);
        GLTexture color2;
        glBindTexture(GL_TEXTURE_2D, color2);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, kInitialData);

        ANGLE_GL_PROGRAM(setupTexture, essl1_shaders::vs::Texture2D(),
                         R"(precision mediump float;
uniform sampler2D tex2D;
uniform sampler2D tex2D2;
varying vec2 v_texCoord;

void main()
{
    gl_FragColor = texture2D(tex2D, v_texCoord) + texture2D(tex2D2, v_texCoord);
})");
        drawQuad(setupTexture, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        glFinish();

        ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(),
                         essl1_shaders::fs::Texture2D());
        drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        // Don't flush yet; this leaves the descriptor set updates to the texture pending in the
        // Vulkan backend.
        threadSynchronization.nextStep(Step::Thread0CreateTextureAndDraw);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1DrawAndFlush));

        // Flush after thread 1
        EXPECT_PIXEL_COLOR_NEAR(
            0, 0, GLColor(kInitialData[0], kInitialData[1], kInitialData[2], kInitialData[3]), 1);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Finish);
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Wait for thread 0 to set up
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0CreateTextureAndDraw));

        // Draw with the same texture, in the same way as thread 0.  This ensures that the
        // descriptor sets used in the Vulkan backend are identical.
        glBindTexture(GL_TEXTURE_2D, texture);
        ANGLE_GL_PROGRAM(drawTexture, essl1_shaders::vs::Texture2D(),
                         essl1_shaders::fs::Texture2D());
        drawQuad(drawTexture, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        // Flush
        EXPECT_PIXEL_COLOR_NEAR(
            0, 0, GLColor(kInitialData[0], kInitialData[1], kInitialData[2], kInitialData[3]), 1);

        threadSynchronization.nextStep(Step::Thread1DrawAndFlush);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Test framebuffer fetch program used between share groups.
void MultithreadingTestES3::testFramebufferFetch(DrawOrder drawOrder)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_framebuffer_fetch_non_coherent"));

    GLProgram framebufferFetchProgram;

    constexpr char kFS[] = R"(#version 300 es
#extension GL_EXT_shader_framebuffer_fetch_non_coherent : require
layout(noncoherent, location = 0) inout highp vec4 o_color;

uniform highp vec4 u_color;
void main (void)
{
    o_color += u_color;
})";

    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0PreCreateProgram,
        Thread1CreateProgram,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Start));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Open a render pass, if requested.
        if (drawOrder == DrawOrder::Before)
        {
            ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
            drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
            ASSERT_GL_NO_ERROR();
        }

        threadSynchronization.nextStep(Step::Thread0PreCreateProgram);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1CreateProgram));

        // Render using the framebuffer fetch program
        if (drawOrder == DrawOrder::After)
        {
            ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
            drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
            ASSERT_GL_NO_ERROR();
        }

        glFramebufferFetchBarrierEXT();

        glUseProgram(framebufferFetchProgram);
        GLint colorLocation = glGetUniformLocation(framebufferFetchProgram, "u_color");
        glUniform4f(colorLocation, 1, 0, 0, 0);
        drawQuad(framebufferFetchProgram, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);

        threadSynchronization.nextStep(Step::Finish);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Wait for thread 0 to set up
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0PreCreateProgram));

        // Create the framebuffer fetch program
        framebufferFetchProgram.makeRaster(essl3_shaders::vs::Simple(), kFS);
        glUseProgram(framebufferFetchProgram);

        // Notify the other thread to use it
        threadSynchronization.nextStep(Step::Thread1CreateProgram);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

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

        glFramebufferFetchBarrierEXT();

        glUseProgram(framebufferFetchProgram);
        GLint colorLocation = glGetUniformLocation(framebufferFetchProgram, "u_color");
        glUniform4f(colorLocation, 0, 0, 1, 0);
        drawQuad(framebufferFetchProgram, essl1_shaders::PositionAttrib(), 0.0f);
        ASSERT_GL_NO_ERROR();

        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Thread 1 creates the framebuffer fetch program.  Thread 0 proceeds to use it.
TEST_P(MultithreadingTestES3, CreateFramebufferFetchBeforeRenderPass)
{
    testFramebufferFetch(DrawOrder::After);
}

// Thread 1 creates the framebuffer fetch program while thread 0 is mid render pass.  Thread 0
// proceeds to use the framebuffer fetch program in the rest of its render pass.
TEST_P(MultithreadingTestES3, CreateFramebufferFetchMidRenderPass)
{
    testFramebufferFetch(DrawOrder::Before);
}

// Test async monolithic pipeline creation in the Vulkan backend vs shared programs.  This test
// makes one context/thread create a set of programs, then has another context/thread use them a few
// times, and then the original context destroys them.
TEST_P(MultithreadingTestES3, ProgramUseAndDestroyInTwoContexts)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    GLProgram programs[6];

    GLsync sync = 0;

    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0CreatePrograms,
        Thread1UsePrograms,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Start));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Create the programs
        programs[0].makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        programs[1].makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        programs[2].makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
        programs[3].makeRaster(essl1_shaders::vs::Passthrough(), essl1_shaders::fs::Checkered());
        programs[4].makeRaster(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
        programs[5].makeRaster(essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());

        EXPECT_TRUE(programs[0].valid());
        EXPECT_TRUE(programs[1].valid());
        EXPECT_TRUE(programs[2].valid());
        EXPECT_TRUE(programs[3].valid());
        EXPECT_TRUE(programs[4].valid());
        EXPECT_TRUE(programs[5].valid());

        threadSynchronization.nextStep(Step::Thread0CreatePrograms);
        // Wait for the other thread to use the programs
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1UsePrograms));

        // Destroy them
        glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
        programs[0].reset();
        programs[1].reset();
        programs[2].reset();
        programs[3].reset();
        programs[4].reset();
        programs[5].reset();

        threadSynchronization.nextStep(Step::Finish);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        // Wait for thread 0 to create the programs
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0CreatePrograms));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Use them a few times.
        drawQuad(programs[0], essl1_shaders::PositionAttrib(), 0.0f);
        drawQuad(programs[1], essl1_shaders::PositionAttrib(), 0.0f);
        drawQuad(programs[2], essl1_shaders::PositionAttrib(), 0.0f);
        drawQuad(programs[3], essl1_shaders::PositionAttrib(), 0.0f);
        drawQuad(programs[4], essl1_shaders::PositionAttrib(), 0.0f);

        drawQuad(programs[0], essl1_shaders::PositionAttrib(), 0.0f);
        drawQuad(programs[1], essl1_shaders::PositionAttrib(), 0.0f);
        drawQuad(programs[2], essl1_shaders::PositionAttrib(), 0.0f);

        drawQuad(programs[0], essl1_shaders::PositionAttrib(), 0.0f);

        sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        ASSERT_NE(sync, nullptr);

        // Notify the other thread to destroy the programs.
        threadSynchronization.nextStep(Step::Thread1UsePrograms);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Tests that Context with High Priority will correctly sample Texture rendered by Share Context
// with Low Priority.
TEST_P(MultithreadingTestES3, RenderThenSampleDifferentContextPriority)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    constexpr size_t kIterationCountMax = 10;

    const bool reduceLoad       = isSwiftshader();
    const size_t iterationCount = reduceLoad ? 3 : kIterationCountMax;
    const size_t heavyDrawCount = reduceLoad ? 25 : 100;

    // Initialize contexts
    EGLWindow *window = getEGLWindow();
    EGLDisplay dpy    = window->getDisplay();
    EGLConfig config  = window->getConfig();

    // Large enough texture to catch timing problems.
    constexpr GLsizei kTexSize       = 1024;
    constexpr size_t kThreadCount    = 2;
    EGLSurface surface[kThreadCount] = {EGL_NO_SURFACE, EGL_NO_SURFACE};
    EGLContext ctx[kThreadCount]     = {EGL_NO_CONTEXT, EGL_NO_CONTEXT};

    EGLint priorities[kThreadCount] = {EGL_CONTEXT_PRIORITY_LOW_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG};

    EGLint pbufferAttributes[kThreadCount][6] = {
        {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE},
        {EGL_WIDTH, kTexSize, EGL_HEIGHT, kTexSize, EGL_NONE, EGL_NONE}};

    EGLint attributes[]     = {EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_NONE,
                               EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE, EGL_NONE, EGL_NONE};
    EGLint *extraAttributes = attributes;
    if (!IsEGLDisplayExtensionEnabled(dpy, "EGL_ANGLE_context_virtualization"))
    {
        attributes[2] = EGL_NONE;
    }
    if (!IsEGLDisplayExtensionEnabled(dpy, "EGL_IMG_context_priority"))
    {
        // Run tests with single priority anyway.
        extraAttributes += 2;
    }

    for (size_t t = 0; t < kThreadCount; ++t)
    {
        surface[t] = eglCreatePbufferSurface(dpy, config, pbufferAttributes[t]);
        EXPECT_EGL_SUCCESS();

        attributes[1] = priorities[t];
        attributes[3] = mVirtualizationGroup++;

        ctx[t] = window->createContext(t == 0 ? EGL_NO_CONTEXT : ctx[0], extraAttributes);
        EXPECT_NE(EGL_NO_CONTEXT, ctx[t]);
    }

    // Synchronization tools to ensure the two threads are interleaved as designed by this test.
    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0Init,
        Thread1Init,
        Thread0Draw,
        Thread1Draw,
        Finish = Thread0Draw + kIterationCountMax * 2,
        Abort,
    };
    Step currentStep = Step::Start;

    GLTexture texture;
    GLsync thread0DrawSyncObj;

    auto calculateTestColor = [](size_t i) {
        return GLColor(i % 256, (i + 1) % 256, (i + 2) % 256, 255);
    };
    auto makeStep = [](Step base, size_t i) {
        return static_cast<Step>(static_cast<size_t>(base) + i * 2);
    };

    // Render to the texture.
    std::thread thread0 = std::thread([&]() {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface[0], surface[0], ctx[0]));
        EXPECT_EGL_SUCCESS();

        glBindTexture(GL_TEXTURE_2D, texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        glViewport(0, 0, kTexSize, kTexSize);

        ANGLE_GL_PROGRAM(colorProgram, essl1_shaders::vs::Simple(),
                         essl1_shaders::fs::UniformColor());
        GLint colorLocation =
            glGetUniformLocation(colorProgram, angle::essl1_shaders::ColorUniform());
        ASSERT_NE(-1, colorLocation);
        glUseProgram(colorProgram);

        // Notify second thread that initialization is finished.
        threadSynchronization.nextStep(Step::Thread0Init);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Init));

        for (size_t i = 0; i < iterationCount; ++i)
        {
            // Simulate heavy work...
            glUniform4f(colorLocation, 0.0f, 0.0f, 0.0f, 0.0f);
            for (size_t j = 0; j < heavyDrawCount; ++j)
            {
                drawQuad(colorProgram, essl1_shaders::PositionAttrib(), 0.5f);
            }

            // Draw with test color.
            Vector4 color = calculateTestColor(i).toNormalizedVector();
            glUniform4f(colorLocation, color.x(), color.y(), color.z(), color.w());
            drawQuad(colorProgram, essl1_shaders::PositionAttrib(), 0.5f);

            thread0DrawSyncObj = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
            ASSERT_GL_NO_ERROR();

            // Notify second thread that draw is finished.
            threadSynchronization.nextStep(makeStep(Step::Thread0Draw, i));
            ASSERT_TRUE(threadSynchronization.waitForStep(
                (i == iterationCount - 1) ? Step::Finish : makeStep(Step::Thread1Draw, i)));
        }

        EXPECT_GL_NO_ERROR();
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_SUCCESS();
    });

    // Sample texture
    std::thread thread1 = std::thread([&]() {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface[1], surface[1], ctx[1]));
        EXPECT_EGL_SUCCESS();

        glViewport(0, 0, kTexSize, kTexSize);

        ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(),
                         essl1_shaders::fs::Texture2D());
        glUseProgram(textureProgram);

        // Wait for first thread to finish initializing.
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Init));

        glBindTexture(GL_TEXTURE_2D, texture);

        // Wait for first thread to draw using the shared texture.
        threadSynchronization.nextStep(Step::Thread1Init);

        for (size_t i = 0; i < iterationCount; ++i)
        {
            ASSERT_TRUE(threadSynchronization.waitForStep(makeStep(Step::Thread0Draw, i)));

            ASSERT_TRUE(thread0DrawSyncObj != nullptr);
            glWaitSync(thread0DrawSyncObj, 0, GL_TIMEOUT_IGNORED);
            ASSERT_GL_NO_ERROR();

            // Should draw test color.
            drawQuad(textureProgram, essl1_shaders::PositionAttrib(), 0.5f);

            // Check test color in four corners.
            GLColor color = calculateTestColor(i);
            EXPECT_PIXEL_EQ(0, 0, color.R, color.G, color.B, color.A);
            EXPECT_PIXEL_EQ(0, kTexSize - 1, color.R, color.G, color.B, color.A);
            EXPECT_PIXEL_EQ(kTexSize - 1, 0, color.R, color.G, color.B, color.A);
            EXPECT_PIXEL_EQ(kTexSize - 1, kTexSize - 1, color.R, color.G, color.B, color.A);

            glDeleteSync(thread0DrawSyncObj);
            ASSERT_GL_NO_ERROR();
            thread0DrawSyncObj = nullptr;

            threadSynchronization.nextStep(
                (i == iterationCount - 1) ? Step::Finish : makeStep(Step::Thread1Draw, i));
        }

        EXPECT_GL_NO_ERROR();
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_SUCCESS();
    });

    thread0.join();
    thread1.join();

    ASSERT_NE(currentStep, Step::Abort);

    // Clean up
    for (size_t t = 0; t < kThreadCount; ++t)
    {
        eglDestroySurface(dpy, surface[t]);
        eglDestroyContext(dpy, ctx[t]);
    }
}

// Tests that newly created Context with High Priority will correctly sample Texture already
// rendered by Share Context with Low Priority.
TEST_P(MultithreadingTestES3, RenderThenSampleInNewContextWithDifferentPriority)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_disjoint_timer_query"));

    const bool reduceLoad       = isSwiftshader();
    const size_t heavyDrawCount = reduceLoad ? 75 : 1000;

    // Initialize contexts
    EGLWindow *window = getEGLWindow();
    EGLDisplay dpy    = window->getDisplay();
    EGLConfig config  = window->getConfig();

    // Large enough texture to catch timing problems.
    constexpr GLsizei kTexSize       = 1024;
    constexpr size_t kThreadCount    = 2;
    EGLSurface surface[kThreadCount] = {EGL_NO_SURFACE, EGL_NO_SURFACE};
    EGLContext ctx[kThreadCount]     = {EGL_NO_CONTEXT, EGL_NO_CONTEXT};

    EGLint priorities[kThreadCount] = {EGL_CONTEXT_PRIORITY_LOW_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG};

    EGLint pbufferAttributes[kThreadCount][6] = {
        {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE},
        {EGL_WIDTH, kTexSize, EGL_HEIGHT, kTexSize, EGL_NONE, EGL_NONE}};

    EGLint attributes[]     = {EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_NONE,
                               EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE, EGL_NONE, EGL_NONE};
    EGLint *extraAttributes = attributes;
    if (!IsEGLDisplayExtensionEnabled(dpy, "EGL_ANGLE_context_virtualization"))
    {
        attributes[2] = EGL_NONE;
    }
    if (!IsEGLDisplayExtensionEnabled(dpy, "EGL_IMG_context_priority"))
    {
        // Run tests with single priority anyway.
        extraAttributes += 2;
    }

    for (size_t t = 0; t < kThreadCount; ++t)
    {
        surface[t] = eglCreatePbufferSurface(dpy, config, pbufferAttributes[t]);
        EXPECT_EGL_SUCCESS();

        attributes[1] = priorities[t];
        attributes[3] = mVirtualizationGroup++;

        // Second context will be created in a thread 1
        if (t == 0)
        {
            ctx[t] = window->createContext(t == 0 ? EGL_NO_CONTEXT : ctx[0], extraAttributes);
            EXPECT_NE(EGL_NO_CONTEXT, ctx[t]);
        }
    }

    // Synchronization tools to ensure the two threads are interleaved as designed by this test.
    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0Draw,
        Thread1Draw,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    // Create shared resources before threads to minimize timing delays.
    EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface[0], surface[0], ctx[0]));
    EXPECT_EGL_SUCCESS();

    ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
    ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
    ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(),
                     essl1_shaders::fs::Texture2D());

    GLTexture texture;
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 nullptr);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    glViewport(0, 0, kTexSize, kTexSize);

    EXPECT_GL_NO_ERROR();
    EXPECT_EGL_TRUE(window->makeCurrent());
    EXPECT_EGL_SUCCESS();

    GLsync thread0DrawSyncObj;

    // Render to the texture.
    std::thread thread0 = std::thread([&]() {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface[0], surface[0], ctx[0]));
        EXPECT_EGL_SUCCESS();

        // Enable additive blend
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);

        GLuint query;
        glGenQueries(1, &query);
        glBeginQuery(GL_TIME_ELAPSED_EXT, query);
        ASSERT_GL_NO_ERROR();

        // Simulate heavy work...
        glUseProgram(redProgram);
        for (size_t j = 0; j < heavyDrawCount; ++j)
        {
            // Draw with Red color.
            drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
        }

        // Draw with Green color.
        glUseProgram(greenProgram);
        drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);

        // This should force "flushToPrimary()"
        glEndQuery(GL_TIME_ELAPSED_EXT);
        glDeleteQueries(1, &query);
        ASSERT_GL_NO_ERROR();

        // Continue draw with Blue color after flush...
        glUseProgram(blueProgram);
        drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);

        thread0DrawSyncObj = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        ASSERT_GL_NO_ERROR();

        // Notify second thread that draw is finished.
        threadSynchronization.nextStep(Step::Thread0Draw);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

        EXPECT_GL_NO_ERROR();
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_SUCCESS();
    });

    // Sample texture
    std::thread thread1 = std::thread([&]() {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        // Wait for first thread to finish draw.
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Draw));

        // Create High priority Context when Low priority Context already rendered to the texture.
        ctx[1] = window->createContext(ctx[0], extraAttributes);
        EXPECT_NE(EGL_NO_CONTEXT, ctx[1]);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface[1], surface[1], ctx[1]));
        EXPECT_EGL_SUCCESS();

        glViewport(0, 0, kTexSize, kTexSize);

        ASSERT_TRUE(thread0DrawSyncObj != nullptr);
        glWaitSync(thread0DrawSyncObj, 0, GL_TIMEOUT_IGNORED);
        ASSERT_GL_NO_ERROR();

        // Should draw test color.
        glUseProgram(textureProgram);
        glBindTexture(GL_TEXTURE_2D, texture);
        drawQuad(textureProgram, essl1_shaders::PositionAttrib(), 0.5f);

        // Check test color in four corners.
        GLColor color = GLColor::white;
        EXPECT_PIXEL_EQ(0, 0, color.R, color.G, color.B, color.A);
        EXPECT_PIXEL_EQ(0, kTexSize - 1, color.R, color.G, color.B, color.A);
        EXPECT_PIXEL_EQ(kTexSize - 1, 0, color.R, color.G, color.B, color.A);
        EXPECT_PIXEL_EQ(kTexSize - 1, kTexSize - 1, color.R, color.G, color.B, color.A);

        glDeleteSync(thread0DrawSyncObj);
        ASSERT_GL_NO_ERROR();
        thread0DrawSyncObj = nullptr;

        threadSynchronization.nextStep(Step::Finish);

        EXPECT_GL_NO_ERROR();
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_SUCCESS();
    });

    thread0.join();
    thread1.join();

    ASSERT_NE(currentStep, Step::Abort);

    // Clean up
    for (size_t t = 0; t < kThreadCount; ++t)
    {
        eglDestroySurface(dpy, surface[t]);
        eglDestroyContext(dpy, ctx[t]);
    }
}

// Tests that Context with High Priority will correctly sample EGLImage target Texture rendered by
// other Context with Low Priority into EGLImage source texture.
TEST_P(MultithreadingTestES3, RenderThenSampleDifferentContextPriorityUsingEGLImage)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_EGL_image"));
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_disjoint_timer_query"));

    const bool reduceLoad       = isSwiftshader();
    const size_t heavyDrawCount = reduceLoad ? 75 : 1000;

    // Initialize contexts
    EGLWindow *window = getEGLWindow();
    EGLDisplay dpy    = window->getDisplay();
    EGLConfig config  = window->getConfig();

    ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(dpy, "EGL_KHR_image_base"));
    ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(dpy, "EGL_KHR_gl_texture_2D_image"));

    // Large enough texture to catch timing problems.
    constexpr GLsizei kTexSize       = 1024;
    constexpr size_t kThreadCount    = 2;
    EGLSurface surface[kThreadCount] = {EGL_NO_SURFACE, EGL_NO_SURFACE};
    EGLContext ctx[kThreadCount]     = {EGL_NO_CONTEXT, EGL_NO_CONTEXT};

    EGLint priorities[kThreadCount] = {EGL_CONTEXT_PRIORITY_LOW_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG};

    EGLint pbufferAttributes[kThreadCount][6] = {
        {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE},
        {EGL_WIDTH, kTexSize, EGL_HEIGHT, kTexSize, EGL_NONE, EGL_NONE}};

    EGLint attributes[]     = {EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_NONE,
                               EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE, EGL_NONE, EGL_NONE};
    EGLint *extraAttributes = attributes;
    if (!IsEGLDisplayExtensionEnabled(dpy, "EGL_ANGLE_context_virtualization"))
    {
        attributes[2] = EGL_NONE;
    }
    if (!IsEGLDisplayExtensionEnabled(dpy, "EGL_IMG_context_priority"))
    {
        // Run tests with single priority anyway.
        extraAttributes += 2;
    }

    for (size_t t = 0; t < kThreadCount; ++t)
    {
        surface[t] = eglCreatePbufferSurface(dpy, config, pbufferAttributes[t]);
        EXPECT_EGL_SUCCESS();

        attributes[1] = priorities[t];
        attributes[3] = mVirtualizationGroup++;

        // Contexts not shared
        ctx[t] = window->createContext(EGL_NO_CONTEXT, extraAttributes);
        EXPECT_NE(EGL_NO_CONTEXT, ctx[t]);
    }

    // Synchronization tools to ensure the two threads are interleaved as designed by this test.
    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread1Init,
        Thread0Draw,
        Thread1Draw,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    EGLImage image  = EGL_NO_IMAGE_KHR;
    EGLSyncKHR sync = EGL_NO_SYNC_KHR;

    // Render to the EGLImage source texture.
    std::thread thread0 = std::thread([&]() {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface[0], surface[0], ctx[0]));
        EXPECT_EGL_SUCCESS();

        // Create source texture.
        GLTexture texture;
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        glViewport(0, 0, kTexSize, kTexSize);

        ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());

        // Wait for second thread to finish initializing.
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Init));

        // Enable additive blend
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);

        GLuint query;
        glGenQueries(1, &query);
        glBeginQuery(GL_TIME_ELAPSED_EXT, query);
        ASSERT_GL_NO_ERROR();

        // Simulate heavy work...
        glUseProgram(redProgram);
        for (size_t j = 0; j < heavyDrawCount; ++j)
        {
            // Draw with Red color.
            drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
        }

        // Draw with Green color.
        glUseProgram(greenProgram);
        drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);

        // This should force "flushToPrimary()"
        glEndQuery(GL_TIME_ELAPSED_EXT);
        glDeleteQueries(1, &query);
        ASSERT_GL_NO_ERROR();

        // Continue draw with Blue color after flush...
        glUseProgram(blueProgram);
        drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);

        sync = eglCreateSyncKHR(dpy, EGL_SYNC_FENCE_KHR, nullptr);
        EXPECT_NE(sync, EGL_NO_SYNC_KHR);

        // Create EGLImage.
        image = eglCreateImageKHR(
            dpy, ctx[0], EGL_GL_TEXTURE_2D_KHR,
            reinterpret_cast<EGLClientBuffer>(static_cast<uintptr_t>(texture)), nullptr);
        ASSERT_EGL_SUCCESS();

        // Notify second thread that draw is finished.
        threadSynchronization.nextStep(Step::Thread0Draw);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

        EXPECT_GL_NO_ERROR();
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_SUCCESS();
    });

    // Sample texture
    std::thread thread1 = std::thread([&]() {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface[1], surface[1], ctx[1]));
        EXPECT_EGL_SUCCESS();

        glViewport(0, 0, kTexSize, kTexSize);

        ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(),
                         essl1_shaders::fs::Texture2D());
        glUseProgram(textureProgram);

        // Create target texture.
        GLTexture texture;
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        // Wait for first thread to draw into the source texture.
        threadSynchronization.nextStep(Step::Thread1Init);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Draw));

        // Wait for draw to complete
        ASSERT_TRUE(eglWaitSyncKHR(dpy, sync, 0));

        // Specify target texture from EGLImage.
        glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image);
        ASSERT_GL_NO_ERROR();

        // Should draw test color.
        drawQuad(textureProgram, essl1_shaders::PositionAttrib(), 0.5f);
        ASSERT_GL_NO_ERROR();

        // Check test color in four corners.
        GLColor color = GLColor::white;
        EXPECT_PIXEL_EQ(0, 0, color.R, color.G, color.B, color.A);
        EXPECT_PIXEL_EQ(0, kTexSize - 1, color.R, color.G, color.B, color.A);
        EXPECT_PIXEL_EQ(kTexSize - 1, 0, color.R, color.G, color.B, color.A);
        EXPECT_PIXEL_EQ(kTexSize - 1, kTexSize - 1, color.R, color.G, color.B, color.A);

        EXPECT_EGL_TRUE(eglDestroyImageKHR(dpy, image));
        image = EGL_NO_IMAGE_KHR;

        EXPECT_EGL_TRUE(eglDestroySyncKHR(dpy, sync));
        sync = EGL_NO_SYNC_KHR;

        threadSynchronization.nextStep(Step::Finish);

        EXPECT_GL_NO_ERROR();
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_SUCCESS();
    });

    thread0.join();
    thread1.join();

    ASSERT_NE(currentStep, Step::Abort);

    // Clean up
    for (size_t t = 0; t < kThreadCount; ++t)
    {
        eglDestroySurface(dpy, surface[t]);
        eglDestroyContext(dpy, ctx[t]);
    }
}

// Tests mixing commands of Contexts with different Priorities in a single Command Buffers (Vulkan).
TEST_P(MultithreadingTestES3, ContextPriorityMixing)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_disjoint_timer_query"));

    constexpr size_t kIterationCountMax = 10;

    const bool reduceLoad       = isSwiftshader();
    const size_t iterationCount = reduceLoad ? 3 : kIterationCountMax;
    const size_t heavyDrawCount = reduceLoad ? 25 : 100;

    // Initialize contexts
    EGLWindow *window = getEGLWindow();
    EGLDisplay dpy    = window->getDisplay();
    EGLConfig config  = window->getConfig();

    // Large enough texture to catch timing problems.
    constexpr GLsizei kTexSize       = 1024;
    constexpr size_t kThreadCount    = 2;
    EGLSurface surface[kThreadCount] = {EGL_NO_SURFACE, EGL_NO_SURFACE};
    EGLContext ctx[kThreadCount]     = {EGL_NO_CONTEXT, EGL_NO_CONTEXT};

    EGLint priorities[kThreadCount] = {EGL_CONTEXT_PRIORITY_LOW_IMG, EGL_CONTEXT_PRIORITY_HIGH_IMG};

    EGLint pbufferAttributes[kThreadCount][6] = {
        {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE},
        {EGL_WIDTH, kTexSize, EGL_HEIGHT, kTexSize, EGL_NONE, EGL_NONE}};

    EGLint attributes[]     = {EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_NONE,
                               EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE, EGL_NONE, EGL_NONE};
    EGLint *extraAttributes = attributes;
    if (!IsEGLDisplayExtensionEnabled(dpy, "EGL_ANGLE_context_virtualization"))
    {
        attributes[2] = EGL_NONE;
    }
    if (!IsEGLDisplayExtensionEnabled(dpy, "EGL_IMG_context_priority"))
    {
        // Run tests with single priority anyway.
        extraAttributes += 2;
    }

    for (size_t t = 0; t < kThreadCount; ++t)
    {
        surface[t] = eglCreatePbufferSurface(dpy, config, pbufferAttributes[t]);
        EXPECT_EGL_SUCCESS();

        attributes[1] = priorities[t];
        attributes[3] = mVirtualizationGroup++;

        // Contexts not shared
        ctx[t] = window->createContext(EGL_NO_CONTEXT, extraAttributes);
        EXPECT_NE(EGL_NO_CONTEXT, ctx[t]);
    }

    // Synchronization tools to ensure the two threads are interleaved as designed by this test.
    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread1DrawColor,
        Thread0Iterate,
        Finish = Thread1DrawColor + kIterationCountMax * 2,
        Abort,
    };
    Step currentStep = Step::Start;

    auto makeStep = [](Step base, size_t i) {
        return static_cast<Step>(static_cast<size_t>(base) + i * 2);
    };

    // Triggers commands submission.
    std::thread thread0 = std::thread([&]() {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface[0], surface[0], ctx[0]));
        EXPECT_EGL_SUCCESS();

        ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());

        for (size_t i = 0; i < iterationCount; ++i)
        {
            ASSERT_TRUE(threadSynchronization.waitForStep(makeStep(Step::Thread1DrawColor, i)));

            glUseProgram(redProgram);
            drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
            ASSERT_GL_NO_ERROR();

            // This should perform commands submission.
            EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
            EXPECT_EGL_SUCCESS();

            threadSynchronization.nextStep(makeStep(Step::Thread0Iterate, i));

            EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface[0], surface[0], ctx[0]));
            EXPECT_EGL_SUCCESS();
        }

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

        EXPECT_GL_NO_ERROR();
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_SUCCESS();
    });

    // Render and then sample texture.
    std::thread thread1 = std::thread([&]() {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface[1], surface[1], ctx[1]));
        EXPECT_EGL_SUCCESS();

        glDisable(GL_DEPTH_TEST);
        glViewport(0, 0, kTexSize, kTexSize);

        GLTexture texture;
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);

        ANGLE_GL_PROGRAM(colorProgram, essl1_shaders::vs::Simple(),
                         essl1_shaders::fs::UniformColor());
        GLint colorLocation =
            glGetUniformLocation(colorProgram, angle::essl1_shaders::ColorUniform());
        ASSERT_NE(-1, colorLocation);

        ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(),
                         essl1_shaders::fs::Texture2D());

        for (size_t i = 0; i < iterationCount; ++i)
        {
            glBindFramebuffer(GL_FRAMEBUFFER, fbo);
            glUseProgram(colorProgram);

            GLuint query;
            glGenQueries(1, &query);
            glBeginQuery(GL_TIME_ELAPSED_EXT, query);
            ASSERT_GL_NO_ERROR();

            // Simulate heavy work...
            glUniform4f(colorLocation, 0.0f, 0.0f, 0.0f, 0.0f);
            for (size_t j = 0; j < heavyDrawCount; ++j)
            {
                drawQuad(colorProgram, essl1_shaders::PositionAttrib(), 0.5f);
            }

            // Draw with test color.
            GLColor color(i % 256, (i + 1) % 256, (i + 2) % 256, 255);
            Vector4 colorF = color.toNormalizedVector();
            glUniform4f(colorLocation, colorF.x(), colorF.y(), colorF.z(), colorF.w());
            drawQuad(colorProgram, essl1_shaders::PositionAttrib(), 0.5f);
            ASSERT_GL_NO_ERROR();

            // This should force "flushToPrimary()"
            glEndQuery(GL_TIME_ELAPSED_EXT);
            glDeleteQueries(1, &query);
            ASSERT_GL_NO_ERROR();

            threadSynchronization.nextStep(makeStep(Step::Thread1DrawColor, i));
            ASSERT_TRUE(threadSynchronization.waitForStep(makeStep(Step::Thread0Iterate, i)));

            glBindFramebuffer(GL_FRAMEBUFFER, 0);
            glUseProgram(textureProgram);

            // Should draw test color.
            drawQuad(textureProgram, essl1_shaders::PositionAttrib(), 0.5f);
            ASSERT_GL_NO_ERROR();

            // Check test color in four corners.
            EXPECT_PIXEL_EQ(0, 0, color.R, color.G, color.B, color.A);
            EXPECT_PIXEL_EQ(0, kTexSize - 1, color.R, color.G, color.B, color.A);
            EXPECT_PIXEL_EQ(kTexSize - 1, 0, color.R, color.G, color.B, color.A);
            EXPECT_PIXEL_EQ(kTexSize - 1, kTexSize - 1, color.R, color.G, color.B, color.A);
        }

        threadSynchronization.nextStep(Step::Finish);

        EXPECT_GL_NO_ERROR();
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_SUCCESS();
    });

    thread0.join();
    thread1.join();

    ASSERT_NE(currentStep, Step::Abort);

    // Clean up
    for (size_t t = 0; t < kThreadCount; ++t)
    {
        eglDestroySurface(dpy, surface[t]);
        eglDestroyContext(dpy, ctx[t]);
    }
}

// Test that it is possible to upload textures in one thread and use them in another with
// synchronization.
TEST_P(MultithreadingTestES3, MultithreadedTextureUploadAndDraw)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    constexpr size_t kTexSize = 4;
    GLTexture texture1;
    GLTexture texture2;
    std::vector<GLColor> textureColors1(kTexSize * kTexSize, GLColor::red);
    std::vector<GLColor> textureColors2(kTexSize * kTexSize, GLColor::green);

    // Sync primitives
    GLsync sync = nullptr;
    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0UploadFinish,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    // Threads to upload and draw with textures.
    auto thread0Upload = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Start));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Two mipmap textures are defined here. They are used for drawing in the other thread.
        glBindTexture(GL_TEXTURE_2D, texture1);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     textureColors1.data());
        glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, textureColors1.data());
        glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kTexSize / 4, kTexSize / 4, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, textureColors1.data());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        ASSERT_GL_NO_ERROR();

        glBindTexture(GL_TEXTURE_2D, texture2);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     textureColors2.data());
        glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, textureColors2.data());
        glTexImage2D(GL_TEXTURE_2D, 2, GL_RGBA8, kTexSize / 4, kTexSize / 4, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, textureColors2.data());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        ASSERT_GL_NO_ERROR();

        // Create a sync object to be used for the draw thread.
        sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        glFlush();
        ASSERT_NE(sync, nullptr);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Thread0UploadFinish);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
    };

    auto thread1Draw = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0UploadFinish));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Wait for the sync object to be signaled.
        glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
        ASSERT_GL_NO_ERROR();

        // Draw using the textures from the texture upload thread.
        ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture2D(),
                         essl1_shaders::fs::Texture2D());
        glUseProgram(textureProgram);

        glBindTexture(GL_TEXTURE_2D, texture1);
        drawQuad(textureProgram, essl1_shaders::PositionAttrib(), 0.5f);
        glFlush();
        ASSERT_GL_NO_ERROR();
        EXPECT_PIXEL_RECT_EQ(0, 0, kTexSize, kTexSize, GLColor::red);

        glBindTexture(GL_TEXTURE_2D, texture2);
        drawQuad(textureProgram, essl1_shaders::PositionAttrib(), 0.5f);
        glFlush();
        ASSERT_GL_NO_ERROR();
        EXPECT_PIXEL_RECT_EQ(0, 0, kTexSize, kTexSize, GLColor::green);

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Finish);
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0Upload),
        std::move(thread1Draw),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Test that it is possible to create a new context after uploading mutable mipmap textures in the
// previous context, and use them in the new context.
TEST_P(MultithreadingTestES3, CreateNewContextAfterTextureUploadOnNewThread)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    constexpr size_t kTexSize = 4;
    GLTexture texture1;
    GLTexture texture2;
    std::vector<GLColor> textureColors1(kTexSize * kTexSize, GLColor::red);
    std::vector<GLColor> textureColors2(kTexSize * kTexSize, GLColor::green);

    EGLWindow *window = getEGLWindow();
    EGLDisplay dpy    = window->getDisplay();

    std::thread thread = std::thread([&]() {
        // Create a context and upload the textures.
        EGLContext ctx1 = createMultithreadedContext(window, EGL_NO_CONTEXT);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx1));

        glBindTexture(GL_TEXTURE_2D, texture1);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     textureColors1.data());
        glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, textureColors1.data());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        ASSERT_GL_NO_ERROR();

        glBindTexture(GL_TEXTURE_2D, texture2);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     textureColors2.data());
        glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, textureColors2.data());
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        ASSERT_GL_NO_ERROR();

        // Create a new context and use the uploaded textures.
        EGLContext ctx2 = createMultithreadedContext(window, ctx1);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx2));

        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture1, 0);
        EXPECT_PIXEL_RECT_EQ(0, 0, kTexSize, kTexSize, GLColor::red);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
        EXPECT_PIXEL_RECT_EQ(0, 0, kTexSize, kTexSize, GLColor::green);

        // Destroy the contexts.
        EXPECT_EGL_TRUE(eglDestroyContext(dpy, ctx2));
        EXPECT_EGL_TRUE(eglDestroyContext(dpy, ctx1));
    });

    thread.join();
}

// Test that it is possible to create a new context after uploading mutable mipmap textures in the
// main thread, and use them in the new context.
TEST_P(MultithreadingTestES3, CreateNewContextAfterTextureUploadOnMainThread)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    EGLWindow *window = getEGLWindow();
    EGLDisplay dpy    = window->getDisplay();

    // Upload the textures.
    constexpr size_t kTexSize = 4;
    GLTexture texture1;
    GLTexture texture2;
    std::vector<GLColor> textureColors1(kTexSize * kTexSize, GLColor::red);
    std::vector<GLColor> textureColors2(kTexSize * kTexSize, GLColor::green);

    glBindTexture(GL_TEXTURE_2D, texture1);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 textureColors1.data());
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, textureColors1.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();

    glBindTexture(GL_TEXTURE_2D, texture2);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 textureColors2.data());
    glTexImage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kTexSize / 2, kTexSize / 2, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, textureColors2.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    ASSERT_GL_NO_ERROR();

    GLsync sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

    std::thread thread = std::thread([&]() {
        // Create a context.
        EGLContext ctx1 = createMultithreadedContext(window, window->getContext());
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, ctx1));

        // Wait for the sync object to be signaled.
        glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);
        ASSERT_GL_NO_ERROR();

        // Use the uploaded textures in the main thread.
        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture1, 0);
        EXPECT_PIXEL_RECT_EQ(0, 0, kTexSize, kTexSize, GLColor::red);

        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture2, 0);
        EXPECT_PIXEL_RECT_EQ(0, 0, kTexSize, kTexSize, GLColor::green);

        // Destroy the context.
        EXPECT_EGL_TRUE(eglDestroyContext(dpy, ctx1));

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    });

    thread.join();
}

// Test when lots of upload happens on a different thread at the same time as the main thread doing
// draws.
TEST_P(MultithreadingTestES3, SimultaneousUploadAndDraw)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    // The following shader is used to create busy work while the worker thread is doing something.
    // It intentionally spreads its uniforms and inputs so the main thread has to make many GL
    // calls.
    constexpr char kBusyDrawVS[] = R"(#version 300 es
uniform mediump float x0;
uniform mediump float y0;
uniform mediump float x1;
uniform mediump float y1;

in mediump float r;
in mediump float g;
in mediump float b;
in mediump float a;

out mediump vec4 color;

void main()
{
    // gl_VertexID    x    y
    //      0        -1   -1
    //      1         1   -1
    //      2        -1    1
    //      3         1    1
    int bit0 = gl_VertexID & 1;
    int bit1 = gl_VertexID >> 1;
    gl_Position.x = bit0 == 0 ? x0 : x1;
    gl_Position.y = bit1 == 0 ? y0 : y1;
    gl_Position.z = 0.;
    gl_Position.w = 1.;

    color = vec4(r, g, b, a);
})";
    constexpr char kBusyDrawFS[] = R"(#version 300 es

in mediump vec4 color;
out mediump vec4 colorOut;

void main()
{
    colorOut = color;
})";

    // The following shader is used to consume the results of texture uploads, ensuring appropriate
    // synchronization.
    constexpr char kTextureDrawVS[] = R"(#version 300 es
out mediump vec2 uv;

void main()
{
    // gl_VertexID    x    y
    //      0        -1   -1
    //      1         1   -1
    //      2        -1    1
    //      3         1    1
    int bit0 = gl_VertexID & 1;
    int bit1 = gl_VertexID >> 1;
    gl_Position = vec4(bit0 * 2 - 1, bit1 * 2 - 1, 0, 1);
    uv = vec2(bit0, bit1);
})";
    constexpr char kTextureDrawFS[] = R"(#version 300 es

uniform mediump sampler2D s0;
uniform mediump sampler2D s1;
uniform mediump sampler2D s2;
uniform mediump sampler2D s3;
uniform mediump sampler2D s4;
uniform mediump sampler2D s5;
uniform mediump sampler2D s6;
uniform mediump sampler2D s7;
uniform mediump sampler2D s8;
uniform mediump sampler2D s9;

in mediump vec2 uv;
out mediump vec4 colorOut;

void main()
{
    highp vec4 result = texture(s0, uv) +
                        texture(s1, uv) +
                        texture(s2, uv) +
                        texture(s3, uv) +
                        texture(s4, uv) +
                        texture(s5, uv) +
                        texture(s6, uv) +
                        texture(s7, uv) +
                        texture(s8, uv) +
                        texture(s9, uv);
    result /= 10.;

    colorOut = result;
})";

    constexpr uint32_t kTextureCount = 10;
    GLuint textures[kTextureCount];

    ASSERT(IsGLExtensionEnabled("GL_KHR_texture_compression_astc_ldr") ||
           IsGLExtensionEnabled("GL_EXT_texture_compression_bptc"));
    // Note ASTC may be emulated in ANGLE, so check for BPTC first
    const bool hasBPTC = IsGLExtensionEnabled("GL_EXT_texture_compression_bptc");
    const GLenum compressedFormat =
        hasBPTC ? GL_COMPRESSED_RGBA_BPTC_UNORM_EXT : GL_COMPRESSED_RGBA_ASTC_4x4_KHR;

    std::vector<uint8_t> textureData[kTextureCount];

    constexpr int kSurfaceWidth  = 256;
    constexpr int kSurfaceHeight = 512;
    constexpr int kTexSize       = 1024;

    // Sync primitives
    GLsync sync = nullptr;
    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread1Ready,
        Thread0UploadFinish,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    // Threads to upload and draw with textures.
    auto thread0Upload = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Wait for the other thread to set everything up
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Ready));

        // Perform uploads while the other thread does draws
        for (uint32_t i = 0; i < kTextureCount; ++i)
        {
            glBindTexture(GL_TEXTURE_2D, textures[i]);
            glCompressedTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, kTexSize, kTexSize, compressedFormat,
                                      static_cast<GLsizei>(textureData[i].size()),
                                      textureData[i].data());
        }
        ASSERT_GL_NO_ERROR();

        // Create a sync object to be used for the draw thread.
        sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        ASSERT_NE(sync, nullptr);
        ASSERT_GL_NO_ERROR();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Thread0UploadFinish);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
    };

    auto thread1Draw = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        ANGLE_GL_PROGRAM(busyDrawProgram, kBusyDrawVS, kBusyDrawFS);

        // Set up the test.  Don't let the other thread work yet.
        glUseProgram(busyDrawProgram);
        GLuint busyDrawX0Loc = glGetUniformLocation(busyDrawProgram, "x0");
        GLuint busyDrawY0Loc = glGetUniformLocation(busyDrawProgram, "y0");
        GLuint busyDrawX1Loc = glGetUniformLocation(busyDrawProgram, "x1");
        GLuint busyDrawY1Loc = glGetUniformLocation(busyDrawProgram, "y1");
        GLuint busyDrawRLoc  = glGetAttribLocation(busyDrawProgram, "r");
        GLuint busyDrawGLoc  = glGetAttribLocation(busyDrawProgram, "g");
        GLuint busyDrawBLoc  = glGetAttribLocation(busyDrawProgram, "b");
        GLuint busyDrawALoc  = glGetAttribLocation(busyDrawProgram, "a");

        ANGLE_GL_PROGRAM(textureDrawProgram, kTextureDrawVS, kTextureDrawFS);
        GLuint textureDrawSamplerLoc[kTextureCount] = {};

        glUseProgram(textureDrawProgram);
        glGenTextures(kTextureCount, textures);
        for (uint32_t i = 0; i < kTextureCount; ++i)
        {
            std::ostringstream name;
            name << "s" << i;

            textureDrawSamplerLoc[i] = glGetUniformLocation(textureDrawProgram, name.str().c_str());

            glBindTexture(GL_TEXTURE_2D, textures[i]);
            glTexStorage2D(GL_TEXTURE_2D, 1, compressedFormat, kTexSize, kTexSize);

            // Both ASTC 4x4 and BPTC have 1 byte per pixel.  The textures' contents are arbitrary
            // but distinct.
            textureData[i].resize(kTexSize * kTexSize);
            for (int y = 0; y < kTexSize; ++y)
            {
                for (int x = 0; x < kTexSize; ++x)
                {
                    textureData[i][y * kTexSize + x] = (i * 50 + y + x) % 255;
                }
            }
        }
        ASSERT_GL_NO_ERROR();

        // Now that everything is set up, let the upload thread work while this thread does draws.
        threadSynchronization.nextStep(Step::Thread1Ready);

        int w = kSurfaceWidth;
        int h = kSurfaceHeight;

        glClear(GL_COLOR_BUFFER_BIT);
        glViewport(0, 0, w, h);
        glUseProgram(busyDrawProgram);
        for (uint32_t y = 0; y < 8; ++y)
        {
            for (uint32_t x = 0; x < 8; ++x)
            {
                float width  = w / 4;
                float height = h / 8;

                glUniform1f(busyDrawX0Loc, x * width / w - 1);
                glUniform1f(busyDrawY0Loc, y * height / h);
                glUniform1f(busyDrawX1Loc, (x + 1) * width / w - 1);
                glUniform1f(busyDrawY1Loc, (y + 1) * height / h);

                glVertexAttrib1f(busyDrawRLoc, x / 8.0f);
                glVertexAttrib1f(busyDrawGLoc, y / 8.0f);
                glVertexAttrib1f(busyDrawBLoc, 0);
                glVertexAttrib1f(busyDrawALoc, 1);

                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
            }
        }
        ASSERT_GL_NO_ERROR();

        // Wait for the other thread to finish with uploads.
        threadSynchronization.waitForStep(Step::Thread0UploadFinish);

        // Wait for fence and use all textures in a draw.
        glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);

        glUseProgram(textureDrawProgram);
        for (uint32_t i = 0; i < kTextureCount; ++i)
        {
            glActiveTexture(GL_TEXTURE0 + i);
            glBindTexture(GL_TEXTURE_2D, textures[i]);
            glUniform1i(textureDrawSamplerLoc[i], i);
        }
        glViewport(0, 0, w, h / 2);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
        ASSERT_GL_NO_ERROR();

        threadSynchronization.nextStep(Step::Finish);

        // Verify results
        for (uint32_t y = 0; y < 8; ++y)
        {
            for (uint32_t x = 0; x < 8; ++x)
            {
                int width  = w / 8;
                int height = h / 16;

                EXPECT_PIXEL_COLOR_NEAR(x * width + width / 2, h - (y * height + height / 2),
                                        GLColor(x * 255 / 8, (7 - y) * 255 / 8, 0, 255), 1);
            }
        }
        ASSERT_GL_NO_ERROR();

        for (uint32_t x = 0; x < 8; ++x)
        {
            // The compressed data is gibberish, just ensure it's not all black.
            EXPECT_PIXEL_NE(x * w / 8, h / 4, 0, 0, 0, 0);
        }
        ASSERT_GL_NO_ERROR();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0Upload),
        std::move(thread1Draw),
    };

    RunLockStepThreadsWithSize(getEGLWindow(), kSurfaceWidth, kSurfaceHeight, threadFuncs.size(),
                               threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Test that calling glUniformBlockBinding on one context affects all contexts.
TEST_P(MultithreadingTestES3, UniformBlockBinding)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    constexpr char kVS[] = R"(#version 300 es
void main()
{
    vec2 pos = vec2(0.0);
    switch (gl_VertexID) {
        case 0: pos = vec2(-1.0, -1.0); break;
        case 1: pos = vec2(3.0, -1.0); break;
        case 2: pos = vec2(-1.0, 3.0); break;
    };
    gl_Position = vec4(pos, 0.0, 1.0);
})";
    constexpr char kFS[] = R"(#version 300 es
out mediump vec4 colorOut;

layout(std140) uniform buffer { mediump vec4 color; };

void main()
{
    colorOut = color;
})";

    GLProgram program;
    GLint uniformBufferIndex;

    // Sync primitives
    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread1Ready,
        Thread0BindingChanged,
        Thread1FinishedDrawing,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    // Threads to create programs and draw with different uniform blocks.
    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Create buffers bound to bindings 1 and 2
        constexpr std::array<float, 4> kRed              = {1, 0, 0, 1};
        constexpr std::array<float, 4> kTransparentGreen = {0, 1, 0, 0};
        GLBuffer red, transparentGreen;
        glBindBuffer(GL_UNIFORM_BUFFER, red);
        glBufferData(GL_UNIFORM_BUFFER, sizeof(kRed), kRed.data(), GL_STATIC_DRAW);
        glBindBuffer(GL_UNIFORM_BUFFER, transparentGreen);
        glBufferData(GL_UNIFORM_BUFFER, sizeof(kTransparentGreen), kTransparentGreen.data(),
                     GL_STATIC_DRAW);

        glBindBufferBase(GL_UNIFORM_BUFFER, 1, transparentGreen);
        glBindBufferBase(GL_UNIFORM_BUFFER, 2, red);

        // Wait for the other thread to set everything up
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Ready));

        // Issue a draw call.  The buffer should be transparent green now
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT);
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);

        glUseProgram(program);
        glDrawArrays(GL_TRIANGLES, 0, 3);

        // Change the binding
        glUniformBlockBinding(program, uniformBufferIndex, 1);
        ASSERT_GL_NO_ERROR();

        // Let the other thread work before any deferred operations for the binding change above are
        // processed in this context.
        threadSynchronization.nextStep(Step::Thread0BindingChanged);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1FinishedDrawing));

        // Draw again, it should accumulate blue and the buffer should become magenta.
        glDrawArrays(GL_TRIANGLES, 0, 3);

        // Verify results
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::yellow);
        ASSERT_GL_NO_ERROR();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Finish);
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Create buffers bound to bindings 1 and 2
        constexpr std::array<float, 4> kBlue           = {0, 0, 1, 1};
        constexpr std::array<float, 4> kTransparentRed = {1, 0, 0, 0};
        GLBuffer blue, transparentRed;
        glBindBuffer(GL_UNIFORM_BUFFER, blue);
        glBufferData(GL_UNIFORM_BUFFER, sizeof(kBlue), kBlue.data(), GL_STATIC_DRAW);
        glBindBuffer(GL_UNIFORM_BUFFER, transparentRed);
        glBufferData(GL_UNIFORM_BUFFER, sizeof(kTransparentRed), kTransparentRed.data(),
                     GL_STATIC_DRAW);

        glBindBufferBase(GL_UNIFORM_BUFFER, 1, blue);
        glBindBufferBase(GL_UNIFORM_BUFFER, 2, transparentRed);

        // Create the program
        program.makeRaster(kVS, kFS);
        glUseProgram(program);
        uniformBufferIndex = glGetUniformBlockIndex(program, "buffer");

        // Configure the buffer binding to binding 2
        glUniformBlockBinding(program, uniformBufferIndex, 2);
        ASSERT_GL_NO_ERROR();

        // Issue a draw call.  The buffer should be transparent red now
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT);
        glEnable(GL_BLEND);
        glBlendFunc(GL_ONE, GL_ONE);

        glDrawArrays(GL_TRIANGLES, 0, 3);

        // Now that everything is set up, let the other thread continue
        threadSynchronization.nextStep(Step::Thread1Ready);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0BindingChanged));

        // The other thread has changed the binding.  Draw again, it should accumulate blue and the
        // buffer should become magenta.
        glDrawArrays(GL_TRIANGLES, 0, 3);

        // Verify results
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::magenta);
        ASSERT_GL_NO_ERROR();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        // Tell the other thread to finish up.
        threadSynchronization.nextStep(Step::Thread1FinishedDrawing);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Test that observers are notified of a change in foveation state of a texture
TEST_P(MultithreadingTestES3, SharedFoveatedTexture)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_QCOM_texture_foveated"));

    // Shared texture
    GLTexture texture;

    // Sync primitives
    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0Draw,
        Thread1Draw,
        Thread0ConfiguredTextureFoveation,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    // Thread to configure texture foveation.
    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Create non-foveated framebuffer and attach shared texture as color attachment
        GLFramebuffer framebuffer;
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, nullptr);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        EXPECT_GL_NO_ERROR();
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        ASSERT_GL_NO_ERROR();
        EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Render before configuring foveation on the texture
        ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
        glUseProgram(greenProgram);

        // Draw
        drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_GL_NO_ERROR();

        // Verify results
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
        ASSERT_GL_NO_ERROR();

        threadSynchronization.nextStep(Step::Thread0Draw);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Draw));

        // Configure foveation for the texture
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM,
                        GL_FOVEATION_ENABLE_BIT_QCOM);
        EXPECT_GL_NO_ERROR();
        glTextureFoveationParametersQCOM(texture, 0, 0, 0.0f, 0.0f, 8.0f, 8.0f, 0.0f);
        EXPECT_GL_NO_ERROR();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Thread0ConfiguredTextureFoveation);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Draw));

        // Create non-foveated framebuffer and attach shared texture as color attachment
        GLFramebuffer framebuffer;
        glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
        ASSERT_GL_NO_ERROR();
        EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);

        // Render before configuring foveation on the texture
        ANGLE_GL_PROGRAM(redProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
        glUseProgram(redProgram);

        // Draw
        drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_GL_NO_ERROR();

        // Verify results
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
        ASSERT_GL_NO_ERROR();

        threadSynchronization.nextStep(Step::Thread1Draw);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0ConfiguredTextureFoveation));

        // Render after texture foveation was configured
        ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
        glUseProgram(blueProgram);

        // Draw
        drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_GL_NO_ERROR();

        // Verify results
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);
        ASSERT_GL_NO_ERROR();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Finish);
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Test GL_EXT_sRGB_write_control works as expected when multiple contexts are used
TEST_P(MultithreadingTestES3, SharedSrgbTextureMultipleContexts)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_sRGB_write_control"));

    constexpr angle::GLColor encodedToSrgbColor(64, 127, 191, 255);
    constexpr angle::GLColor inputColor(13, 54, 133, 255);

    EGLWindow *window   = getEGLWindow();
    EGLDisplay dpy      = window->getDisplay();
    EGLContext context1 = window->createContext(EGL_NO_CONTEXT, nullptr);
    EGLContext context2 = window->createContext(context1, nullptr);

    // Shared texture
    GLTexture texture;

    // Shared program
    GLuint program;

    // Sync primitives
    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0Draw1,
        Thread1Draw1,
        Thread0Draw2,
        Thread1Draw2,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    // Thread0 rendering to shared texture.
    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context1));
        EXPECT_EGL_SUCCESS();

        glBindTexture(GL_TEXTURE_2D, texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, 1, 1, 0, GL_SRGB_ALPHA_EXT,
                     GL_UNSIGNED_BYTE, nullptr);

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

        program = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
        ASSERT_NE(0u, program);

        GLint colorLocation = glGetUniformLocation(program, essl1_shaders::ColorUniform());
        ASSERT_NE(-1, colorLocation);

        glUseProgram(program);
        glUniform4fv(colorLocation, 1, inputColor.toNormalizedVector().data());

        glDisable(GL_FRAMEBUFFER_SRGB_EXT);
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_PIXEL_COLOR_NEAR(0, 0, inputColor, 1.0);

        threadSynchronization.nextStep(Step::Thread0Draw1);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Draw1));

        glEnable(GL_FRAMEBUFFER_SRGB_EXT);
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_PIXEL_COLOR_NEAR(0, 0, encodedToSrgbColor, 1.0);

        threadSynchronization.nextStep(Step::Thread0Draw2);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Draw2));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_SUCCESS();

        threadSynchronization.nextStep(Step::Finish);
    };

    // Thread1 rendering to shared texture.
    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context2));
        EXPECT_EGL_SUCCESS();

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Draw1));

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

        ASSERT_NE(0u, program);
        GLint colorLocation = glGetUniformLocation(program, essl1_shaders::ColorUniform());
        ASSERT_NE(-1, colorLocation);

        glUseProgram(program);
        glUniform4fv(colorLocation, 1, inputColor.toNormalizedVector().data());

        drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_PIXEL_COLOR_NEAR(0, 0, encodedToSrgbColor, 1.0);

        threadSynchronization.nextStep(Step::Thread1Draw1);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Draw2));

        glBindTexture(GL_TEXTURE_2D, texture);
        glDisable(GL_FRAMEBUFFER_SRGB_EXT);
        drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_PIXEL_COLOR_NEAR(0, 0, inputColor, 1.0);

        threadSynchronization.nextStep(Step::Thread1Draw2);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_SUCCESS();
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    // Cleanup
    EXPECT_EGL_TRUE(eglDestroyContext(dpy, context1));
    EXPECT_EGL_TRUE(eglDestroyContext(dpy, context2));
    EXPECT_EGL_SUCCESS();

    ASSERT_NE(currentStep, Step::Abort);
}

// Test that a program linked in one context can be bound in another context while link may be
// happening in parallel.
TEST_P(MultithreadingTest, ProgramLinkAndBind)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    GLuint vs;
    GLuint redfs;
    GLuint greenfs;

    GLuint program;

    // Sync primitives
    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread1Ready,
        Thread0ProgramLinked,
        Thread1FinishedDrawing,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    // Threads to create programs and draw.
    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        // Wait for thread 1 to bind the program before linking it
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Ready));

        glUseProgram(program);

        // Link a program, but don't resolve link.
        glDetachShader(program, greenfs);
        glAttachShader(program, redfs);
        glLinkProgram(program);

        // Let the other thread bind and use the program.
        threadSynchronization.nextStep(Step::Thread0ProgramLinked);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1FinishedDrawing));

        // Draw in this context too
        drawQuad(program, essl1_shaders::PositionAttrib(), 0);

        // Verify results
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
        ASSERT_GL_NO_ERROR();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Finish);
    };

    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        vs      = CompileShader(GL_VERTEX_SHADER, essl1_shaders::vs::Simple());
        redfs   = CompileShader(GL_FRAGMENT_SHADER, essl1_shaders::fs::Red());
        greenfs = CompileShader(GL_FRAGMENT_SHADER, essl1_shaders::fs::Green());
        program = glCreateProgram();

        glAttachShader(program, vs);
        glAttachShader(program, greenfs);
        glLinkProgram(program);
        ASSERT_NE(CheckLinkStatusAndReturnProgram(program, true), 0u);

        // Bind the program before it's relinked.  Otherwise the program is resolved before the
        // binding happens.
        glUseProgram(program);

        threadSynchronization.nextStep(Step::Thread1Ready);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0ProgramLinked));

        // Unbind and rebind for extra testing
        glUseProgram(0);
        glUseProgram(program);

        // Issue a draw call
        drawQuad(program, essl1_shaders::PositionAttrib(), 0);

        // Verify results
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
        ASSERT_GL_NO_ERROR();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        // Tell the other thread to finish up.
        threadSynchronization.nextStep(Step::Thread1FinishedDrawing);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreads(getEGLWindow(), threadFuncs.size(), threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Test that two contexts in share group can generate, delete and bind buffers for themselves in
// parallel.
TEST_P(MultithreadingTestES3, SimultaneousBufferBindAndGen)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    constexpr char kFS[] = R"(#version 300 es
precision mediump float;

layout(std140) uniform Block
{
    vec4 colorIn;
};

out vec4 color;

void main()
{
    color = colorIn;
})";

    constexpr int kSurfaceWidth  = 32;
    constexpr int kSurfaceHeight = 128;

    // Sync primitives
    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0Ready,
        Thread1Ready,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto threadFunc = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context, uint32_t index) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);

        // Make sure the two threads start work around the same time
        if (index == 0)
        {
            threadSynchronization.nextStep(Step::Thread0Ready);
            ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Ready));
        }
        else
        {
            ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Ready));
            threadSynchronization.nextStep(Step::Thread1Ready);
        }

        std::vector<GLuint> buffers(kSurfaceWidth * kSurfaceHeight);

        glEnable(GL_SCISSOR_TEST);
        for (int y = 0; y < kSurfaceHeight; ++y)
        {
            for (int x = 0; x < kSurfaceWidth; ++x)
            {
                GLuint &buffer            = buffers[y * kSurfaceWidth + x];
                const float bufferData[4] = {
                    ((y * kSurfaceWidth + x + index * 100) % 255) / 255.0f,
                    ((y * kSurfaceWidth + x + index * 100 + 1) % 255) / 255.0f,
                    ((y * kSurfaceWidth + x + index * 100 + 2) % 255) / 255.0f,
                    ((y * kSurfaceWidth + x + index * 100 + 3) % 255) / 255.0f,
                };

                // Generate one buffer per pixel and shade the pixel with it.
                glGenBuffers(1, &buffer);
                glBindBuffer(GL_UNIFORM_BUFFER, buffers[y * kSurfaceWidth + x]);
                glBufferData(GL_UNIFORM_BUFFER, sizeof(bufferData), bufferData, GL_STATIC_DRAW);
                glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);

                glScissor(x, y, 1, 1);
                drawQuad(program, essl3_shaders::PositionAttrib(), 0);

                if ((x + y) % 2 == 0)
                {
                    glDeleteBuffers(1, &buffer);
                    buffer = 0;
                }
            }
        }

        // Verify the results
        auto verify = [&](int x, int y) {
            const GLColor expect((y * kSurfaceWidth + x + index * 100) % 255,
                                 (y * kSurfaceWidth + x + index * 100 + 1) % 255,
                                 (y * kSurfaceWidth + x + index * 100 + 2) % 255,
                                 (y * kSurfaceWidth + x + index * 100 + 3) % 255);
            EXPECT_PIXEL_COLOR_EQ(x, y, expect);
        };

        verify(0, 0);
        verify(0, kSurfaceHeight - 1);
        verify(kSurfaceWidth - 1, 0);
        verify(kSurfaceWidth - 1, kSurfaceHeight - 1);
        verify(kSurfaceWidth / 2, kSurfaceHeight / 2);
        ASSERT_GL_NO_ERROR();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        if (index == 0)
        {
            threadSynchronization.nextStep(Step::Finish);
        }
        else
        {
            ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
        }
    };

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        threadFunc(dpy, surface, context, 0);
    };
    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        threadFunc(dpy, surface, context, 1);
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreadsWithSize(getEGLWindow(), kSurfaceWidth, kSurfaceHeight, threadFuncs.size(),
                               threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

// Test that ref counting is thread-safe when the same buffer is used in multiple threads.
TEST_P(MultithreadingTestES3, SimultaneousBufferBind)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());

    constexpr char kFS[] = R"(#version 300 es
precision mediump float;

layout(std140) uniform Block
{
    vec4 colorIn;
};

out vec4 color;

void main()
{
    color = colorIn;
})";

    constexpr int kSurfaceWidth  = 32;
    constexpr int kSurfaceHeight = 128;

    GLuint buffer;
    GLsync sync = nullptr;

    // Sync primitives
    std::mutex mutex;
    std::condition_variable condVar;

    enum class Step
    {
        Start,
        Thread0Ready,
        Thread1Ready,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

    auto thread0 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);

        // Create the buffer in this context
        glGenBuffers(1, &buffer);

        constexpr float kBufferData[4] = {
            10.0f / 255.0f,
            50.0f / 255.0f,
            130.0f / 255.0f,
            220.0f / 255.0f,
        };
        glBindBuffer(GL_UNIFORM_BUFFER, buffer);
        glBufferData(GL_UNIFORM_BUFFER, sizeof(kBufferData), kBufferData, GL_STATIC_DRAW);

        sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);

        // Make sure the two threads start work around the same time
        threadSynchronization.nextStep(Step::Thread0Ready);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Ready));

        // Bind and unbind the buffer many times.  If ref counting is not thread safe, chances are
        // the ref count would be incorrect in the end.  This can result in the buffer prematurely
        // getting deleted.
        for (uint32_t i = 0; i < 8000; ++i)
        {
            glBindBuffer(GL_UNIFORM_BUFFER, i % 2 == 0 ? 0 : buffer);
        }
        ASSERT_GL_NO_ERROR();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        threadSynchronization.nextStep(Step::Finish);
    };
    auto thread1 = [&](EGLDisplay dpy, EGLSurface surface, EGLContext context) {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, surface, surface, context));

        ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), kFS);

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Ready));
        threadSynchronization.nextStep(Step::Thread1Ready);

        glWaitSync(sync, 0, GL_TIMEOUT_IGNORED);

        // Bind and unbind the buffer many times.
        for (uint32_t i = 0; i < 4000; ++i)
        {
            glBindBuffer(GL_UNIFORM_BUFFER, i % 2 == 0 ? buffer : 0);
        }

        // Draw with it to make sure buffer is still valid and not accidentally deleted due to bad
        // ref counting.
        glBindBuffer(GL_UNIFORM_BUFFER, buffer);
        glBindBufferBase(GL_UNIFORM_BUFFER, 0, buffer);
        drawQuad(program, essl3_shaders::PositionAttrib(), 0);

        // Verify the results
        const GLColor expect(10, 50, 130, 220);
        EXPECT_PIXEL_RECT_EQ(0, 0, kSurfaceWidth, kSurfaceHeight, expect);
        ASSERT_GL_NO_ERROR();

        // Clean up
        EXPECT_EGL_TRUE(eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
    };

    std::array<LockStepThreadFunc, 2> threadFuncs = {
        std::move(thread0),
        std::move(thread1),
    };

    RunLockStepThreadsWithSize(getEGLWindow(), kSurfaceWidth, kSurfaceHeight, threadFuncs.size(),
                               threadFuncs.data());

    ASSERT_NE(currentStep, Step::Abort);
}

ANGLE_INSTANTIATE_TEST(
    MultithreadingTest,
    ES2_METAL(),
    ES3_METAL(),
    ES2_OPENGL(),
    ES3_OPENGL(),
    ES2_OPENGLES(),
    ES3_OPENGLES(),
    ES3_VULKAN(),
    ES3_VULKAN_SWIFTSHADER().enable(Feature::PreferMonolithicPipelinesOverLibraries),
    ES3_VULKAN_SWIFTSHADER()
        .enable(Feature::PreferMonolithicPipelinesOverLibraries)
        .enable(Feature::SlowDownMonolithicPipelineCreationForTesting),
    ES3_VULKAN_SWIFTSHADER()
        .enable(Feature::PreferMonolithicPipelinesOverLibraries)
        .disable(Feature::MergeProgramPipelineCachesToGlobalCache),
    ES3_VULKAN_SWIFTSHADER().enable(Feature::PermanentlySwitchToFramebufferFetchMode),
    ES3_VULKAN_SWIFTSHADER()
        .enable(Feature::PermanentlySwitchToFramebufferFetchMode)
        .enable(Feature::PreferMonolithicPipelinesOverLibraries),
    ES3_VULKAN_SWIFTSHADER()
        .enable(Feature::PermanentlySwitchToFramebufferFetchMode)
        .enable(Feature::PreferMonolithicPipelinesOverLibraries)
        .enable(Feature::SlowDownMonolithicPipelineCreationForTesting),
    ES2_D3D11(),
    ES3_D3D11());

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(MultithreadingTestES3);
ANGLE_INSTANTIATE_TEST(
    MultithreadingTestES3,
    ES3_OPENGL(),
    ES3_OPENGLES(),
    ES3_VULKAN(),
    ES3_VULKAN_SWIFTSHADER().enable(Feature::PreferMonolithicPipelinesOverLibraries),
    ES3_VULKAN_SWIFTSHADER()
        .enable(Feature::PreferMonolithicPipelinesOverLibraries)
        .enable(Feature::SlowDownMonolithicPipelineCreationForTesting),
    ES3_VULKAN_SWIFTSHADER()
        .enable(Feature::PreferMonolithicPipelinesOverLibraries)
        .disable(Feature::MergeProgramPipelineCachesToGlobalCache),
    ES3_VULKAN_SWIFTSHADER().enable(Feature::PermanentlySwitchToFramebufferFetchMode),
    ES3_VULKAN_SWIFTSHADER()
        .enable(Feature::PermanentlySwitchToFramebufferFetchMode)
        .enable(Feature::PreferMonolithicPipelinesOverLibraries),
    ES3_VULKAN_SWIFTSHADER()
        .enable(Feature::PermanentlySwitchToFramebufferFetchMode)
        .enable(Feature::PreferMonolithicPipelinesOverLibraries)
        .enable(Feature::SlowDownMonolithicPipelineCreationForTesting),
    ES3_D3D11());

}  // namespace angle
