//
// Copyright 2016 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.
//
// EGLContextSharingTest.cpp:
//   Tests relating to shared Contexts.

#include <gtest/gtest.h>
#include "common/unsafe_buffers.h"

#include <array>

#include "common/tls.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/MultiThreadSteps.h"
#include "test_utils/angle_test_configs.h"
#include "test_utils/gl_raii.h"
#include "util/EGLWindow.h"
#include "util/OSWindow.h"
#include "util/test_utils.h"

using namespace angle;

namespace
{

EGLBoolean SafeDestroyContext(EGLDisplay display, EGLContext &context)
{
    EGLBoolean result = EGL_TRUE;
    if (context != EGL_NO_CONTEXT)
    {
        result  = eglDestroyContext(display, context);
        context = EGL_NO_CONTEXT;
    }
    return result;
}

class EGLContextSharingTest : public ANGLETest<>
{
  public:
    EGLContextSharingTest() : mContexts{EGL_NO_CONTEXT, EGL_NO_CONTEXT}, mTexture(0) {}

    void testTearDown() override
    {
        glDeleteTextures(1, &mTexture);

        EGLDisplay display = getEGLWindow()->getDisplay();

        if (display != EGL_NO_DISPLAY)
        {
            for (auto &context : mContexts)
            {
                SafeDestroyContext(display, context);
            }
        }

        // Set default test state to not give an error on shutdown.
        getEGLWindow()->makeCurrent();
    }

    bool chooseConfig(EGLDisplay dpy, EGLConfig *config) const
    {
        bool result  = false;
        EGLint count = 0;
        EGLint clientVersion =
            GetParam().majorVersion == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT;
        EGLint attribs[] = {EGL_RED_SIZE,
                            8,
                            EGL_GREEN_SIZE,
                            8,
                            EGL_BLUE_SIZE,
                            8,
                            EGL_RENDERABLE_TYPE,
                            clientVersion,
                            EGL_SURFACE_TYPE,
                            EGL_WINDOW_BIT | EGL_PBUFFER_BIT,
                            EGL_NONE};

        result = eglChooseConfig(dpy, attribs, config, 1, &count);
        EXPECT_EGL_TRUE(result && (count > 0));
        return result;
    }

    std::array<EGLContext, 2> mContexts = {EGL_NO_CONTEXT, EGL_NO_CONTEXT};
    GLuint mTexture;
};

class EGLContextSharingTestNoFixture : public EGLContextSharingTest
{
  public:
    EGLContextSharingTestNoFixture() : EGLContextSharingTest() {}

    void testSetUp() override
    {
        mOsWindow     = OSWindow::New();
        mMajorVersion = GetParam().majorVersion;
    }

    void testTearDown() override
    {
        if (mDisplay != EGL_NO_DISPLAY)
        {
            eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

            if (mSurface != EGL_NO_SURFACE)
            {
                eglDestroySurface(mDisplay, mSurface);
                ASSERT_EGL_SUCCESS();
                mSurface = EGL_NO_SURFACE;
            }

            for (auto &context : mContexts)
            {
                SafeDestroyContext(mDisplay, context);
            }

            eglTerminate(mDisplay);
            mDisplay = EGL_NO_DISPLAY;
            ASSERT_EGL_SUCCESS();
            eglReleaseThread();
            ASSERT_EGL_SUCCESS();
        }

        mOsWindow->destroy();
        OSWindow::Delete(&mOsWindow);
        ASSERT_EGL_SUCCESS() << "Error during test TearDown";
    }

    bool createContext(EGLConfig config,
                       EGLContext *context,
                       EGLContext share_context = EGL_NO_CONTEXT)
    {
        bool result      = false;
        EGLint attribs[] = {EGL_CONTEXT_MAJOR_VERSION, mMajorVersion,
                            EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE, mVirtualizationGroup++,
                            EGL_NONE};

        if (!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_ANGLE_context_virtualization"))
        {
            attribs[2] = EGL_NONE;
        }

        *context = eglCreateContext(mDisplay, config, share_context, attribs);
        result   = (*context != EGL_NO_CONTEXT);
        EXPECT_TRUE(result);
        return result;
    }

    bool createWindowSurface(EGLConfig config, EGLNativeWindowType win, EGLSurface *surface)
    {
        bool result      = false;
        EGLint attribs[] = {EGL_NONE};

        *surface = eglCreateWindowSurface(mDisplay, config, win, attribs);
        result   = (*surface != EGL_NO_SURFACE);
        EXPECT_TRUE(result);
        return result;
    }

    bool createPbufferSurface(EGLDisplay dpy,
                              EGLConfig config,
                              EGLint width,
                              EGLint height,
                              EGLSurface *surface)
    {
        bool result      = false;
        EGLint attribs[] = {EGL_WIDTH, width, EGL_HEIGHT, height, EGL_NONE};

        *surface = eglCreatePbufferSurface(dpy, config, attribs);
        result   = (*surface != EGL_NO_SURFACE);
        EXPECT_TRUE(result);
        return result;
    }

    OSWindow *mOsWindow;
    EGLDisplay mDisplay  = EGL_NO_DISPLAY;
    EGLSurface mSurface  = EGL_NO_SURFACE;
    const EGLint kWidth  = 64;
    const EGLint kHeight = 64;
    EGLint mMajorVersion = 0;
    std::atomic<EGLint> mVirtualizationGroup;
};

// Tests that creating resources works after freeing the share context.
TEST_P(EGLContextSharingTest, BindTextureAfterShareContextFree)
{
    EGLDisplay display = getEGLWindow()->getDisplay();
    EGLConfig config   = getEGLWindow()->getConfig();
    EGLSurface surface = getEGLWindow()->getSurface();

    const EGLint contextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION,
                                     getEGLWindow()->getClientMajorVersion(), EGL_NONE};

    mContexts[0] = eglCreateContext(display, config, nullptr, contextAttribs);
    ASSERT_EGL_SUCCESS();
    ASSERT_TRUE(mContexts[0] != EGL_NO_CONTEXT);
    mContexts[1] = eglCreateContext(display, config, mContexts[1], contextAttribs);
    ASSERT_EGL_SUCCESS();
    ASSERT_TRUE(mContexts[1] != EGL_NO_CONTEXT);

    ASSERT_EGL_TRUE(SafeDestroyContext(display, mContexts[0]));
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[1]));
    ASSERT_EGL_SUCCESS();

    glGenTextures(1, &mTexture);
    glBindTexture(GL_TEXTURE_2D, mTexture);
    ASSERT_GL_NO_ERROR();
}

// Tests that destroying a context with an undeleted sampler does not cause use-after-free.
// https://crbug.com/550347790
TEST_P(EGLContextSharingTest, DestroyContextWithUndeletedSampler)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);

    EGLDisplay display = getEGLWindow()->getDisplay();
    EGLConfig config   = getEGLWindow()->getConfig();
    EGLSurface surface = getEGLWindow()->getSurface();

    const bool hasVirt = IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_context_virtualization");

    const EGLint virtAttribs1[] = {EGL_CONTEXT_CLIENT_VERSION, 3,
                                   EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE, 1, EGL_NONE};
    const EGLint virtAttribs2[] = {EGL_CONTEXT_CLIENT_VERSION, 3,
                                   EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE, 2, EGL_NONE};
    const EGLint plainAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};

    const EGLint *a1 = hasVirt ? virtAttribs1 : plainAttribs;
    const EGLint *a2 = hasVirt ? virtAttribs2 : plainAttribs;

    mContexts[0] = eglCreateContext(display, config, EGL_NO_CONTEXT, a1);
    ASSERT_NE(EGL_NO_CONTEXT, mContexts[0]);
    mContexts[1] = eglCreateContext(display, config, mContexts[0], a2);
    ASSERT_NE(EGL_NO_CONTEXT, mContexts[1]);

    // Context 0: compile a program (which may hold a ref to the renderer) and create a sampler.
    // Intentionally do NOT delete the sampler to simulate garbage collection / leaked objects.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));
    ASSERT_EGL_SUCCESS();

    constexpr char kVS[] = R"(#version 300 es
void main() {
    gl_Position = vec4(0.0);
})";
    constexpr char kFS[] = R"(#version 300 es
