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

#ifdef UNSAFE_BUFFERS_BUILD
#    pragma allow_unsafe_buffers
#endif

#include <gtest/gtest.h>

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

#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 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;
    const EGLint invalidCreateSyncAttributeList[][3] = {
        {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][0]);

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