//
// Copyright 2019 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.
//
// EGLSyncTest.cpp:
//   Tests of EGL_KHR_fence_sync and EGL_KHR_wait_sync extensions.

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

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

#include <array>
#include <condition_variable>

using namespace angle;

class EGLSyncTest : public ANGLETest<>
{
  protected:
    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"); }

    bool hasAndroidNativeFenceSyncExtension() const
    {
        return IsEGLDisplayExtensionEnabled(getEGLWindow()->getDisplay(),
                                            "EGL_ANDROID_native_fence_sync");
    }
};

// Test error cases for all EGL_KHR_fence_sync functions
TEST_P(EGLSyncTest, FenceSyncErrors)
{
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());

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

    // If the client API doesn't have the necessary extension, test that sync creation fails and
    // ignore the rest of the tests.
    if (!hasGLSyncExtension())
    {
        EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr));
        EXPECT_EGL_ERROR(EGL_BAD_MATCH);
    }

    ANGLE_SKIP_TEST_IF(!hasGLSyncExtension());

    EGLContext context     = eglGetCurrentContext();
    EGLSurface drawSurface = eglGetCurrentSurface(EGL_DRAW);
    EGLSurface readSurface = eglGetCurrentSurface(EGL_READ);

    EXPECT_NE(context, EGL_NO_CONTEXT);
    EXPECT_NE(drawSurface, EGL_NO_SURFACE);
    EXPECT_NE(readSurface, EGL_NO_SURFACE);

    // CreateSync with no attribute shouldn't cause an error
    EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
    EXPECT_NE(sync, EGL_NO_SYNC_KHR);

    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));

    // CreateSync with empty attribute shouldn't cause an error
    const EGLint emptyAttributes[] = {EGL_NONE};
    sync                           = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, emptyAttributes);
    EXPECT_NE(sync, EGL_NO_SYNC_KHR);

    // DestroySync generates BAD_PARAMETER if the sync is not valid
    EXPECT_EGL_FALSE(eglDestroySyncKHR(display, reinterpret_cast<EGLSyncKHR>(20)));
    EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);

    // CreateSync generates BAD_DISPLAY if display is not valid
    EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(EGL_NO_DISPLAY, EGL_SYNC_FENCE_KHR, nullptr));
    EXPECT_EGL_ERROR(EGL_BAD_DISPLAY);

    // CreateSync generates BAD_ATTRIBUTE if attribute is neither nullptr nor empty.
    const EGLint nonEmptyAttributes[] = {
        EGL_CL_EVENT_HANDLE,
        0,
        EGL_NONE,
    };
    EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nonEmptyAttributes));
    EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);

    // CreateSync generates BAD_ATTRIBUTE if type is not valid
    EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, 0, nullptr));
    EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);

    // CreateSync generates BAD_MATCH if no context is current
    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    EXPECT_EQ(EGL_NO_SYNC_KHR, eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr));
    EXPECT_EGL_ERROR(EGL_BAD_MATCH);
    eglMakeCurrent(display, drawSurface, readSurface, context);

    // ClientWaitSync generates EGL_BAD_PARAMETER if the sync object is not valid
    EXPECT_EGL_FALSE(eglClientWaitSyncKHR(display, reinterpret_cast<EGLSyncKHR>(30), 0, 0));
    EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);

    // GetSyncAttrib generates EGL_BAD_PARAMETER if the sync object is not valid, and value is not
    // modified
    constexpr EGLint kSentinelAttribValue = 123456789;
    EGLint attribValue                    = kSentinelAttribValue;
    EXPECT_EGL_FALSE(eglGetSyncAttribKHR(display, reinterpret_cast<EGLSyncKHR>(40),
                                         EGL_SYNC_TYPE_KHR, &attribValue));
    EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
    EXPECT_EQ(attribValue, kSentinelAttribValue);

    // GetSyncAttrib generates EGL_BAD_ATTRIBUTE if the attribute is not valid, and value is not
    // modified
    EXPECT_EGL_FALSE(eglGetSyncAttribKHR(display, sync, EGL_CL_EVENT_HANDLE, &attribValue));
    EXPECT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
    EXPECT_EQ(attribValue, kSentinelAttribValue);

    // GetSyncAttrib generates EGL_BAD_MATCH if the attribute is valid for sync, but not the
    // particular sync type. We don't have such a case at the moment.

    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
}