precision mediump float;
out vec4 color;
void main() {
    color = vec4(1.0);
})";
    GLuint program       = CompileProgram(kVS, kFS);
    ASSERT_NE(0u, program);

    GLSampler leakedSampler;
    glSamplerParameteri(leakedSampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glBindSampler(0, leakedSampler);
    ASSERT_GL_NO_ERROR();

    // Context 1: create and delete a sampler cleanly.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[1]));
    ASSERT_EGL_SUCCESS();
    GLSampler sampler2;
    sampler2.reset();
    ASSERT_GL_NO_ERROR();

    // Destroy context 0 without deleting leakedSampler.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));
    glBindSampler(0, 0);
    ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    ASSERT_EGL_TRUE(SafeDestroyContext(display, mContexts[0]));

    // Clean up context 1.
    ASSERT_EGL_TRUE(SafeDestroyContext(display, mContexts[1]));
}

// Tests that destroying a single context with a program and an undeleted sampler does not cause
// use-after-free.
// https://crbug.com/550347790
TEST_P(EGLContextSharingTest, DestroySingleContextWithUndeletedSampler)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);

    EGLDisplay display = getEGLWindow()->getDisplay();
    EGLConfig config   = getEGLWindow()->getConfig();
    EGLSurface surface = getEGLWindow()->getSurface();

    const bool hasVirt = IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_context_virtualization");

    const EGLint virtAttribs[]  = {EGL_CONTEXT_CLIENT_VERSION, 3,
                                   EGL_CONTEXT_VIRTUALIZATION_GROUP_ANGLE, 1, EGL_NONE};
    const EGLint plainAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};

    const EGLint *attribs = hasVirt ? virtAttribs : plainAttribs;

    mContexts[0] = eglCreateContext(display, config, EGL_NO_CONTEXT, attribs);
    ASSERT_NE(EGL_NO_CONTEXT, mContexts[0]);

    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));
    ASSERT_EGL_SUCCESS();

    constexpr char kVS[] = R"(#version 300 es
void main() {
    gl_Position = vec4(0.0);
})";
    constexpr char kFS[] = R"(#version 300 es
precision mediump float;
out vec4 color;
void main() {
    color = vec4(1.0);
})";
    GLuint program       = CompileProgram(kVS, kFS);
    ASSERT_NE(0u, program);

    GLSampler leakedSampler;
    glSamplerParameteri(leakedSampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glBindSampler(0, leakedSampler);
    ASSERT_GL_NO_ERROR();

    glBindSampler(0, 0);
    ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
    ASSERT_EGL_TRUE(SafeDestroyContext(display, mContexts[0]));
}

// Tests the creation of contexts using EGL_ANGLE_display_texture_share_group
TEST_P(EGLContextSharingTest, DisplayShareGroupContextCreation)
{
    EGLDisplay display = getEGLWindow()->getDisplay();
    EGLConfig config   = getEGLWindow()->getConfig();

    const EGLint inShareGroupContextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2, EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_TRUE, EGL_NONE};

    // Check whether extension's supported to avoid clearing the EGL error state
    // after failed context creation.
    bool extensionEnabled =
        IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_display_texture_share_group");

    // Test creating two contexts in the global share group
    mContexts[0] = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
    mContexts[1] = eglCreateContext(display, config, mContexts[1], inShareGroupContextAttribs);

    if (!extensionEnabled)
    {
        // Make sure an error is generated and early-exit
        ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
        ASSERT_EQ(EGL_NO_CONTEXT, mContexts[0]);
        return;
    }

    ASSERT_EGL_SUCCESS();

    ASSERT_NE(EGL_NO_CONTEXT, mContexts[0]);
    ASSERT_NE(EGL_NO_CONTEXT, mContexts[1]);
    eglDestroyContext(display, mContexts[0]);
    mContexts[0] = EGL_NO_CONTEXT;

    // Try creating a context that is not in the global share group but tries to share with a
    // context that is
    const EGLint notInShareGroupContextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2, EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_FALSE, EGL_NONE};
    mContexts[0] = eglCreateContext(display, config, mContexts[1], notInShareGroupContextAttribs);
    ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
    ASSERT_TRUE(mContexts[0] == EGL_NO_CONTEXT);
}

// Tests the sharing of textures using EGL_ANGLE_display_texture_share_group
TEST_P(EGLContextSharingTest, DisplayShareGroupObjectSharing)
{
    EGLDisplay display = getEGLWindow()->getDisplay();
    ANGLE_SKIP_TEST_IF(
        !IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_display_texture_share_group"));

    EGLConfig config   = getEGLWindow()->getConfig();
    EGLSurface surface = getEGLWindow()->getSurface();

    const EGLint inShareGroupContextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2, EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_TRUE, EGL_NONE};

    // Create two contexts in the global share group but not in the same context share group
    mContexts[0] = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
    mContexts[1] = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);

    ASSERT_EGL_SUCCESS();

    ASSERT_NE(EGL_NO_CONTEXT, mContexts[0]);
    ASSERT_NE(EGL_NO_CONTEXT, mContexts[1]);

    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));
    ASSERT_EGL_SUCCESS();

    // Create a texture and buffer in ctx 0
    GLTexture textureFromCtx0;
    glBindTexture(GL_TEXTURE_2D, textureFromCtx0);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glBindTexture(GL_TEXTURE_2D, 0);
    ASSERT_GL_TRUE(glIsTexture(textureFromCtx0));

    GLBuffer bufferFromCtx0;
    glBindBuffer(GL_ARRAY_BUFFER, bufferFromCtx0);
    glBufferData(GL_ARRAY_BUFFER, 1, nullptr, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    ASSERT_GL_TRUE(glIsBuffer(bufferFromCtx0));

    ASSERT_GL_NO_ERROR();

    // Switch to context 1 and verify that the texture is accessible but the buffer is not
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[1]));
    ASSERT_EGL_SUCCESS();

    ASSERT_GL_TRUE(glIsTexture(textureFromCtx0));

    ASSERT_GL_FALSE(glIsBuffer(bufferFromCtx0));
    ASSERT_GL_NO_ERROR();

    // Call readpixels on the texture to verify that the backend has proper support
    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureFromCtx0, 0);

    GLubyte pixel[4];
    glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel);
    ASSERT_GL_NO_ERROR();

    // Switch back to context 0 and delete the buffer
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));
    ASSERT_EGL_SUCCESS();
}

// Tests that shared textures using EGL_ANGLE_display_texture_share_group are released when the last
// context is destroyed
TEST_P(EGLContextSharingTest, DisplayShareGroupReleasedWithLastContext)
{
    EGLDisplay display = getEGLWindow()->getDisplay();
    ANGLE_SKIP_TEST_IF(
        !IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_display_texture_share_group"));
    EGLConfig config   = getEGLWindow()->getConfig();
    EGLSurface surface = getEGLWindow()->getSurface();

    const EGLint inShareGroupContextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2, EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_TRUE, EGL_NONE};

    // Create two contexts in the global share group but not in the same context share group
    mContexts[0] = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
    mContexts[1] = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);

    // Create a texture and buffer in ctx 0
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));
    GLTexture textureFromCtx0;
    glBindTexture(GL_TEXTURE_2D, textureFromCtx0);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
    glBindTexture(GL_TEXTURE_2D, 0);
    ASSERT_GL_TRUE(glIsTexture(textureFromCtx0));

    // Switch to context 1 and verify that the texture is accessible
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[1]));
    ASSERT_GL_TRUE(glIsTexture(textureFromCtx0));

    // Destroy both contexts, the texture should be cleaned up automatically
    ASSERT_EGL_TRUE(eglDestroyContext(display, mContexts[0]));
    mContexts[0] = EGL_NO_CONTEXT;
    ASSERT_EGL_TRUE(eglDestroyContext(display, mContexts[1]));
    mContexts[1] = EGL_NO_CONTEXT;

    // Unmake current, so the context can be released.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

    // Create a new context and verify it cannot access the texture previously created
    mContexts[0] = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));

    ASSERT_GL_FALSE(glIsTexture(textureFromCtx0));
}