// Test error cases for all EGL_KHR_wait_sync functions
TEST_P(EGLSyncTest, WaitSyncErrors)
{
    // The client API that shows support for eglWaitSyncKHR is the same as the one required for
    // eglCreateSyncKHR.  As such, there is no way to create a sync and not be able to wait on it.
    // This would have created an EGL_BAD_MATCH error.
    ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());

    EGLDisplay display     = getEGLWindow()->getDisplay();
    EGLContext context     = eglGetCurrentContext();
    EGLSurface drawSurface = eglGetCurrentSurface(EGL_DRAW);
    EGLSurface readSurface = eglGetCurrentSurface(EGL_READ);

    EXPECT_NE(context, EGL_NO_CONTEXT);
    EXPECT_NE(drawSurface, EGL_NO_SURFACE);
    EXPECT_NE(readSurface, EGL_NO_SURFACE);

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

    // WaitSync generates BAD_MATCH if no context is current
    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    EXPECT_EGL_FALSE(eglWaitSyncKHR(display, sync, 0));
    EXPECT_EGL_ERROR(EGL_BAD_MATCH);
    eglMakeCurrent(display, drawSurface, readSurface, context);

    // WaitSync generates BAD_PARAMETER if the sync is not valid
    EXPECT_EGL_FALSE(eglWaitSyncKHR(display, reinterpret_cast<EGLSyncKHR>(20), 0));
    EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);

    // WaitSync generates BAD_PARAMETER if flags is non-zero
    EXPECT_EGL_FALSE(eglWaitSyncKHR(display, sync, 1));
    EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);

    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
}

// Test usage of eglGetSyncAttribKHR
TEST_P(EGLSyncTest, GetSyncAttrib)
{
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());

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

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

    // Fence sync attributes are:
    //
    // EGL_SYNC_TYPE_KHR: EGL_SYNC_FENCE_KHR
    // EGL_SYNC_STATUS_KHR: EGL_UNSIGNALED_KHR or EGL_SIGNALED_KHR
    // EGL_SYNC_CONDITION_KHR: EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR

    constexpr EGLint kSentinelAttribValue = 123456789;
    EGLint attribValue                    = kSentinelAttribValue;
    EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_TYPE_KHR, &attribValue));
    EXPECT_EQ(attribValue, EGL_SYNC_FENCE_KHR);

    attribValue = kSentinelAttribValue;
    EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_CONDITION_KHR, &attribValue));
    EXPECT_EQ(attribValue, EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR);

    attribValue = kSentinelAttribValue;
    EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_STATUS_KHR, &attribValue));

    // Hack around EXPECT_* not having an "either this or that" variant:
    if (attribValue != EGL_SIGNALED_KHR)
    {
        EXPECT_EQ(attribValue, EGL_UNSIGNALED_KHR);
    }

    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
}

// Test that basic usage works and doesn't generate errors or crash
TEST_P(EGLSyncTest, BasicOperations)
{
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());

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

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

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

    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_EGL_TRUE(eglWaitSyncKHR(display, sync, 0));

    glFlush();

    glClear(GL_COLOR_BUFFER_BIT);

    // Don't wait forever to make sure the test terminates
    constexpr GLuint64 kTimeout = 1'000'000'000;  // 1 second
    EGLint value                = 0;
    ASSERT_EQ(EGL_CONDITION_SATISFIED_KHR,
              eglClientWaitSyncKHR(display, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, kTimeout));

    for (size_t i = 0; i < 20; i++)
    {
        glClear(GL_COLOR_BUFFER_BIT);
        EXPECT_EQ(
            EGL_CONDITION_SATISFIED_KHR,
            eglClientWaitSyncKHR(display, sync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR));
        EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync, EGL_SYNC_STATUS_KHR, &value));
        EXPECT_EQ(value, EGL_SIGNALED_KHR);
    }

    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
}

// Test that eglClientWaitSync* APIs work.
TEST_P(EGLSyncTest, EglClientWaitSync)
{
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());

    EGLDisplay display = getEGLWindow()->getDisplay();
    ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());

    // Test eglClientWaitSyncKHR
    for (size_t i = 0; i < 5; i++)
    {
        glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        drawQuad(greenProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
        ASSERT_GL_NO_ERROR();

        // Don't wait forever to make sure the test terminates
        constexpr GLuint64 kTimeout = 1'000'000'000;  // 1 second
        EGLSyncKHR clientWaitSync   = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
        EXPECT_NE(clientWaitSync, EGL_NO_SYNC_KHR);

        ASSERT_EQ(EGL_CONDITION_SATISFIED_KHR,
                  eglClientWaitSyncKHR(display, clientWaitSync, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
                                       kTimeout));

        EXPECT_EGL_TRUE(eglDestroySyncKHR(display, clientWaitSync));
        ASSERT_EGL_SUCCESS();
    }

    // Test eglClientWaitSync
    for (size_t i = 0; i < 5; i++)
    {
        glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
        drawQuad(greenProgram, std::string(essl1_shaders::PositionAttrib()), 0.0f);
        ASSERT_GL_NO_ERROR();

        // Don't wait forever to make sure the test terminates
        constexpr GLuint64 kTimeout = 1'000'000'000;  // 1 second
        EGLSyncKHR clientWaitSync   = eglCreateSync(display, EGL_SYNC_FENCE, nullptr);
        EXPECT_NE(clientWaitSync, EGL_NO_SYNC);

        ASSERT_EQ(
            EGL_CONDITION_SATISFIED,
            eglClientWaitSync(display, clientWaitSync, EGL_SYNC_FLUSH_COMMANDS_BIT, kTimeout));

        EXPECT_EGL_TRUE(eglDestroySync(display, clientWaitSync));
        ASSERT_EGL_SUCCESS();
    }
}