// Tests that after creating a texture using EGL_ANGLE_display_texture_share_group,
// and deleting the Context and the egl::ShareGroup who own a texture staged updates,
// the texture staged updates are flushed, and the Context and egl::ShareGroup can be destroyed
// successfully, and the texture can still be accessed from the global display texture share group
TEST_P(EGLContextSharingTest, DisplayShareGroupReleaseShareGroupThatOwnsStagedUpdates)
{
    EGLDisplay display = getEGLWindow()->getDisplay();
    ANGLE_SKIP_TEST_IF(
        !IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_display_texture_share_group"));

    EGLConfig config   = getEGLWindow()->getConfig();
    EGLSurface surface = getEGLWindow()->getSurface();

    const EGLint inShareGroupContextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2, EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_TRUE, EGL_NONE};

    // Create two contexts in the global share group, but not in the same context share group
    EGLContext context1 = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
    EGLContext context2 = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);

    // Create a texture in context1 and stage a texture update
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, context1));
    constexpr GLsizei kTexSize                   = 2;
    const GLColor kBlueData[kTexSize * kTexSize] = {GLColor::blue, GLColor::blue, GLColor::blue,
                                                    GLColor::blue};
    GLTexture textureFromCtx0;
    glBindTexture(GL_TEXTURE_2D, textureFromCtx0);
    // This will stage a texture update in context1's SharedGroup::BufferPool
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kBlueData);

    // Destroy context 1, this also destroys context1's SharedGroup and BufferPool
    // The texture staged update in context1's SharedGroup BufferPool will be flushed
    SafeDestroyContext(display, context1);

    // Switch to context2 and verify that the texture is accessible
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, context2));
    ASSERT_GL_TRUE(glIsTexture(textureFromCtx0));

    // Sample from textureFromCtx0 and check it works properly
    glBindTexture(GL_TEXTURE_2D, textureFromCtx0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    ANGLE_GL_PROGRAM(program1, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    glUseProgram(program1);
    drawQuad(program1, essl1_shaders::PositionAttrib(), 0.5f);
    EXPECT_GL_NO_ERROR();
    EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);

    // Destroy context2
    eglDestroyContext(display, context2);
}

// Regression test for sampler lifetime bug when EGL_ANGLE_display_texture_share_group is used.
TEST_P(EGLContextSharingTest, DisplayShareGroupSamplerInFlightWhenOwningShareGroupDestroyed)
{
    EGLDisplay display = getEGLWindow()->getDisplay();
    ANGLE_SKIP_TEST_IF(
        !IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_display_texture_share_group"));
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    EGLConfig config   = getEGLWindow()->getConfig();
    EGLSurface surface = getEGLWindow()->getSurface();

    const EGLint inShareGroupContextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2, EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_TRUE, EGL_NONE};

    // Two contexts in the *display* texture share group but each in its own share group
    EGLContext contextA = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
    EGLContext contextB = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
    ASSERT_NE(contextA, EGL_NO_CONTEXT);
    ASSERT_NE(contextB, EGL_NO_CONTEXT);

    // A larger render target widens the GPU window for the heavy draw in B.
    constexpr int kHeavyDim       = 256;
    const EGLint pbufferAttribs[] = {EGL_WIDTH, kHeavyDim, EGL_HEIGHT, kHeavyDim, EGL_NONE};
    EGLSurface pbufferB           = eglCreatePbufferSurface(display, config, pbufferAttribs);
    ASSERT_NE(pbufferB, EGL_NO_SURFACE);

    // Context A: create the shared texture and draw with it once.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, contextA));
    GLTexture sharedTex;
    glBindTexture(GL_TEXTURE_2D, sharedTex);
    constexpr GLsizei kTexSize = 4;
    std::vector<GLColor> texData(kTexSize * kTexSize, GLColor::green);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 texData.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    {
        ANGLE_GL_PROGRAM(progA, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
        drawQuad(progA, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_GL_NO_ERROR();
        glFlush();
    }

    // Context B: bind the same display-shared texture and submit a long running draw.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, pbufferB, pbufferB, contextB));
    glViewport(0, 0, kHeavyDim, kHeavyDim);
    glBindTexture(GL_TEXTURE_2D, sharedTex);

    constexpr char kHeavyFS[] = R"(precision highp float;
varying vec2 v_texCoord;
uniform sampler2D u_tex2D;
void main()
{
    vec4 acc = vec4(0.0);
    // Busy work to make sure the GPU is using the texture when context A is destroyed.
    for (int i = 0; i < 4000; ++i)
    {
        acc += texture2D(u_tex2D, v_texCoord + vec2(float(i) * 0.000001, 0.0));
    }
    gl_FragColor = acc * 0.00025;
})";
    ANGLE_GL_PROGRAM(progHeavy, essl1_shaders::vs::Texture2D(), kHeavyFS);
    glUseProgram(progHeavy);
    glUniform1i(glGetUniformLocation(progHeavy, "u_tex2D"), 0);
    // Several expensive draw calls so the GPU is using the texture when context A is destroyed
    for (int i = 0; i < 16; ++i)
    {
        drawQuad(progHeavy, essl1_shaders::PositionAttrib(), 0.5f);
    }
    EXPECT_GL_NO_ERROR();
    glFlush();  // batch_B submitted, GPU now executing with S_A in its descriptor set.

    // Still in B: dirty a sampler-state bit and draw again.
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    {
        ANGLE_GL_PROGRAM(progB2, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
        drawQuad(progB2, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_GL_NO_ERROR();
        glFlush();
    }

    // Destroy context A. The texture's sampler currently in use by context B should not be freed.
    SafeDestroyContext(display, contextA);

    // Finish, to make sure the work is done.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, pbufferB, pbufferB, contextB));
    glFinish();
    sharedTex.reset();
    EXPECT_GL_NO_ERROR();

    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglDestroySurface(display, pbufferB);
    SafeDestroyContext(display, contextB);
    getEGLWindow()->makeCurrent();
}

// Variant of DisplayShareGroupSamplerInFlightWhenOwningShareGroupDestroyed, except the texture's
// sampler state is not modified
TEST_P(EGLContextSharingTest, DisplayShareGroupOrphanedSamplerReapedWhileInFlight)
{
    EGLDisplay display = getEGLWindow()->getDisplay();
    ANGLE_SKIP_TEST_IF(
        !IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_display_texture_share_group"));
    ANGLE_SKIP_TEST_IF(!IsVulkan());

    EGLConfig config   = getEGLWindow()->getConfig();
    EGLSurface surface = getEGLWindow()->getSurface();

    const EGLint inShareGroupContextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2, EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_TRUE, EGL_NONE};

    EGLContext contextA = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
    EGLContext contextB = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
    EGLContext contextC = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
    ASSERT_NE(contextA, EGL_NO_CONTEXT);
    ASSERT_NE(contextB, EGL_NO_CONTEXT);
    ASSERT_NE(contextC, EGL_NO_CONTEXT);

    constexpr int kHeavyDim       = 256;
    const EGLint pbufferAttribs[] = {EGL_WIDTH, kHeavyDim, EGL_HEIGHT, kHeavyDim, EGL_NONE};
    EGLSurface pbufferB           = eglCreatePbufferSurface(display, config, pbufferAttribs);
    ASSERT_NE(pbufferB, EGL_NO_SURFACE);

    // A: Create texture and draw: this creates an internal sampler for the texture
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, contextA));
    GLTexture sharedTex;
    glBindTexture(GL_TEXTURE_2D, sharedTex);
    std::vector<GLColor> texData(16, GLColor::cyan);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texData.data());
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    {
        ANGLE_GL_PROGRAM(p, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
        drawQuad(p, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_GL_NO_ERROR();
        glFlush();
    }

    // B: Draw with texture, using an expensive shader so the GPU is busy when context C is
    // destroyed
    ASSERT_EGL_TRUE(eglMakeCurrent(display, pbufferB, pbufferB, contextB));
    glViewport(0, 0, kHeavyDim, kHeavyDim);
    glBindTexture(GL_TEXTURE_2D, sharedTex);
    constexpr char kHeavyFS[] = R"(precision highp float;
varying vec2 v_texCoord;
uniform sampler2D u_tex2D;
void main()
{
    vec4 acc = vec4(0.0);
    for (int i = 0; i < 4000; ++i)
    {
        acc += texture2D(u_tex2D, v_texCoord + vec2(float(i) * 0.000001, 0.0));
    }
    gl_FragColor = acc * 0.00025;
})";
    ANGLE_GL_PROGRAM(progHeavy, essl1_shaders::vs::Texture2D(), kHeavyFS);
    glUseProgram(progHeavy);
    glUniform1i(glGetUniformLocation(progHeavy, "u_tex2D"), 0);
    for (int i = 0; i < 16; ++i)
    {
        drawQuad(progHeavy, essl1_shaders::PositionAttrib(), 0.5f);
    }
    EXPECT_GL_NO_ERROR();
    glFlush();

    // Destroy A first; context B still references the texture's internal sampler.
    SafeDestroyContext(display, contextA);

    // B: dirty sampler state and draw so the texture's internal sampler is recreated.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, pbufferB, pbufferB, contextB));
    glBindTexture(GL_TEXTURE_2D, sharedTex);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    {
        ANGLE_GL_PROGRAM(p2, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
        drawQuad(p2, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_GL_NO_ERROR();
        glFlush();
    }

    // Destroy unrelated context C.  The original texture's internal sampler, still in use by the
    // GPU, should not be freed.
    SafeDestroyContext(display, contextC);

    ASSERT_EGL_TRUE(eglMakeCurrent(display, pbufferB, pbufferB, contextB));
    glFinish();
    sharedTex.reset();
    EXPECT_GL_NO_ERROR();

    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglDestroySurface(display, pbufferB);
    SafeDestroyContext(display, contextB);
    getEGLWindow()->makeCurrent();
}

// Tests that after creating a texture using EGL_ANGLE_display_texture_share_group,
// and use it for sampling, and then deleting the Context (which destroys shareGroup) works. If
// anything cached in ShareGroup, it should be handled nicely if texture can outlive ShareGroup (for
// example, bugs like http://anglebug.com/42265935).
TEST_P(EGLContextSharingTest, DisplayShareGroupReleaseShareGroupThenDestroyTexture)
{
    EGLDisplay display = getEGLWindow()->getDisplay();
    ANGLE_SKIP_TEST_IF(
        !IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_display_texture_share_group"));

    EGLConfig config   = getEGLWindow()->getConfig();
    EGLSurface surface = getEGLWindow()->getSurface();

    const EGLint inShareGroupContextAttribs[] = {
        EGL_CONTEXT_CLIENT_VERSION, 2, EGL_DISPLAY_TEXTURE_SHARE_GROUP_ANGLE, EGL_TRUE, EGL_NONE};

    // Create two contexts in the global share group, but not in the same context share group
    EGLContext context1 = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);
    EGLContext context2 = eglCreateContext(display, config, nullptr, inShareGroupContextAttribs);

    // Create a texture in context1 and stage a texture update
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, context1));
    constexpr GLsizei kTexSize                   = 2;
    const GLColor kBlueData[kTexSize * kTexSize] = {GLColor::blue, GLColor::blue, GLColor::blue,
                                                    GLColor::blue};
    {
        GLTexture textureFromCtx1;
        glBindTexture(GL_TEXTURE_2D, textureFromCtx1);
        // This will stage a texture update in context1's SharedGroup::BufferPool
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 2, 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, kBlueData);

        // Sample from textureFromCtx1 and check it works properly
        glBindTexture(GL_TEXTURE_2D, textureFromCtx1);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        ANGLE_GL_PROGRAM(program1, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
        glUseProgram(program1);
        drawQuad(program1, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_GL_NO_ERROR();
        EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::blue);

        // Destroy context 1, this also destroys context1's SharedGroup and BufferPool
        // The texture staged update in context1's SharedGroup BufferPool will be flushed
        SafeDestroyContext(display, context1);

        // Switch to context2 and verify that the texture is accessible
        ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, context2));
        ASSERT_GL_TRUE(glIsTexture(textureFromCtx1));

        // textureFromCtx1 should be destroyed when leaving this scope
    }

    // Destroy context2
    eglDestroyContext(display, context2);
}