// Test eglWaitClient api
TEST_P(EGLSyncTest, WaitClient)
{
    // Clear to red color
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);

    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_EGL_TRUE(eglWaitClient());
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);

    EGLDisplay display = getEGLWindow()->getDisplay();
    EGLContext context = getEGLWindow()->getContext();
    EGLSurface surface = getEGLWindow()->getSurface();
    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    EXPECT_EGL_TRUE(eglWaitClient());
    eglMakeCurrent(display, surface, surface, context);
}

// Test eglWaitGL api
TEST_P(EGLSyncTest, WaitGL)
{
    // Clear to red color
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);

    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_EGL_TRUE(eglWaitGL());
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);

    EGLDisplay display = getEGLWindow()->getDisplay();
    EGLContext context = getEGLWindow()->getContext();
    EGLSurface surface = getEGLWindow()->getSurface();
    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    EXPECT_EGL_TRUE(eglWaitGL());
    eglMakeCurrent(display, surface, surface, context);
}

// Test eglWaitNative api
TEST_P(EGLSyncTest, WaitNative)
{
    // Clear to red color
    glClearColor(1.0f, 0.0f, 0.0f, 1.0f);

    glClear(GL_COLOR_BUFFER_BIT);
    EXPECT_EGL_TRUE(eglWaitNative(EGL_CORE_NATIVE_ENGINE));
    EXPECT_PIXEL_COLOR_EQ(getWindowWidth() / 2, getWindowHeight() / 2, GLColor::red);

    EGLDisplay display = getEGLWindow()->getDisplay();
    EGLContext context = getEGLWindow()->getContext();
    EGLSurface surface = getEGLWindow()->getSurface();
    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    EXPECT_EGL_TRUE(eglWaitNative(EGL_CORE_NATIVE_ENGINE));
    eglMakeCurrent(display, surface, surface, context);
}

// Verify eglDupNativeFence for EGL_ANDROID_native_fence_sync
TEST_P(EGLSyncTest, AndroidNativeFence_DupNativeFenceFD)
{
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());

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

    // We can ClientWait on this
    EGLSyncKHR syncWithGeneratedFD =
        eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
    EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);

    int fd = eglDupNativeFenceFDANDROID(display, syncWithGeneratedFD);

    // Clean up created objects.
    if (fd != EGL_NO_NATIVE_FENCE_FD_ANDROID)
    {
        EXPECT_EGL_SUCCESS();
        close(fd);
    }
    else
    {
        // For some driver, eglDupNativeFenceFDANDROID() may return -1 with EGL_BAD_PARAMETER, if
        // the sync has been signalled.
        EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
        EGLint value;
        EXPECT_EGL_TRUE(
            eglGetSyncAttribKHR(display, syncWithGeneratedFD, EGL_SYNC_STATUS_KHR, &value));
        EXPECT_EQ(value, EGL_SIGNALED_KHR);

        EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithGeneratedFD,
                                            EGL_SYNC_NATIVE_FENCE_FD_ANDROID, &value));
        EXPECT_EQ(value, EGL_NO_NATIVE_FENCE_FD_ANDROID);
    }

    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
}

// Test the validation errors for bad parameters for eglDupNativeFenceFDANDROID
TEST_P(EGLSyncTest, AndroidNativeFence_DupNativeFenceFD_NegativeValidation)
{
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());

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

    int fd;
    fd = eglDupNativeFenceFDANDROID(display, EGL_NO_SYNC_KHR);
    EXPECT_EGL_ERROR(EGL_BAD_PARAMETER);
    EXPECT_EQ(fd, EGL_NO_NATIVE_FENCE_FD_ANDROID);
}