// Tests that deleting an object on one Context doesn't destroy it ahead-of-time. Mostly focused
// on the Vulkan back-end where we manage object lifetime manually.
TEST_P(EGLContextSharingTest, TextureLifetime)
{
    EGLWindow *eglWindow = getEGLWindow();
    EGLConfig config     = getEGLWindow()->getConfig();
    EGLDisplay display   = getEGLWindow()->getDisplay();

    // Create a pbuffer surface for use with a shared context.
    EGLSurface surface     = eglWindow->getSurface();
    EGLContext mainContext = eglWindow->getContext();

    // Initialize a shared context.
    mContexts[0] = eglCreateContext(display, config, mainContext, nullptr);
    ASSERT_NE(mContexts[0], EGL_NO_CONTEXT);

    // Create a Texture on the shared context.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));

    constexpr GLsizei kTexSize                  = 2;
    const GLColor kTexData[kTexSize * kTexSize] = {GLColor::red, GLColor::green, GLColor::blue,
                                                   GLColor::yellow};
    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 kTexData);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    // Make the main Context current and draw with the texture.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mainContext));

    glBindTexture(GL_TEXTURE_2D, tex);
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    glUseProgram(program);

    // No uniform update because the update seems to hide the error on Vulkan.

    // Enqueue the draw call.
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    EXPECT_GL_NO_ERROR();

    // Delete the texture in the main context to orphan it.
    // Do not read back the data to keep the commands in the graph.
    tex.reset();

    // Bind and delete the test context. This should trigger texture garbage collection.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));
    SafeDestroyContext(display, mContexts[0]);

    // Bind the main context to clean up the test.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mainContext));
}

// Tests that deleting an object on one Context doesn't destroy it ahead-of-time. Mostly focused
// on the Vulkan back-end where we manage object lifetime manually.
TEST_P(EGLContextSharingTest, SamplerLifetime)
{
    EGLWindow *eglWindow = getEGLWindow();
    EGLConfig config     = getEGLWindow()->getConfig();
    EGLDisplay display   = getEGLWindow()->getDisplay();

    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);
    ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(display, "EGL_KHR_create_context"));

    // Create a pbuffer surface for use with a shared context.
    EGLSurface surface     = eglWindow->getSurface();
    EGLContext mainContext = eglWindow->getContext();

    std::vector<EGLint> contextAttributes;
    contextAttributes.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR);
    contextAttributes.push_back(getClientMajorVersion());
    contextAttributes.push_back(EGL_NONE);

    // Initialize a shared context.
    mContexts[0] = eglCreateContext(display, config, mainContext, contextAttributes.data());
    ASSERT_NE(mContexts[0], EGL_NO_CONTEXT);

    // Create a Texture on the shared context. Also create a Sampler object.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));

    constexpr GLsizei kTexSize                  = 2;
    const GLColor kTexData[kTexSize * kTexSize] = {GLColor::red, GLColor::green, GLColor::blue,
                                                   GLColor::yellow};
    GLTexture tex;
    glBindTexture(GL_TEXTURE_2D, tex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 kTexData);

    GLSampler sampler;
    glBindSampler(0, sampler);
    glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    // Make the main Context current and draw with the texture and sampler.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mainContext));

    glBindTexture(GL_TEXTURE_2D, tex);
    glBindSampler(0, sampler);
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
    glUseProgram(program);

    // No uniform update because the update seems to hide the error on Vulkan.

    // Enqueue the draw call.
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
    EXPECT_GL_NO_ERROR();

    // Delete the texture and sampler in the main context to orphan them.
    // Do not read back the data to keep the commands in the graph.
    tex.reset();
    sampler.reset();

    // Bind and delete the test context. This should trigger texture garbage collection.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mContexts[0]));
    SafeDestroyContext(display, mContexts[0]);

    // Bind the main context to clean up the test.
    ASSERT_EGL_TRUE(eglMakeCurrent(display, surface, surface, mainContext));
}