// Verify CreateSync and ClientWait for EGL_ANDROID_native_fence_sync
TEST_P(EGLSyncTest, AndroidNativeFence_ClientWait)
{
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());

    EGLint value       = 0;
    EGLDisplay display = getEGLWindow()->getDisplay();

    // We can ClientWait on this
    EGLSyncKHR syncWithGeneratedFD =
        eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
    EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);

    // Create work to do
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();

    // Wait for draw to complete
    EXPECT_EQ(EGL_CONDITION_SATISFIED,
              eglClientWaitSyncKHR(display, syncWithGeneratedFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
                                   1'000'000'000));
    EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithGeneratedFD, EGL_SYNC_STATUS_KHR, &value));
    EXPECT_EQ(value, EGL_SIGNALED_KHR);

    // Clean up created objects.
    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
}

// Verify WaitSync with EGL_ANDROID_native_fence_sync
// Simulate passing FDs across processes by passing across Contexts.
TEST_P(EGLSyncTest, AndroidNativeFence_WaitSync)
{
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());

    EGLint value       = 0;
    EGLDisplay display = getEGLWindow()->getDisplay();
    EGLSurface surface = getEGLWindow()->getSurface();

    /*- First Context ------------------------*/

    // We can ClientWait on this
    EGLSyncKHR syncWithGeneratedFD =
        eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
    EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);

    int fd = eglDupNativeFenceFDANDROID(display, syncWithGeneratedFD);
    EXPECT_EGL_SUCCESS();  // Can return -1 (when signaled) or valid FD.

    // Create work to do
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();

    /*- Second Context ------------------------*/
    if (fd > EGL_NO_NATIVE_FENCE_FD_ANDROID)
    {
        EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        EGLContext context2 = getEGLWindow()->createContext(EGL_NO_CONTEXT, nullptr);
        EXPECT_EGL_TRUE(eglMakeCurrent(display, surface, surface, context2));

        // We can eglWaitSync on this - import FD from first sync.
        EGLint syncAttribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, (EGLint)fd, EGL_NONE};
        EGLSyncKHR syncWithDupFD =
            eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, syncAttribs);
        EXPECT_NE(syncWithDupFD, EGL_NO_SYNC_KHR);

        // Second draw waits for first to complete. May already be signaled - ignore error.
        if (eglWaitSyncKHR(display, syncWithDupFD, 0) == EGL_TRUE)
        {
            // Create work to do
            glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
            glFlush();
        }

        // Wait for second draw to complete
        EXPECT_EQ(EGL_CONDITION_SATISFIED,
                  eglClientWaitSyncKHR(display, syncWithDupFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
                                       1000000000));
        EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithDupFD, EGL_SYNC_STATUS_KHR, &value));
        EXPECT_EQ(value, EGL_SIGNALED_KHR);

        // Reset to default context and surface.
        EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_TRUE(eglMakeCurrent(display, surface, surface, getEGLWindow()->getContext()));

        // Clean up created objects.
        EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithDupFD));
        EXPECT_EGL_TRUE(eglDestroyContext(display, context2));
    }

    // Wait for first draw to complete
    EXPECT_EQ(EGL_CONDITION_SATISFIED,
              eglClientWaitSyncKHR(display, syncWithGeneratedFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
                                   1000000000));
    EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithGeneratedFD, EGL_SYNC_STATUS_KHR, &value));
    EXPECT_EQ(value, EGL_SIGNALED_KHR);

    // Clean up created objects.
    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
}