// Test that deleting an object reading from a shared object in one context doesn't cause the other
// context to crash.  Mostly focused on the Vulkan back-end where we track resource dependencies in
// a graph.
TEST_P(EGLContextSharingTest, DeleteReaderOfSharedTexture)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    // GL Fences require GLES 3.0+
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);

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

    constexpr size_t kThreadCount    = 2;
    std::array<EGLSurface, kThreadCount> surface = {EGL_NO_SURFACE, EGL_NO_SURFACE};
    std::array<EGLContext, kThreadCount> ctx     = {EGL_NO_CONTEXT, EGL_NO_CONTEXT};

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

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

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

    // Initialize test resources.  They are done outside the threads to reduce the sources of
    // errors and thus deadlock-free teardown.
    ASSERT_EGL_TRUE(eglMakeCurrent(dpy, surface[1], surface[1], ctx[1]));

    // Shared texture to read from.
    constexpr GLsizei kTexSize = 1;
    const GLColor kTexData     = GLColor::red;

    GLTexture sharedTex;
    glBindTexture(GL_TEXTURE_2D, sharedTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                 &kTexData);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

    // Resources for each context.
    std::array<GLRenderbuffer, kThreadCount> renderbuffer;
    std::array<GLFramebuffer, kThreadCount> fbo;
    std::array<GLProgram, kThreadCount> program;

    for (size_t t = 0; t < kThreadCount; ++t)
    {
        ASSERT_EGL_TRUE(eglMakeCurrent(dpy, surface[t], surface[t], ctx[t]));

        glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer[t]);
        constexpr int kRenderbufferSize = 4;
        glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, kRenderbufferSize, kRenderbufferSize);

        glBindFramebuffer(GL_FRAMEBUFFER, fbo[t]);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
                                  renderbuffer[t]);

        glBindTexture(GL_TEXTURE_2D, sharedTex);
        program[t].makeRaster(essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
        ASSERT_TRUE(program[t].valid());
    }

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

    // Synchronization tools to ensure the two threads are interleaved as designed by this test.
    std::mutex mutex;
    std::condition_variable condVar;
    std::atomic<GLsync> deletingThreadSyncObj;
    std::atomic<GLsync> continuingThreadSyncObj;

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

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

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

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

        // Draw using the shared texture.
        drawQuad(program[0].get(), essl1_shaders::PositionAttrib(), 0.5f);

        deletingThreadSyncObj = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        ASSERT_GL_NO_ERROR();
        // Force the fence to be created
        glFlush();

        // Wait for the other thread to also draw using the shared texture.
        threadSynchronization.nextStep(Step::Thread0Draw);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Draw));

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

        // Delete this thread's framebuffer (reader of the shared texture).
        fbo[0].reset();

        // Wait for the other thread to use the shared texture again before unbinding the
        // context (so no implicit flush happens).
        threadSynchronization.nextStep(Step::Thread0Delete);
        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();
    });

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

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

        // Wait for first thread to draw using the shared texture.
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Draw));

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

        // Draw using the shared texture.
        drawQuad(program[0].get(), essl1_shaders::PositionAttrib(), 0.5f);

        continuingThreadSyncObj = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        ASSERT_GL_NO_ERROR();
        // Force the fence to be created
        glFlush();

        // Wait for the other thread to delete its framebuffer.
        threadSynchronization.nextStep(Step::Thread1Draw);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Delete));

        // Write to the shared texture differently, so a dependency is created from the previous
        // readers of the shared texture (the two framebuffers of the two threads) to the new
        // commands being recorded for the shared texture.
        //
        // If the backend attempts to create a dependency from nodes associated with the
        // previous readers of the texture to the new node that will contain the following
        // commands, there will be a use-after-free error.
        const GLColor kTexData2 = GLColor::green;
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kTexSize, kTexSize, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     &kTexData2);
        drawQuad(program[0].get(), essl1_shaders::PositionAttrib(), 0.5f);

        threadSynchronization.nextStep(Step::Finish);

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

    deletingThread.join();
    continuingThread.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 will be destroyed in thread cleanup callback and it is safe to call GLES APIs.
TEST_P(EGLContextSharingTest, ThreadCleanupCallback)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!IsAndroid());

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

    EGLContext context = window->createContext(EGL_NO_CONTEXT, nullptr);
    EXPECT_NE(context, EGL_NO_CONTEXT);

    EGLint pbufferAttributes[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
    EGLSurface surface         = eglCreatePbufferSurface(dpy, config, pbufferAttributes);
    EXPECT_NE(surface, EGL_NO_SURFACE);

    auto registerThreadCleanupCallback = []() {
#if defined(ANGLE_PLATFORM_ANDROID)
        static pthread_once_t once = PTHREAD_ONCE_INIT;
        static TLSIndex tlsIndex   = TLS_INVALID_INDEX;

        auto createThreadCleanupTLSIndex = []() {
            auto threadCleanupCallback = [](void *) {
                // From the point of view of this test Context is still current.
                glFinish();
                // Test expects that Context will be destroyed here.
                eglReleaseThread();
            };
            tlsIndex = CreateTLSIndex(threadCleanupCallback);
        };
        pthread_once(&once, createThreadCleanupTLSIndex);
        ASSERT(tlsIndex != TLS_INVALID_INDEX);

        // Set any non nullptr value.
        SetTLSValue(tlsIndex, &once);
#endif
    };

    std::thread thread([&]() {
        registerThreadCleanupCallback();

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

        // Clear and read back to make sure thread uses context.
        glClearColor(1.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);

        // Destroy context and surface while still current.
        eglDestroyContext(dpy, context);
        ASSERT_EGL_SUCCESS();
        eglDestroySurface(dpy, surface);
        ASSERT_EGL_SUCCESS();
    });

    thread.join();

    // Check if context was actually destroyed.
    EGLint val;
    EXPECT_EGL_FALSE(eglQueryContext(dpy, context, EGL_CONTEXT_CLIENT_TYPE, &val));
    EXPECT_EQ(eglGetError(), EGL_BAD_CONTEXT);
}

// Tests that Context will be automatically unmade from current on thread exit.
TEST_P(EGLContextSharingTest, UnmakeFromCurrentOnThreadExit)
{
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    ANGLE_SKIP_TEST_IF(!IsAndroid());

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

    EGLContext context = window->createContext(EGL_NO_CONTEXT, nullptr);
    EXPECT_NE(context, EGL_NO_CONTEXT);

    EGLint pbufferAttributes[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
    EGLSurface surface         = eglCreatePbufferSurface(dpy, config, pbufferAttributes);
    EXPECT_NE(surface, EGL_NO_SURFACE);

    std::mutex mutex;
    std::condition_variable condVar;
    enum class Step
    {
        Start,
        ThreadMakeCurrent,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;
    ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);

    std::thread thread([&]() {
        eglMakeCurrent(dpy, surface, surface, context);
        ASSERT_EGL_SUCCESS();

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

        // Clear and read back to make sure thread uses context.
        glClearColor(1.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
    });

    // Wait while Context is made current in the thread.
    ASSERT_TRUE(threadSynchronization.waitForStep(Step::ThreadMakeCurrent));

    // This should fail because context is already current in other thread.
    eglMakeCurrent(dpy, surface, surface, context);
    EXPECT_EQ(eglGetError(), EGL_BAD_ACCESS);

    // Finish the thread.
    threadSynchronization.nextStep(Step::Finish);
    thread.join();

    // This should succeed, because thread is finished so context is no longer current.
    eglMakeCurrent(dpy, surface, surface, context);
    EXPECT_EGL_SUCCESS();
    eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    ASSERT_EGL_SUCCESS();

    // Destroy context and surface.
    eglDestroyContext(dpy, context);
    ASSERT_EGL_SUCCESS();
    eglDestroySurface(dpy, surface);
    ASSERT_EGL_SUCCESS();
}

// Tests that calling MakeCurrent() with EGL_NO_CONTEXT must also specify EGL_NO_SURFACE
TEST_P(EGLContextSharingTest, MakeCurrentNoContextAndNoSurface)
{
    EGLWindow *window = getEGLWindow();

    // There's a valid context and surface current at the test start
    ASSERT_NE(eglGetCurrentContext(), EGL_NO_CONTEXT);
    ASSERT_EGL_SUCCESS();

    // Release the current context. The helper must substitute EGL_NO_SURFACE for both the
    // draw and read surfaces, while using a real window surface would cause EGL_BAD_MATCH
    // and further downstream errors
    EXPECT_TRUE(window->makeCurrent(EGL_NO_CONTEXT));
    EXPECT_EGL_SUCCESS();

    // A failed eglMakeCurrent() will leave the previous context/surface bound
    EXPECT_EQ(eglGetCurrentContext(), EGL_NO_CONTEXT);
    EXPECT_EQ(eglGetCurrentSurface(EGL_DRAW), EGL_NO_SURFACE);
    EXPECT_EQ(eglGetCurrentSurface(EGL_READ), EGL_NO_SURFACE);

    EXPECT_TRUE(window->makeCurrent());
    EXPECT_EGL_SUCCESS();
}

// Test that an inactive but alive thread doesn't prevent memory cleanup.
TEST_P(EGLContextSharingTestNoFixture, InactiveThreadDoesntPreventCleanup)
{
    EGLAttrib dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE,
                             GetParam().getRenderer(),
                             EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE,
                             static_cast<EGLAttrib>(mOsWindow->getNativeDisplayPlatformType()),
                             EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE,
                             GetParam().getDeviceType(),
                             EGL_NONE};

    // 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,
        Thread0Initialize,
        Thread1MakeCurrent,
        Thread0MakeCurrent,
        Thread1Render,
        Thread0Terminate,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

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

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

        mDisplay = eglGetPlatformDisplay(GetEglPlatform(),
                                         reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
        EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
        EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));

        threadSynchronization.nextStep(Step::Thread0Initialize);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1MakeCurrent));

        EGLContext ctx;
        EGLSurface srf;
        EGLConfig config = EGL_NO_CONFIG_KHR;
        EXPECT_TRUE(chooseConfig(mDisplay, &config));
        EXPECT_TRUE(createContext(config, &ctx));

        EXPECT_TRUE(createPbufferSurface(mDisplay, config, 1280, 720, &srf));
        ASSERT_EGL_SUCCESS() << "eglCreatePbufferSurface failed.";

        EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, srf, srf, ctx));
        threadSynchronization.nextStep(Step::Thread0MakeCurrent);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread1Render));

        eglTerminate(mDisplay);
        EXPECT_EGL_SUCCESS();
        EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        threadSynchronization.nextStep(Step::Thread0Terminate);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));

        // Wait a little to simulate an inactive but alive thread.
        angle::Sleep(100);
    });

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

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

        EGLContext ctx;
        EGLSurface srf;
        EGLConfig config = EGL_NO_CONFIG_KHR;
        EXPECT_TRUE(chooseConfig(mDisplay, &config));
        EXPECT_TRUE(createContext(config, &ctx));

        EXPECT_TRUE(createPbufferSurface(mDisplay, config, 1280, 720, &srf));
        ASSERT_EGL_SUCCESS() << "eglCreatePbufferSurface failed.";

        EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, srf, srf, ctx));

        threadSynchronization.nextStep(Step::Thread1MakeCurrent);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0MakeCurrent));

        // Clear and read back to make sure thread uses context and surface.
        glClearColor(1.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);

        threadSynchronization.nextStep(Step::Thread1Render);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0Terminate));

        EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        threadSynchronization.nextStep(Step::Finish);
    });

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

    ASSERT_NE(currentStep, Step::Abort);
}