// Verify EGL_ANDROID_native_fence_sync
// Simulate passing FDs across processes by passing across Contexts.
TEST_P(EGLSyncTest, AndroidNativeFence_withFences)
{
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());

    EGLint value       = 0;
    EGLDisplay display = getEGLWindow()->getDisplay();
    EGLSurface surface = getEGLWindow()->getSurface();

    /*- First Context ------------------------*/

    // Extra fence syncs to ensure that Fence and Android Native fences work together
    EGLSyncKHR syncFence1 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
    EXPECT_NE(syncFence1, EGL_NO_SYNC_KHR);

    // We can ClientWait on this
    EGLSyncKHR syncWithGeneratedFD =
        eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
    EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);

    int fd = eglDupNativeFenceFDANDROID(display, syncWithGeneratedFD);
    EXPECT_EGL_SUCCESS();  // Can return -1 (when signaled) or valid FD.

    EGLSyncKHR syncFence2 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
    EXPECT_NE(syncFence2, EGL_NO_SYNC_KHR);

    // Create work to do
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glFlush();

    /*- Second Context ------------------------*/
    if (fd > EGL_NO_NATIVE_FENCE_FD_ANDROID)
    {
        EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));

        EGLContext context2 = getEGLWindow()->createContext(EGL_NO_CONTEXT, nullptr);
        EXPECT_EGL_TRUE(eglMakeCurrent(display, surface, surface, context2));

        // check that Fence and Android fences work together
        EGLSyncKHR syncFence3 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
        EXPECT_NE(syncFence3, EGL_NO_SYNC_KHR);

        // We can eglWaitSync on this
        EGLint syncAttribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, (EGLint)fd, EGL_NONE};
        EGLSyncKHR syncWithDupFD =
            eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, syncAttribs);
        EXPECT_NE(syncWithDupFD, EGL_NO_SYNC_KHR);

        EGLSyncKHR syncFence4 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
        EXPECT_NE(syncFence4, EGL_NO_SYNC_KHR);

        // Second draw waits for first to complete. May already be signaled - ignore error.
        if (eglWaitSyncKHR(display, syncWithDupFD, 0) == EGL_TRUE)
        {
            // Create work to do
            glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
            glClear(GL_COLOR_BUFFER_BIT);
            glFlush();
        }

        // Wait for second draw to complete
        EXPECT_EQ(EGL_CONDITION_SATISFIED,
                  eglClientWaitSyncKHR(display, syncWithDupFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
                                       1000000000));
        EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithDupFD, EGL_SYNC_STATUS_KHR, &value));
        EXPECT_EQ(value, EGL_SIGNALED_KHR);

        // Reset to default context and surface.
        EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_TRUE(eglMakeCurrent(display, surface, surface, getEGLWindow()->getContext()));

        // Clean up created objects.
        EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncFence3));
        EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncFence4));
        EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithDupFD));
        EXPECT_EGL_TRUE(eglDestroyContext(display, context2));
    }

    // Wait for first draw to complete
    EXPECT_EQ(EGL_CONDITION_SATISFIED,
              eglClientWaitSyncKHR(display, syncWithGeneratedFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
                                   1000000000));
    EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithGeneratedFD, EGL_SYNC_STATUS_KHR, &value));
    EXPECT_EQ(value, EGL_SIGNALED_KHR);

    // Clean up created objects.
    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncFence1));
    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncFence2));
    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
}

// Verify that VkSemaphore is not destroyed before used for waiting
TEST_P(EGLSyncTest, AndroidNativeFence_VkSemaphoreDestroyBug)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasWaitSyncExtension() || !hasGLSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());

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

    glFinish();  // Ensure no pending commands

    EGLSyncKHR syncWithGeneratedFD =
        eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
    EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);
    EXPECT_EGL_TRUE(eglWaitSyncKHR(display, syncWithGeneratedFD, 0));
    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));
    glFinish();  // May destroy VkSemaphore if bug is present.

    // Create work to do
    glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    glFinish();  // Will submit destroyed Semaphores.
}

// Verify that no VVL errors are generated when External Fence Handle is used to track submissions
TEST_P(EGLSyncTest, AndroidNativeFence_ExternalFenceWaitVVLBug)
{
    ANGLE_SKIP_TEST_IF(!IsVulkan());
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
    ANGLE_SKIP_TEST_IF(!hasAndroidNativeFenceSyncExtension());

    EGLint value       = 0;
    EGLDisplay display = getEGLWindow()->getDisplay();

    // Create work to do
    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
    drawQuad(program, essl1_shaders::PositionAttrib(), 0.0f);
    ASSERT_GL_NO_ERROR();

    // We can ClientWait on this
    EGLSyncKHR syncWithGeneratedFD =
        eglCreateSyncKHR(display, EGL_SYNC_NATIVE_FENCE_ANDROID, nullptr);
    EXPECT_NE(syncWithGeneratedFD, EGL_NO_SYNC_KHR);

    // Wait for draw to complete
    EXPECT_EQ(EGL_CONDITION_SATISFIED,
              eglClientWaitSyncKHR(display, syncWithGeneratedFD, EGL_SYNC_FLUSH_COMMANDS_BIT_KHR,
                                   1'000'000'000));
    EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, syncWithGeneratedFD, EGL_SYNC_STATUS_KHR, &value));
    EXPECT_EQ(value, EGL_SIGNALED_KHR);

    // Clean up created objects.
    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, syncWithGeneratedFD));

    // Finish to cleanup internal garbage in the backend.
    glFinish();
}

// Test functionality of EGL_ANGLE_global_fence_sync.
TEST_P(EGLSyncTest, GlobalFenceSync)
{
    EGLDisplay display = getEGLWindow()->getDisplay();

    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
    ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_global_fence_sync"));

    // Create a second context
    EGLContext context1     = eglGetCurrentContext();
    EGLSurface drawSurface1 = eglGetCurrentSurface(EGL_DRAW);
    EGLSurface readSurface1 = eglGetCurrentSurface(EGL_READ);
    EGLConfig config        = getEGLWindow()->getConfig();

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

    EGLContext context2 = eglCreateContext(display, config, context1, contextAttribs);
    ASSERT_NE(EGL_NO_CONTEXT, context2);

    const EGLint pbufferAttribs[] = {EGL_WIDTH, getWindowWidth(), EGL_HEIGHT, getWindowHeight(),
                                     EGL_NONE};
    EGLSurface drawSurface2       = eglCreatePbufferSurface(display, config, pbufferAttribs);
    ASSERT_NE(EGL_NO_SURFACE, drawSurface2);

    // Do an expensive draw in context 2
    eglMakeCurrent(display, drawSurface2, drawSurface2, context2);

    constexpr char kCostlyVS[] = R"(attribute highp vec4 position;
varying highp vec4 testPos;
void main(void)
{
    testPos     = position;
    gl_Position = position;
})";

    constexpr char kCostlyFS[] = R"(precision highp float;
varying highp vec4 testPos;
void main(void)
{
    vec4 test = testPos;
    for (int i = 0; i < 500; i++)
    {
        test = sqrt(test);
    }
    gl_FragColor = test;
})";

    ANGLE_GL_PROGRAM(expensiveProgram, kCostlyVS, kCostlyFS);
    drawQuad(expensiveProgram, "position", 0.0f);

    // Signal a fence sync for testing
    EGLSyncKHR sync2 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);

    // Switch to context 1, and create a global fence sync
    eglMakeCurrent(display, drawSurface1, readSurface1, context1);

    EGLSyncKHR sync1 = eglCreateSyncKHR(display, EGL_SYNC_GLOBAL_FENCE_ANGLE, nullptr);

    // Wait for the global fence sync to finish.
    constexpr GLuint64 kTimeout = 2'000'000'000;  // 2 seconds
    ASSERT_EQ(EGL_CONDITION_SATISFIED_KHR, eglClientWaitSyncKHR(display, sync1, 0, kTimeout));

    // If the global fence sync is signaled, then the signal from context2 must also be signaled.
    // Note that if sync1 was an EGL_SYNC_FENCE_KHR, this would not necessarily be true.
    EGLint value = 0;
    EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync2, EGL_SYNC_STATUS_KHR, &value));
    EXPECT_EQ(value, EGL_SIGNALED_KHR);

    EXPECT_EQ(EGL_CONDITION_SATISFIED_KHR, eglClientWaitSyncKHR(display, sync2, 0, 0));

    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync1));
    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync2));

    EXPECT_EGL_TRUE(eglDestroySurface(display, drawSurface2));
    EXPECT_EGL_TRUE(eglDestroyContext(display, context2));
}

// Test functionality of EGL_ANGLE_global_fence_sync in the presence of multiple threads.
TEST_P(EGLSyncTest, GlobalFenceSyncMultithreaded)
{
    EGLDisplay display = getEGLWindow()->getDisplay();

    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());
    ANGLE_SKIP_TEST_IF(!IsEGLDisplayExtensionEnabled(display, "EGL_ANGLE_global_fence_sync"));

    // Create a second context
    EGLContext context1     = eglGetCurrentContext();
    EGLSurface drawSurface1 = eglGetCurrentSurface(EGL_DRAW);
    EGLSurface readSurface1 = eglGetCurrentSurface(EGL_READ);
    EGLConfig config        = getEGLWindow()->getConfig();

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

    EGLContext context2 = eglCreateContext(display, config, context1, contextAttribs);
    ASSERT_NE(EGL_NO_CONTEXT, context2);

    const EGLint pbufferAttribs[] = {EGL_WIDTH, getWindowWidth(), EGL_HEIGHT, getWindowHeight(),
                                     EGL_NONE};
    EGLSurface drawSurface2       = eglCreatePbufferSurface(display, config, pbufferAttribs);
    ASSERT_NE(EGL_NO_SURFACE, drawSurface2);

    EGLSyncKHR sync2 = EGL_NO_SYNC_KHR;

    // Do an expensive draw in context 2, in a thread
    std::thread slowSubmit([&]() {
        eglMakeCurrent(display, drawSurface2, drawSurface2, context2);

        constexpr char kCostlyVS[] = R"(attribute highp vec4 position;
    varying highp vec4 testPos;
    void main(void)
    {
        testPos     = position;
        gl_Position = position;
    })";

        constexpr char kCostlyFS[] = R"(precision highp float;
    varying highp vec4 testPos;
    void main(void)
    {
        vec4 test = testPos;
        for (int i = 0; i < 500; i++)
        {
            test = sqrt(test);
        }
        gl_FragColor = test;
    })";

        ANGLE_GL_PROGRAM(expensiveProgram, kCostlyVS, kCostlyFS);
        drawQuad(expensiveProgram, "position", 0.0f);

        // Signal a fence sync for testing
        sync2 = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);

        // Release the context.  In the Vulkan backend, this frees the queue index assigned to the
        // context.
        eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    });
    slowSubmit.join();

    // Re-make-current the context.  In the Vulkan backend, this realloces the queue index assigned
    // to the context.
    eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
    eglMakeCurrent(display, drawSurface1, readSurface1, context1);

    // Create a global fence sync
    EGLSyncKHR sync1 = eglCreateSyncKHR(display, EGL_SYNC_GLOBAL_FENCE_ANGLE, nullptr);

    // Wait for the global fence sync to finish.
    constexpr GLuint64 kTimeout = 2'000'000'000;  // 2 seconds
    ASSERT_EQ(EGL_CONDITION_SATISFIED_KHR, eglClientWaitSyncKHR(display, sync1, 0, kTimeout));

    // If the global fence sync is signaled, then the signal from context2 must also be signaled.
    // Note that if sync1 was an EGL_SYNC_FENCE_KHR, this would not necessarily be true.
    EGLint value = 0;
    EXPECT_EGL_TRUE(eglGetSyncAttribKHR(display, sync2, EGL_SYNC_STATUS_KHR, &value));
    EXPECT_EQ(value, EGL_SIGNALED_KHR);

    EXPECT_EQ(EGL_CONDITION_SATISFIED_KHR, eglClientWaitSyncKHR(display, sync2, 0, 0));

    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync1));
    EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync2));

    EXPECT_EGL_TRUE(eglDestroySurface(display, drawSurface2));
    EXPECT_EGL_TRUE(eglDestroyContext(display, context2));
}