// Test that eglTerminate() with a thread doesn't cause other threads to crash.
TEST_P(EGLContextSharingTestNoFixture, EglTerminateMultiThreaded)
{
    // http://anglebug.com/42264731
    // The following EGL calls led to a crash in eglMakeCurrent():
    //
    // Thread A: eglMakeCurrent(context A)
    // Thread B: eglDestroyContext(context A)
    //        B: eglTerminate() <<--- this release context A
    // Thread A: eglMakeCurrent(context B)

    EGLAttrib dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(),
                             EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE,
                             static_cast<EGLAttrib>(GetPbufferOnlyDefaultPlatformType()), EGL_NONE};
    mDisplay              = eglGetPlatformDisplay(GetEglPlatform(),
                                                  reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
    EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
    EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));

    EGLConfig config = EGL_NO_CONFIG_KHR;
    EXPECT_TRUE(chooseConfig(mDisplay, &config));

    mOsWindow->initialize("EGLContextSharingTestNoFixture", kWidth, kHeight);
    EXPECT_TRUE(createWindowSurface(config, mOsWindow->getNativeWindow(), &mSurface));
    ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";

    EXPECT_TRUE(createContext(config, &mContexts[0]));
    EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContexts[0]));

    // Must be after the eglMakeCurrent() so renderer string is initialized.
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    // TODO(http://anglebug.com/42264822): Fails with OpenGL ES backend.
    ANGLE_SKIP_TEST_IF(IsOpenGLES());

    EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

    // 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,
        Thread0Clear,
        Thread1Terminate,
        Thread0MakeCurrentContext1,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

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

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

        EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContexts[0]));

        // Clear and read back to make sure thread 0 uses context 0.
        glClearColor(1.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);

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

        // First Display was terminated, so we need to create a new one to create a new Context.
        mDisplay = eglGetPlatformDisplay(GetEglPlatform(),
                                         reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
        EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
        EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));
        config = EGL_NO_CONFIG_KHR;
        EXPECT_TRUE(chooseConfig(mDisplay, &config));
        EXPECT_TRUE(createContext(config, &mContexts[1]));

        // Thread1's terminate call will make mSurface an invalid handle, recreate a new surface
        EXPECT_TRUE(createPbufferSurface(mDisplay, config, 1280, 720, &mSurface));
        ASSERT_EGL_SUCCESS() << "eglCreatePbufferSurface failed.";

        EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContexts[1]));

        // Clear and read back to make sure thread 0 uses context 1.
        glClearColor(1.0, 1.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        EXPECT_PIXEL_EQ(0, 0, 255, 255, 0, 255);

        // Cleanup
        EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_TRUE(SafeDestroyContext(mDisplay, mContexts[1]));
        eglDestroySurface(mDisplay, mSurface);
        mSurface = EGL_NO_SURFACE;
        eglTerminate(mDisplay);
        mDisplay = EGL_NO_DISPLAY;
        EXPECT_EGL_SUCCESS();

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

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

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

        // Destroy context 0 while thread1 has it current.
        EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_TRUE(SafeDestroyContext(mDisplay, mContexts[0]));
        EXPECT_EGL_SUCCESS();
        eglTerminate(mDisplay);
        mDisplay = EGL_NO_DISPLAY;
        EXPECT_EGL_SUCCESS();

        // Wait for the thread 0 to make a new context and glClear().
        threadSynchronization.nextStep(Step::Thread1Terminate);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0MakeCurrentContext1));

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

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

    ASSERT_NE(currentStep, Step::Abort);
}

// Test that eglDestoryContext() can be called multiple times on the same Context without causing
// errors.
TEST_P(EGLContextSharingTestNoFixture, EglDestoryContextManyTimesSameContext)
{
    EGLAttrib dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(),
                             EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE,
                             static_cast<EGLAttrib>(mOsWindow->getNativeDisplayPlatformType()),
                             EGL_NONE};
    mDisplay              = eglGetPlatformDisplay(GetEglPlatform(),
                                                  reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
    EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
    EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));

    EGLConfig config = EGL_NO_CONFIG_KHR;
    EXPECT_TRUE(chooseConfig(mDisplay, &config));

    mOsWindow->initialize("EGLContextSharingTestNoFixture", kWidth, kHeight);
    EXPECT_TRUE(createWindowSurface(config, mOsWindow->getNativeWindow(), &mSurface));
    ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";

    EXPECT_TRUE(createContext(config, &mContexts[0]));
    EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContexts[0]));

    // Must be after the eglMakeCurrent() so renderer string is initialized.
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    // TODO(http://anglebug.com/42264822): Fails with OpenGL ES backend.
    ANGLE_SKIP_TEST_IF(IsOpenGLES());

    EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

    // 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,
        Thread0Clear,
        Thread1Terminate,
        Thread0MakeCurrentContext1,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

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

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

        EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContexts[0]));

        // Clear and read back to make sure thread 0 uses context 0.
        glClearColor(1.0, 0.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);

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

        // First Display was terminated, so we need to create a new one to create a new Context.
        mDisplay = eglGetPlatformDisplay(GetEglPlatform(),
                                         reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
        EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
        EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));
        config = EGL_NO_CONFIG_KHR;
        EXPECT_TRUE(chooseConfig(mDisplay, &config));
        EXPECT_TRUE(createContext(config, &mContexts[1]));

        // Thread1's terminate call will make mSurface an invalid handle, recreate a new surface
        EXPECT_TRUE(createPbufferSurface(mDisplay, config, 1280, 720, &mSurface));
        ASSERT_EGL_SUCCESS() << "eglCreatePbufferSurface failed.";

        EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContexts[1]));
        EXPECT_EGL_SUCCESS();

        // Clear and read back to make sure thread 0 uses context 1.
        glClearColor(1.0, 1.0, 0.0, 1.0);
        glClear(GL_COLOR_BUFFER_BIT);
        EXPECT_PIXEL_EQ(0, 0, 255, 255, 0, 255);

        // Cleanup
        EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_TRUE(SafeDestroyContext(mDisplay, mContexts[1]));
        eglDestroySurface(mDisplay, mSurface);
        mSurface = EGL_NO_SURFACE;
        eglTerminate(mDisplay);
        mDisplay = EGL_NO_DISPLAY;
        EXPECT_EGL_SUCCESS();

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

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

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

        EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        // Destroy context 0 5 times while thread1 has it current.
        EXPECT_EGL_TRUE(eglDestroyContext(mDisplay, mContexts[0]));
        EXPECT_EGL_TRUE(eglDestroyContext(mDisplay, mContexts[0]));
        EXPECT_EGL_TRUE(eglDestroyContext(mDisplay, mContexts[0]));
        EXPECT_EGL_TRUE(eglDestroyContext(mDisplay, mContexts[0]));
        EXPECT_EGL_TRUE(eglDestroyContext(mDisplay, mContexts[0]));
        mContexts[0] = EGL_NO_CONTEXT;

        eglDestroySurface(mDisplay, mSurface);
        mSurface = EGL_NO_SURFACE;
        eglTerminate(mDisplay);
        mDisplay = EGL_NO_DISPLAY;
        EXPECT_EGL_SUCCESS();

        // Wait for the thread 0 to make a new context and glClear().
        threadSynchronization.nextStep(Step::Thread1Terminate);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Thread0MakeCurrentContext1));

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

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

    ASSERT_NE(currentStep, Step::Abort);
}