// Test that leaked fences are cleaned up in a safe way. Regression test for sync objects using tail
// calls for destruction.
TEST_P(EGLSyncTest, DISABLED_LeakSyncToDisplayDestruction)
{
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension());

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

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

// Test the validation errors for bad parameters for eglCreateSyncKHR
TEST_P(EGLSyncTest, NegativeValidationBadAttributes)
{
    EGLDisplay display = getEGLWindow()->getDisplay();
    EGLSyncKHR sync;
    static constexpr std::array<std::array<EGLint, 3>, 3> invalidCreateSyncAttributeList = {{
        {EGL_SYNC_CONDITION_KHR, EGL_NONE, 0},
        {EGL_SYNC_CONDITION_KHR, EGL_RENDERABLE_TYPE, EGL_NONE},
        {EGL_SYNC_CONDITION_KHR, EGL_SYNC_PRIOR_COMMANDS_COMPLETE_KHR, EGL_RENDERABLE_TYPE},
    }};

    for (size_t i = 0; i < 3; i++)
    {
        sync =
            eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, invalidCreateSyncAttributeList[i].data());

        ASSERT_EQ(sync, EGL_NO_SYNC_KHR);
        ASSERT_EGL_ERROR(EGL_BAD_ATTRIBUTE);
    }
}

// Tests that eglClientWaitSyncKHR() is not blocking when Vulkan CommandQueue performs CPU
// throttling during submission (when `kInFlightCommandsLimit` is exceeded).
TEST_P(EGLSyncTest, BlockingOnSubmitCPUThrottling)
{
    ANGLE_SKIP_TEST_IF(!isVulkanRenderer() || isSwiftshader());
    ANGLE_SKIP_TEST_IF(!hasFenceSyncExtension() || !hasGLSyncExtension());
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);

    // Should be somewhat larger than the `kInFlightCommandsLimit`.  At the same time,
    // `kInFlightCommandsLimit` should be less than the internal driver limit, otherwise test will
    // not work.
    constexpr size_t kMaxSyncCount = 100;

    constexpr GLsizei kBufferResolution = 1024;
    constexpr size_t kDrawsPerSync      = 2;

    constexpr double kLongWaitThresholdMs = 5.0;
    constexpr size_t kMinLongWaitsToFail  = 5;

    constexpr char kCostlyVS[] = R"(attribute highp vec4 position;
varying highp vec4 testPos;
void main(void)
{
    testPos     = position;
    gl_Position = position;
})";

    constexpr char kCostlyFS[] = R"(precision highp float;