// Test that eglTerminate() can be called multiple times on the same Display while Contexts are
// still current without causing errors.
TEST_P(EGLContextSharingTestNoFixture, EglTerminateMultipleTimes)
{
    // https://bugs.chromium.org/p/skia/issues/detail?id=12413#c4
    // The following sequence caused a crash with the D3D backend in the Skia infra:
    //   eglDestroyContext(ctx0)
    //   eglDestroySurface(srf0)
    //   eglTerminate(shared-display)
    //   eglDestroyContext(ctx1) // completes the cleanup from the above terminate
    //   eglDestroySurface(srf1)
    //   eglTerminate(shared-display)

    EGLAttrib dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(),
                             EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE,
                             static_cast<EGLAttrib>(mOsWindow->getNativeDisplayPlatformType()),
                             EGL_NONE};
    mDisplay              = eglGetPlatformDisplay(GetEglPlatform(),
                                                  reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
    EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
    EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));

    EGLConfig config = EGL_NO_CONFIG_KHR;
    EXPECT_TRUE(chooseConfig(mDisplay, &config));

    mOsWindow->initialize("EGLContextSharingTestNoFixture", kWidth, kHeight);
    EXPECT_TRUE(createWindowSurface(config, mOsWindow->getNativeWindow(), &mSurface));
    EXPECT_TRUE(mSurface != EGL_NO_SURFACE);
    ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";

    EXPECT_TRUE(createContext(config, &mContexts[0]));
    EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContexts[0]));
    EXPECT_TRUE(createContext(config, &mContexts[1]));
    EXPECT_EGL_TRUE(eglMakeCurrent(mDisplay, mSurface, mSurface, mContexts[1]));

    // Must be after the eglMakeCurrent() so renderer string is initialized.
    // TODO(http://anglebug.com/42264822): Fails with Mac + OpenGL backend.
    ANGLE_SKIP_TEST_IF(IsMac() && IsOpenGL());

    EXPECT_TRUE(eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

    eglDestroySurface(mDisplay, mSurface);
    mSurface = EGL_NO_SURFACE;
    EXPECT_EGL_TRUE(eglDestroyContext(mDisplay, mContexts[0]));
    mContexts[0] = EGL_NO_CONTEXT;
    eglTerminate(mDisplay);
    EXPECT_EGL_SUCCESS();

    eglDestroyContext(mDisplay, mContexts[1]);
    mContexts[1] = EGL_NO_CONTEXT;
    ASSERT_EGL_ERROR(EGL_NOT_INITIALIZED);
    eglTerminate(mDisplay);
    EXPECT_EGL_SUCCESS();
    mDisplay = EGL_NO_DISPLAY;
}

// Test that we can eglSwapBuffers in one thread while another thread renders to a texture.
TEST_P(EGLContextSharingTestNoFixture, SwapBuffersShared)
{
    EGLAttrib dispattrs[] = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(),
                             EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE,
                             static_cast<EGLAttrib>(mOsWindow->getNativeDisplayPlatformType()),
                             EGL_NONE};
    mDisplay              = eglGetPlatformDisplay(GetEglPlatform(),
                                                  reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
    EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
    EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));

    EGLConfig config = EGL_NO_CONFIG_KHR;
    EXPECT_TRUE(chooseConfig(mDisplay, &config));

    mOsWindow->initialize("EGLContextSharingTestNoFixture", kWidth, kHeight);
    EXPECT_TRUE(createWindowSurface(config, mOsWindow->getNativeWindow(), &mSurface));
    ASSERT_EGL_SUCCESS() << "eglCreateWindowSurface failed.";

    EGLSurface pbufferSurface;
    EXPECT_TRUE(createPbufferSurface(mDisplay, config, kWidth, kHeight, &pbufferSurface));

    // Create the two contextss
    EXPECT_TRUE(createContext(config, &mContexts[0]));
    EXPECT_TRUE(createContext(config, &mContexts[1], mContexts[0]));

    eglMakeCurrent(mDisplay, mSurface, mSurface, mContexts[0]);
    ANGLE_SKIP_TEST_IF(!platformSupportsMultithreading());
    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);

    // 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,
        TextureInitialized,
        Finish,
        Abort,
    };

    Step currentStep = Step::Start;

    // Sample a texture in the swap thread.
    std::thread swapThread = std::thread([&]() {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Start));
        eglMakeCurrent(mDisplay, mSurface, mSurface, mContexts[0]);

        glGenTextures(1, &mTexture);
        glBindTexture(GL_TEXTURE_2D, mTexture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kWidth, kHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     nullptr);

        threadSynchronization.nextStep(Step::TextureInitialized);

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

        for (int i = 0; i < 100; ++i)
        {
            glClear(GL_COLOR_BUFFER_BIT);
            drawQuad(program, essl1_shaders::PositionAttrib(), 0.5f);
            EXPECT_GL_NO_ERROR();
            eglSwapBuffers(mDisplay, mSurface);
        }
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        eglReleaseThread();

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

    // Render to the texture in the render thread.
    std::thread renderThread = std::thread([&]() {
        ThreadSynchronization<Step> threadSynchronization(&currentStep, &mutex, &condVar);
        ASSERT_EGL_TRUE(eglMakeCurrent(mDisplay, pbufferSurface, pbufferSurface, mContexts[1]));

        GLFramebuffer fbo;
        glBindFramebuffer(GL_FRAMEBUFFER, fbo);

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

        // The render thread will draw to the texture.
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::TextureInitialized));
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, mTexture, 0);
        glDisable(GL_DEPTH_TEST);

        for (int i = 0; i < 400; ++i)
        {
            glClear(GL_COLOR_BUFFER_BIT);
            glUseProgram(redProgram);
            drawQuad(redProgram, essl1_shaders::PositionAttrib(), 0.5f);

            glClear(GL_COLOR_BUFFER_BIT);
            glUseProgram(greenProgram);
            drawQuad(greenProgram, essl1_shaders::PositionAttrib(), 0.5f);

            glClear(GL_COLOR_BUFFER_BIT);
            glUseProgram(blueProgram);
            drawQuad(blueProgram, essl1_shaders::PositionAttrib(), 0.5f);
        }
        eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
        eglReleaseThread();

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

    swapThread.join();
    renderThread.join();

    eglDestroySurface(mDisplay, pbufferSurface);
    ASSERT_EGL_SUCCESS();
}

class EGLContextSharingTestNoSyncTextureUploads : public EGLContextSharingTest
{};

// Test that an application that does not synchronize when using textures across shared contexts can
// still see texture updates. This behavior is not required by the GLES specification, but is
// exhibited by some applications. That application will malfunction if our implementation does not
// handle this in the way it expects. Only the vulkan backend has the workaround needed for this
// usecase.
TEST_P(EGLContextSharingTestNoSyncTextureUploads, NoSync)
{
    EGLDisplay display = getEGLWindow()->getDisplay();
    EGLConfig config   = getEGLWindow()->getConfig();

    const EGLint inShareGroupContextAttribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
    const EGLint pbufferAttributes[]          = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};

    constexpr size_t kThreadCount    = 2;
    std::array<EGLSurface, kThreadCount> surface = {EGL_NO_SURFACE, EGL_NO_SURFACE};

    for (size_t t = 0; t < kThreadCount; ++t)
    {
        mContexts[t] = eglCreateContext(display, config, t == 0 ? EGL_NO_CONTEXT : mContexts[0],
                                        inShareGroupContextAttribs);
        ASSERT_EGL_SUCCESS();
        ASSERT_NE(EGL_NO_CONTEXT, mContexts[t]);

        surface[t] = eglCreatePbufferSurface(display, config, pbufferAttributes);
        EXPECT_EGL_SUCCESS();
        ASSERT_NE(EGL_NO_SURFACE, surface[t]);
    }

    GLTexture textureFromCtx0;
    constexpr size_t kTextureCount = 10;
    std::array<GLTexture, kTextureCount> textures;

    // 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,
        Ctx0Current,
        Ctx1Current,
        TexturesDone,
        Finish,
        Abort,
    };
    Step currentStep = Step::Start;

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

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Start));
        ASSERT_EGL_TRUE(eglMakeCurrent(display, surface[0], surface[0], mContexts[0]));
        ASSERT_EGL_SUCCESS();
        threadSynchronization.nextStep(Step::Ctx0Current);

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

        // Create the shared textures that will be accessed by the other context
        glBindTexture(GL_TEXTURE_2D, textureFromCtx0);
        glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

        ASSERT_GL_TRUE(glIsTexture(textureFromCtx0));

        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::red);
        glFinish();

        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &GLColor::blue);
        // Do not glFinish

        // We set 6 to be the threshold to flush texture updates.
        // We create redundant textures here to ensure that we trigger that threshold.
        for (size_t i = 0; i < kTextureCount; i++)
        {
            glBindTexture(GL_TEXTURE_2D, textures[i]);
            glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1);
            glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

            ASSERT_GL_TRUE(glIsTexture(textures[i]));

            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE,
                            &GLColor::blue);
        }

        ASSERT_GL_NO_ERROR();

        threadSynchronization.nextStep(Step::TexturesDone);
        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Finish));
        ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        ASSERT_EGL_SUCCESS();
    });

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

        ASSERT_TRUE(threadSynchronization.waitForStep(Step::Ctx0Current));
        ASSERT_EGL_TRUE(eglMakeCurrent(display, surface[1], surface[1], mContexts[1]));
        ASSERT_EGL_SUCCESS();
        threadSynchronization.nextStep(Step::Ctx1Current);

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

        ASSERT_GL_TRUE(glIsTexture(textureFromCtx0));
        ASSERT_GL_NO_ERROR();

        // Draw using ctx0 texture as sampler
        GLTexture ctx1tex;
        glBindTexture(GL_TEXTURE_2D, ctx1tex);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE,
                     GLColor::black.data());
        ASSERT_GL_NO_ERROR();

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

        GLuint sampler;
        glGenSamplers(1, &sampler);

        ASSERT_GL_NO_ERROR();

        ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Texture2D(), essl1_shaders::fs::Texture2D());
        glUseProgram(program);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, textureFromCtx0);
        glBindSampler(0, sampler);
        glUniform1i(glGetUniformLocation(program, essl1_shaders::PositionAttrib()), 0);
        ASSERT_GL_NO_ERROR();

        drawQuad(program, essl1_shaders::PositionAttrib(), 0.5);
        ASSERT_GL_NO_ERROR();

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

        threadSynchronization.nextStep(Step::Finish);
        ASSERT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        ASSERT_EGL_SUCCESS();
    });

    creatingThread.join();
    samplingThread.join();

    ASSERT_NE(currentStep, Step::Abort);
    ASSERT_EGL_SUCCESS();

    for (size_t t = 0; t < kThreadCount; ++t)
    {
        ASSERT_EGL_TRUE(eglDestroySurface(display, surface[t]));
        ASSERT_EGL_SUCCESS();
    }
}

// Tests that creating a context and immediately destroying it works when no surface has been
// created.
TEST_P(EGLContextSharingTestNoFixture, ImmediateContextDestroyAfterCreation)
{
    EGLAttrib dispattrs[]  = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(),
                              EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE,
                              static_cast<EGLAttrib>(mOsWindow->getNativeDisplayPlatformType()),
                              EGL_NONE};
    mDisplay               = eglGetPlatformDisplay(GetEglPlatform(),
                                                   reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
    EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
    EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));

    EGLConfig config = EGL_NO_CONFIG_KHR;
    EXPECT_TRUE(chooseConfig(mDisplay, &config));

    // Create a context and immediately destroy it.  Note that no window surface should be created
    // for this test.  Regression test for platforms that expose multiple queue families in Vulkan,
    // and ANGLE defers creation of the device until a surface is created.  In this case, the
    // context is being destroyed before a queue is ever created.
    EXPECT_TRUE(createContext(config, &mContexts[0]));
    EXPECT_TRUE(SafeDestroyContext(mDisplay, mContexts[0]));
    ASSERT_EGL_SUCCESS();
}

class EGLPriorityContextSharingTestNoFixture : public EGLContextSharingTest
{
  public:
    EGLPriorityContextSharingTestNoFixture() : EGLContextSharingTest() {}

    void testSetUp() override
    {
        mMajorVersion          = GetParam().majorVersion;
        EGLAttrib dispattrs[]  = {EGL_PLATFORM_ANGLE_TYPE_ANGLE, GetParam().getRenderer(),
                                  EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE,
                                  static_cast<EGLAttrib>(GetPbufferOnlyDefaultPlatformType()),
                                  EGL_NONE};
        mDisplay               = eglGetPlatformDisplay(GetEglPlatform(),
                                                       reinterpret_cast<void *>(EGL_DEFAULT_DISPLAY), dispattrs);
        EXPECT_TRUE(mDisplay != EGL_NO_DISPLAY);
        EXPECT_EGL_TRUE(eglInitialize(mDisplay, nullptr, nullptr));
    }

    void testTearDown() override
    {
        ASSERT_EGL_SUCCESS() << "Error during EGLPriorityContextSharingTestNoFixture TearDown";
    }

    EGLDisplay mDisplay  = EGL_NO_DISPLAY;
    const EGLint kWidth  = 64;
    const EGLint kHeight = 64;
    EGLint mMajorVersion = 0;
};

// Tests that create and destroy higher priority shared context
TEST_P(EGLPriorityContextSharingTestNoFixture, MultiContextsCreateDestroy)
{
    ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(mDisplay, "EGL_IMG_context_priority"));

    EGLConfig config = EGL_NO_CONFIG_KHR;
    EXPECT_TRUE(chooseConfig(mDisplay, &config));

    // Initialize contexts
    constexpr size_t kContextCount = 2;

    std::array<EGLSurface, kContextCount> surface = {EGL_NO_SURFACE, EGL_NO_SURFACE};
    std::array<EGLContext, kContextCount> ctx     = {EGL_NO_CONTEXT, EGL_NO_CONTEXT};

    std::array<EGLint, kContextCount> priorities = {EGL_CONTEXT_PRIORITY_LOW_IMG,
                                                    EGL_CONTEXT_PRIORITY_HIGH_IMG};

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

    EGLint attributes[] = {EGL_CONTEXT_PRIORITY_LEVEL_IMG, EGL_NONE, EGL_NONE};

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

        attributes[1] = priorities[t];

        ctx[t] = eglCreateContext(mDisplay, config, t == 0 ? EGL_NO_CONTEXT : ctx[0], attributes);
        EXPECT_NE(EGL_NO_CONTEXT, ctx[t]);
        EXPECT_EGL_SUCCESS();

        eglMakeCurrent(mDisplay, surface[t], surface[t], ctx[t]);
        EXPECT_EGL_SUCCESS();
    }

    eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    for (size_t t = 0; t < kContextCount; ++t)
    {
        eglDestroySurface(mDisplay, surface[t]);
        eglDestroyContext(mDisplay, ctx[t]);
        EXPECT_EGL_SUCCESS();
    }

    eglTerminate(mDisplay);
    mDisplay = EGL_NO_DISPLAY;
    ASSERT_EGL_SUCCESS();
    eglReleaseThread();
    ASSERT_EGL_SUCCESS();
}
}  // anonymous namespace

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLContextSharingTest);
ANGLE_INSTANTIATE_TEST(EGLContextSharingTest,
                       ES2_D3D11(),
                       ES3_D3D11(),
                       ES2_METAL(),
                       ES3_METAL(),
                       ES2_OPENGL(),
                       ES3_OPENGL(),
                       ES2_VULKAN(),
                       ES3_VULKAN());

ANGLE_INSTANTIATE_TEST(EGLContextSharingTestNoFixture,
                       WithNoFixture(ES2_METAL()),
                       WithNoFixture(ES3_METAL()),
                       WithNoFixture(ES2_OPENGLES()),
                       WithNoFixture(ES3_OPENGLES()),
                       WithNoFixture(ES2_OPENGL()),
                       WithNoFixture(ES3_OPENGL()),
                       WithNoFixture(ES2_VULKAN()),
                       WithNoFixture(ES3_VULKAN()));

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLContextSharingTestNoSyncTextureUploads);
ANGLE_INSTANTIATE_TEST(EGLContextSharingTestNoSyncTextureUploads,
                       ES2_VULKAN().enable(Feature::ForceSubmitImmutableTextureUpdates),
                       ES3_VULKAN().enable(Feature::ForceSubmitImmutableTextureUpdates));

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(EGLPriorityContextSharingTestNoFixture);
ANGLE_INSTANTIATE_TEST(EGLPriorityContextSharingTestNoFixture, WithNoFixture(ES3_VULKAN()));