varying highp vec4 testPos;
void main(void)
{
    vec4 test = testPos;
    for (int i = 0; i < 500; i++)
    {
        test = sqrt(test);
    }
    gl_FragColor = test;
})";

    std::array<EGLSyncKHR, kMaxSyncCount> syncArray;
    size_t syncCount = 0;
    std::mutex mutex;
    std::condition_variable condVar;
    size_t numLongWaits        = 0;
    bool isSyncWaitThreadReady = false;

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

    std::thread syncWaitThread([&]() {
        constexpr GLuint64 kTimeout = 0;  // Just check status

        EGLConfig config = getEGLWindow()->getConfig();

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

        EGLContext context2 = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
        ASSERT_NE(EGL_NO_CONTEXT, context2);

        const EGLint pbufferAttribs[] = {EGL_WIDTH, getWindowWidth(), EGL_HEIGHT, getWindowHeight(),
                                         EGL_NONE};
        EGLSurface drawSurface2       = eglCreatePbufferSurface(display, config, pbufferAttribs);
        ASSERT_NE(EGL_NO_SURFACE, drawSurface2);

        // Making some Context current just to prevent blocking in ANGLE_CAPTURE_EGL
        EXPECT_EGL_TRUE(eglMakeCurrent(display, drawSurface2, drawSurface2, context2));

        {
            std::unique_lock<std::mutex> lock(mutex);
            isSyncWaitThreadReady = true;
        }
        condVar.notify_one();

        for (size_t syncIndex = 0; syncIndex < kMaxSyncCount; ++syncIndex)
        {
            {
                std::unique_lock<std::mutex> lock(mutex);
                condVar.wait(lock, [&]() { return syncIndex < syncCount; });
            }
            while (true)
            {
                const double t1 = angle::GetCurrentSystemTime();
                EGLint result   = eglClientWaitSyncKHR(display, syncArray[syncIndex], 0, kTimeout);
                const double t2 = angle::GetCurrentSystemTime();
                if ((t2 - t1) * 1000.0 > kLongWaitThresholdMs)
                {
                    ++numLongWaits;
                }
                if (result != EGL_TIMEOUT_EXPIRED_KHR)
                {
                    EXPECT_EQ(result, EGL_CONDITION_SATISFIED_KHR);
                    break;
                }
                // Wait some time and try again...
                std::this_thread::sleep_for(std::chrono::microseconds(1000));
            }
        }

        EXPECT_EGL_TRUE(eglMakeCurrent(display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
        EXPECT_EGL_TRUE(eglDestroySurface(display, drawSurface2));
        EXPECT_EGL_TRUE(eglDestroyContext(display, context2));
    });

    // Prepare the framebuffer
    GLFramebuffer framebuffer;
    GLTexture fbTexture;
    glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
    glBindTexture(GL_TEXTURE_2D, fbTexture);
    glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kBufferResolution, kBufferResolution);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbTexture, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
    ASSERT_GL_NO_ERROR();
    glViewport(0, 0, kBufferResolution, kBufferResolution);

    ANGLE_GL_PROGRAM(program, kCostlyVS, kCostlyFS);

    // Wait until thread is ready waiting on EGL sync objects...
    {
        std::unique_lock<std::mutex> lock(mutex);
        condVar.wait(lock, [&]() { return isSyncWaitThreadReady; });
    }

    while (syncCount < kMaxSyncCount)
    {
        // Perform GPU heavy rendering
        for (size_t i = 0; i < kDrawsPerSync; ++i)
        {
            drawQuad(program, "position", 0.0f);
            ASSERT_GL_NO_ERROR();
        }

        // Using glFenceSync() to force submission without also blocking on the EGL Global mutex.
        GLsync clientWaitSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
        ASSERT_GL_NO_ERROR();
        constexpr GLuint64 kTimeout = 0;  // Just check status
        glClientWaitSync(clientWaitSync, GL_SYNC_FLUSH_COMMANDS_BIT, kTimeout);
        EXPECT_GL_NO_ERROR();
        glDeleteSync(clientWaitSync);
        ASSERT_GL_NO_ERROR();

        // Creating EGL sync should not block on submission, since glClientWaitSync() should have
        // already done that.
        EGLSyncKHR sync = eglCreateSyncKHR(display, EGL_SYNC_FENCE_KHR, nullptr);
        EXPECT_NE(sync, EGL_NO_SYNC_KHR);

        // Make sync ready for checking from another thread.
        syncArray[syncCount] = sync;
        {
            std::unique_lock<std::mutex> lock(mutex);
            ++syncCount;
        }
        condVar.notify_one();
    }

    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    syncWaitThread.join();

    for (EGLSyncKHR sync : syncArray)
    {
        EXPECT_EGL_TRUE(eglDestroySyncKHR(display, sync));
    }

    EXPECT_LT(numLongWaits, kMinLongWaitsToFail);
}

ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(EGLSyncTest,
                                       ES2_VULKAN().enable(Feature::EnableExtraSubmitFence),
                                       ES3_VULKAN().enable(Feature::EnableExtraSubmitFence));
