//
// Copyright 2020 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.
//
// egl_ext_stubs.cpp: Stubs for EXT extension entry points.
//

#include "libGLESv2/egl_ext_stubs_autogen.h"

#include "libANGLE/Device.h"
#include "libANGLE/Display.h"
#include "libANGLE/EGLSync.h"
#include "libANGLE/Surface.h"
#include "libANGLE/Thread.h"
#include "libANGLE/entry_points_utils.h"
#include "libANGLE/queryutils.h"
#include "libANGLE/renderer/DisplayImpl.h"
#include "libANGLE/validationEGL.h"
#include "libANGLE/validationEGL_autogen.h"
#include "libGLESv2/global_state.h"

namespace egl
{
EGLint ClientWaitSyncKHR(Thread *thread,
                         Display *display,
                         SyncID syncID,
                         EGLint flags,
                         EGLTimeKHR timeout)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglClientWaitSyncKHR",
                                          GetDisplayIfValid(display), EGL_FALSE);
    gl::Context *currentContext = thread->getContext();
    EGLint syncStatus           = EGL_FALSE;
    Sync *sync                  = display->getSync(syncID);
    ANGLE_EGL_TRY_RETURN(thread,
                         sync->clientWait(display, currentContext, flags, timeout, &syncStatus),
                         "eglClientWaitSyncKHR", GetSyncIfValid(display, syncID), EGL_FALSE);

    // When performing CPU wait through UnlockedTailCall we need to handle any error conditions
    if (egl::Display::GetCurrentThreadUnlockedTailCall()->any())
    {
        auto handleErrorStatus = [thread, display, syncID](void *result) {
            EGLint *eglResult = static_cast<EGLint *>(result);
            ASSERT(eglResult);
            if (*eglResult == EGL_FALSE)
            {
                thread->setError(egl::Error(EGL_BAD_ALLOC), "eglClientWaitSyncKHR",
                                 GetSyncIfValid(display, syncID));
            }
            else
            {
                thread->setSuccess();
            }
        };
        egl::Display::GetCurrentThreadUnlockedTailCall()->add(handleErrorStatus);
    }
    else
    {
        thread->setSuccess();
    }
    return syncStatus;
}

EGLImageKHR CreateImageKHR(Thread *thread,
                           Display *display,
                           gl::ContextID contextID,
                           EGLenum target,
                           EGLClientBuffer buffer,
                           const AttributeMap &attributes)
{
    gl::Context *context = display->getContext(contextID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglCreateImageKHR",
                                          GetDisplayIfValid(display), EGL_NO_IMAGE);

    Image *image = nullptr;
    ANGLE_EGL_TRY_RETURN(thread, display->createImage(context, target, buffer, attributes, &image),
                         "", GetDisplayIfValid(display), EGL_NO_IMAGE);

    thread->setSuccess();
    return reinterpret_cast<EGLImage>(static_cast<uintptr_t>(image->id().value));
}

EGLClientBuffer CreateNativeClientBufferANDROID(Thread *thread, const AttributeMap &attribMap)
{
    EGLClientBuffer eglClientBuffer = nullptr;
    ANGLE_EGL_TRY_RETURN(thread,
                         egl::Display::CreateNativeClientBuffer(attribMap, &eglClientBuffer),
                         "eglCreateNativeClientBufferANDROID", nullptr, nullptr);

    thread->setSuccess();
    return eglClientBuffer;
}

EGLSurface CreatePlatformPixmapSurfaceEXT(Thread *thread,
                                          Display *display,
                                          Config *configPacked,
                                          void *native_pixmap,
                                          const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglCreatePlatformPixmapSurfaceEXT",
                                          GetDisplayIfValid(display), EGL_NO_SURFACE);
    thread->setError(EGL_BAD_DISPLAY, "eglCreatePlatformPixmapSurfaceEXT",
                     GetDisplayIfValid(display), "CreatePlatformPixmapSurfaceEXT unimplemented.");
    return EGL_NO_SURFACE;
}

EGLSurface CreatePlatformWindowSurfaceEXT(Thread *thread,
                                          Display *display,
                                          Config *configPacked,
                                          void *native_window,
                                          const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglCreatePlatformWindowSurfaceEXT",
                                          GetDisplayIfValid(display), EGL_NO_SURFACE);
    Surface *surface = nullptr;

    // In X11, eglCreatePlatformWindowSurfaceEXT expects the native_window argument to be a pointer
    // to a Window while the EGLNativeWindowType for X11 is its actual value.
    // https://www.khronos.org/registry/EGL/extensions/KHR/EGL_KHR_platform_x11.txt
    void *actualNativeWindow =
        display->getImplementation()->getWindowSystem() == angle::NativeWindowSystem::X11
            ? *reinterpret_cast<void **>(native_window)
            : native_window;
    EGLNativeWindowType nativeWindow = reinterpret_cast<EGLNativeWindowType>(actualNativeWindow);

    ANGLE_EGL_TRY_RETURN(
        thread, display->createWindowSurface(configPacked, nativeWindow, attributes, &surface),
        "eglCreatePlatformWindowSurfaceEXT", GetDisplayIfValid(display), EGL_NO_SURFACE);

    return reinterpret_cast<EGLSurface>(static_cast<uintptr_t>(surface->id().value));
}

EGLStreamKHR CreateStreamKHR(Thread *thread, Display *display, const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglCreateStreamKHR",
                                          GetDisplayIfValid(display), EGL_NO_STREAM_KHR);
    Stream *stream;
    ANGLE_EGL_TRY_RETURN(thread, display->createStream(attributes, &stream), "eglCreateStreamKHR",
                         GetDisplayIfValid(display), EGL_NO_STREAM_KHR);

    thread->setSuccess();
    return static_cast<EGLStreamKHR>(stream);
}

EGLSyncKHR CreateSyncKHR(Thread *thread,
                         Display *display,
                         EGLenum type,
                         const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglCreateSyncKHR",
                                          GetDisplayIfValid(display), EGL_NO_SYNC);
    egl::Sync *syncObject = nullptr;
    ANGLE_EGL_TRY_RETURN(thread,
                         display->createSync(thread->getContext(), type, attributes, &syncObject),
                         "eglCreateSyncKHR", GetDisplayIfValid(display), EGL_NO_SYNC);

    thread->setSuccess();
    return reinterpret_cast<EGLSync>(static_cast<uintptr_t>(syncObject->id().value));
}

EGLint DebugMessageControlKHR(Thread *thread,
                              EGLDEBUGPROCKHR callback,
                              const AttributeMap &attributes)
{
    Debug *debug = GetDebug();
    debug->setCallback(callback, attributes);

    thread->setSuccess();
    return EGL_SUCCESS;
}

EGLBoolean DestroyImageKHR(Thread *thread, Display *display, egl::ImageID imageID)
{
    Image *img = display->getImage(imageID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglDestroyImageKHR",
                                          GetDisplayIfValid(display), EGL_FALSE);
    display->destroyImage(img);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean DestroyStreamKHR(Thread *thread, Display *display, Stream *streamObject)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglDestroyStreamKHR",
                                          GetDisplayIfValid(display), EGL_FALSE);
    display->destroyStream(streamObject);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean DestroySyncKHR(Thread *thread, Display *display, SyncID syncID)
{
    Sync *sync = display->getSync(syncID);
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglDestroySync",
                                          GetDisplayIfValid(display), EGL_FALSE);
    display->destroySync(sync);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLint DupNativeFenceFDANDROID(Thread *thread, Display *display, SyncID syncID)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglDupNativeFenceFDANDROID", GetDisplayIfValid(display),
                                          EGL_NO_NATIVE_FENCE_FD_ANDROID);
    EGLint result    = EGL_NO_NATIVE_FENCE_FD_ANDROID;
    Sync *syncObject = display->getSync(syncID);
    ANGLE_EGL_TRY_RETURN(thread, syncObject->dupNativeFenceFD(display, &result),
                         "eglDupNativeFenceFDANDROID", GetSyncIfValid(display, syncID),
                         EGL_NO_NATIVE_FENCE_FD_ANDROID);

    thread->setSuccess();
    return result;
}

EGLClientBuffer GetNativeClientBufferANDROID(Thread *thread, const struct AHardwareBuffer *buffer)
{
    thread->setSuccess();
    return egl::Display::GetNativeClientBuffer(buffer);
}

EGLDisplay GetPlatformDisplayEXT(Thread *thread,
                                 EGLenum platform,
                                 void *native_display,
                                 const AttributeMap &attribMap)
{
    switch (platform)
    {
        case EGL_PLATFORM_ANGLE_ANGLE:
        case EGL_PLATFORM_GBM_KHR:
        case EGL_PLATFORM_WAYLAND_EXT:
        case EGL_PLATFORM_SURFACELESS_MESA:
        {
            return egl::Display::GetDisplayFromNativeDisplay(
                platform, gl::bitCast<EGLNativeDisplayType>(native_display), attribMap);
        }
        case EGL_PLATFORM_DEVICE_EXT:
        {
            Device *eglDevice = static_cast<Device *>(native_display);
            return egl::Display::GetDisplayFromDevice(eglDevice, attribMap);
        }
        default:
        {
            UNREACHABLE();
            return EGL_NO_DISPLAY;
        }
    }
}

EGLBoolean GetSyncAttribKHR(Thread *thread,
                            Display *display,
                            SyncID syncObject,
                            EGLint attribute,
                            EGLint *value)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglGetSyncAttrib",
                                          GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, GetSyncAttrib(display, syncObject, attribute, value),
                         "eglGetSyncAttrib", GetSyncIfValid(display, syncObject), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLint LabelObjectKHR(Thread *thread,
                      Display *display,
                      ObjectType objectTypePacked,
                      EGLObjectKHR object,
                      EGLLabelKHR label)
{
    LabeledObject *labeledObject =
        GetLabeledObjectIfValid(thread, display, objectTypePacked, object);
    ASSERT(labeledObject != nullptr);
    labeledObject->setLabel(label);

    thread->setSuccess();
    return EGL_SUCCESS;
}

EGLBoolean PostSubBufferNV(Thread *thread,
                           Display *display,
                           SurfaceID surfaceID,
                           EGLint x,
                           EGLint y,
                           EGLint width,
                           EGLint height)
{
    Surface *eglSurface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglPostSubBufferNV",
                                          GetDisplayIfValid(display), EGL_FALSE);
    Error error = eglSurface->postSubBuffer(thread->getContext(), x, y, width, height);
    if (error.isError())
    {
        thread->setError(error, "eglPostSubBufferNV", GetSurfaceIfValid(display, surfaceID));
        return EGL_FALSE;
    }

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean PresentationTimeANDROID(Thread *thread,
                                   Display *display,
                                   SurfaceID surfaceID,
                                   EGLnsecsANDROID time)
{
    Surface *eglSurface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglPresentationTimeANDROID", GetDisplayIfValid(display),
                                          EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, eglSurface->setPresentationTime(time),
                         "eglPresentationTimeANDROID", GetSurfaceIfValid(display, surfaceID),
                         EGL_FALSE);

    return EGL_TRUE;
}

EGLBoolean GetCompositorTimingSupportedANDROID(Thread *thread,
                                               Display *display,
                                               SurfaceID surfaceID,
                                               CompositorTiming nameInternal)
{
    Surface *eglSurface = display->getSurface(surfaceID);

    thread->setSuccess();
    return eglSurface->getSupportedCompositorTimings().test(nameInternal);
}

EGLBoolean GetCompositorTimingANDROID(Thread *thread,
                                      Display *display,
                                      SurfaceID surfaceID,
                                      EGLint numTimestamps,
                                      const EGLint *names,
                                      EGLnsecsANDROID *values)
{
    Surface *eglSurface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglGetCompositorTimingANDROIDD",
                                          GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, eglSurface->getCompositorTiming(numTimestamps, names, values),
                         "eglGetCompositorTimingANDROIDD", GetSurfaceIfValid(display, surfaceID),
                         EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean GetNextFrameIdANDROID(Thread *thread,
                                 Display *display,
                                 SurfaceID surfaceID,
                                 EGLuint64KHR *frameId)
{
    Surface *eglSurface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglGetNextFrameIdANDROID", GetDisplayIfValid(display),
                                          EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, eglSurface->getNextFrameId(frameId), "eglGetNextFrameIdANDROID",
                         GetSurfaceIfValid(display, surfaceID), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean GetFrameTimestampSupportedANDROID(Thread *thread,
                                             Display *display,
                                             SurfaceID surfaceID,
                                             Timestamp timestampInternal)
{
    Surface *eglSurface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglQueryTimestampSupportedANDROID",
                                          GetDisplayIfValid(display), EGL_FALSE);
    thread->setSuccess();
    return eglSurface->getSupportedTimestamps().test(timestampInternal);
}

EGLBoolean GetFrameTimestampsANDROID(Thread *thread,
                                     Display *display,
                                     SurfaceID surfaceID,
                                     EGLuint64KHR frameId,
                                     EGLint numTimestamps,
                                     const EGLint *timestamps,
                                     EGLnsecsANDROID *values)
{
    Surface *eglSurface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglGetFrameTimestampsANDROID",
                                          GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(
        thread, eglSurface->getFrameTimestamps(frameId, numTimestamps, timestamps, values),
        "eglGetFrameTimestampsANDROID", GetSurfaceIfValid(display, surfaceID), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean QueryDebugKHR(Thread *thread, EGLint attribute, EGLAttrib *value)
{
    Debug *debug = GetDebug();
    switch (attribute)
    {
        case EGL_DEBUG_MSG_CRITICAL_KHR:
        case EGL_DEBUG_MSG_ERROR_KHR:
        case EGL_DEBUG_MSG_WARN_KHR:
        case EGL_DEBUG_MSG_INFO_KHR:
            *value = debug->isMessageTypeEnabled(FromEGLenum<MessageType>(attribute)) ? EGL_TRUE
                                                                                      : EGL_FALSE;
            break;
        case EGL_DEBUG_CALLBACK_KHR:
            *value = reinterpret_cast<EGLAttrib>(debug->getCallback());
            break;

        default:
            UNREACHABLE();
    }

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean QueryDeviceAttribEXT(Thread *thread, Device *dev, EGLint attribute, EGLAttrib *value)
{
    ANGLE_EGL_TRY_RETURN(thread, dev->getAttribute(attribute, value), "eglQueryDeviceAttribEXT",
                         GetDeviceIfValid(dev), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

const char *QueryDeviceStringEXT(Thread *thread, Device *dev, EGLint name)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, dev->getOwningDisplay()->prepareForCall(),
                                          "eglQueryDeviceStringEXT",
                                          GetDisplayIfValid(dev->getOwningDisplay()), EGL_FALSE);
    const char *result;
    switch (name)
    {
        case EGL_EXTENSIONS:
            result = dev->getExtensionString().c_str();
            break;
        case EGL_DRM_DEVICE_FILE_EXT:
        case EGL_DRM_RENDER_NODE_FILE_EXT:
            result = dev->getDeviceString(name).c_str();
            break;
        default:
            thread->setError(egl::Error(EGL_BAD_DEVICE_EXT), "eglQueryDeviceStringEXT",
                             GetDeviceIfValid(dev));
            return nullptr;
    }

    thread->setSuccess();
    return result;
}

EGLBoolean QueryDisplayAttribEXT(Thread *thread,
                                 Display *display,
                                 EGLint attribute,
                                 EGLAttrib *value)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglQueryDisplayAttribEXT", GetDisplayIfValid(display),
                                          EGL_FALSE);
    *value = display->queryAttrib(attribute);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean QueryStreamKHR(Thread *thread,
                          Display *display,
                          Stream *streamObject,
                          EGLenum attribute,
                          EGLint *value)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglQueryStreamKHR",
                                          GetDisplayIfValid(display), EGL_FALSE);
    switch (attribute)
    {
        case EGL_STREAM_STATE_KHR:
            *value = streamObject->getState();
            break;
        case EGL_CONSUMER_LATENCY_USEC_KHR:
            *value = streamObject->getConsumerLatency();
            break;
        case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
            *value = streamObject->getConsumerAcquireTimeout();
            break;
        default:
            UNREACHABLE();
    }

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean QueryStreamu64KHR(Thread *thread,
                             Display *display,
                             Stream *streamObject,
                             EGLenum attribute,
                             EGLuint64KHR *value)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglQueryStreamu64KHR",
                                          GetDisplayIfValid(display), EGL_FALSE);
    switch (attribute)
    {
        case EGL_PRODUCER_FRAME_KHR:
            *value = streamObject->getProducerFrame();
            break;
        case EGL_CONSUMER_FRAME_KHR:
            *value = streamObject->getConsumerFrame();
            break;
        default:
            UNREACHABLE();
    }

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean QuerySurfacePointerANGLE(Thread *thread,
                                    Display *display,
                                    SurfaceID surfaceID,
                                    EGLint attribute,
                                    void **value)
{
    Surface *eglSurface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglQuerySurfacePointerANGLE", GetDisplayIfValid(display),
                                          EGL_FALSE);
    Error error = eglSurface->querySurfacePointerANGLE(attribute, value);
    if (error.isError())
    {
        thread->setError(error, "eglQuerySurfacePointerANGLE",
                         GetSurfaceIfValid(display, surfaceID));
        return EGL_FALSE;
    }

    thread->setSuccess();
    return EGL_TRUE;
}

void SetBlobCacheFuncsANDROID(Thread *thread,
                              Display *display,
                              EGLSetBlobFuncANDROID set,
                              EGLGetBlobFuncANDROID get)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL(thread, display->prepareForCall(), "eglSetBlobCacheFuncsANDROID",
                                   GetDisplayIfValid(display));
    thread->setSuccess();
    display->setBlobCacheFuncs(set, get);
}

EGLBoolean SignalSyncKHR(Thread *thread, Display *display, SyncID syncID, EGLenum mode)
{
    gl::Context *currentContext = thread->getContext();
    Sync *syncObject            = display->getSync(syncID);
    ANGLE_EGL_TRY_RETURN(thread, syncObject->signal(display, currentContext, mode),
                         "eglSignalSyncKHR", GetSyncIfValid(display, syncID), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean StreamAttribKHR(Thread *thread,
                           Display *display,
                           Stream *streamObject,
                           EGLenum attribute,
                           EGLint value)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglStreamAttribKHR",
                                          GetDisplayIfValid(display), EGL_FALSE);
    switch (attribute)
    {
        case EGL_CONSUMER_LATENCY_USEC_KHR:
            streamObject->setConsumerLatency(value);
            break;
        case EGL_CONSUMER_ACQUIRE_TIMEOUT_USEC_KHR:
            streamObject->setConsumerAcquireTimeout(value);
            break;
        default:
            UNREACHABLE();
    }

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean StreamConsumerAcquireKHR(Thread *thread, Display *display, Stream *streamObject)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglStreamConsumerAcquireKHR", GetDisplayIfValid(display),
                                          EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, streamObject->consumerAcquire(thread->getContext()),
                         "eglStreamConsumerAcquireKHR", GetStreamIfValid(display, streamObject),
                         EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean StreamConsumerGLTextureExternalKHR(Thread *thread,
                                              Display *display,
                                              Stream *streamObject)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglStreamConsumerGLTextureExternalKHR",
                                          GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(
        thread, streamObject->createConsumerGLTextureExternal(AttributeMap(), thread->getContext()),
        "eglStreamConsumerGLTextureExternalKHR", GetStreamIfValid(display, streamObject),
        EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean StreamConsumerGLTextureExternalAttribsNV(Thread *thread,
                                                    Display *display,
                                                    Stream *streamObject,
                                                    const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglStreamConsumerGLTextureExternalAttribsNV",
                                          GetDisplayIfValid(display), EGL_FALSE);

    gl::Context *context = gl::GetValidGlobalContext();
    ANGLE_EGL_TRY_RETURN(thread, streamObject->createConsumerGLTextureExternal(attributes, context),
                         "eglStreamConsumerGLTextureExternalAttribsNV",
                         GetStreamIfValid(display, streamObject), EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean StreamConsumerReleaseKHR(Thread *thread, Display *display, Stream *streamObject)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglStreamConsumerReleaseKHR", GetDisplayIfValid(display),
                                          EGL_FALSE);

    gl::Context *context = gl::GetValidGlobalContext();
    ANGLE_EGL_TRY_RETURN(thread, streamObject->consumerRelease(context),
                         "eglStreamConsumerReleaseKHR", GetStreamIfValid(display, streamObject),
                         EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean SwapBuffersWithDamageKHR(Thread *thread,
                                    Display *display,
                                    SurfaceID surfaceID,
                                    const EGLint *rects,
                                    EGLint n_rects)
{
    Surface *eglSurface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglSwapBuffersWithDamageKHR", GetDisplayIfValid(display),
                                          EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, eglSurface->swapWithDamage(thread->getContext(), rects, n_rects),
                         "eglSwapBuffersWithDamageKHR", GetSurfaceIfValid(display, surfaceID),
                         EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

void LockVulkanQueueANGLE(Thread *thread, egl::Display *display)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL(thread, display->prepareForCall(), "eglLockVulkanQueueANGLE",
                                   GetDisplayIfValid(display));
    display->lockVulkanQueue();
    thread->setSuccess();
}

void UnlockVulkanQueueANGLE(Thread *thread, egl::Display *display)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL(thread, display->prepareForCall(), "eglUnlockVulkanQueueANGLE",
                                   GetDisplayIfValid(display));
    display->unlockVulkanQueue();
    thread->setSuccess();
}

EGLBoolean PrepareSwapBuffersANGLE(Thread *thread, Display *display, SurfaceID surfaceID)
{
    Surface *eglSurface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglPrepareSwapBuffersANGLE", GetDisplayIfValid(display),
                                          EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, eglSurface->prepareSwap(thread->getContext()),
                         "eglPrepareSwapBuffersANGLE", eglSurface, EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLint WaitSyncKHR(Thread *thread, Display *display, SyncID syncID, EGLint flags)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglWaitSync",
                                          GetDisplayIfValid(display), EGL_FALSE);
    gl::Context *currentContext = thread->getContext();
    Sync *syncObject            = display->getSync(syncID);
    ANGLE_EGL_TRY_RETURN(thread, syncObject->serverWait(display, currentContext, flags),
                         "eglWaitSync", GetSyncIfValid(display, syncID), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLDeviceEXT CreateDeviceANGLE(Thread *thread,
                               EGLint device_type,
                               void *native_device,
                               const EGLAttrib *attrib_list)
{
    Device *device = nullptr;
    ANGLE_EGL_TRY_RETURN(thread, Device::CreateDevice(device_type, native_device, &device),
                         "eglCreateDeviceANGLE", GetThreadIfValid(thread), EGL_NO_DEVICE_EXT);

    thread->setSuccess();
    return device;
}

EGLBoolean ReleaseDeviceANGLE(Thread *thread, Device *dev)
{
    SafeDelete(dev);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean CreateStreamProducerD3DTextureANGLE(Thread *thread,
                                               Display *display,
                                               Stream *streamObject,
                                               const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglCreateStreamProducerD3DTextureANGLE",
                                          GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, streamObject->createProducerD3D11Texture(attributes),
                         "eglCreateStreamProducerD3DTextureANGLE",
                         GetStreamIfValid(display, streamObject), EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean StreamPostD3DTextureANGLE(Thread *thread,
                                     Display *display,
                                     Stream *streamObject,
                                     void *texture,
                                     const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglStreamPostD3DTextureANGLE",
                                          GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, streamObject->postD3D11Texture(texture, attributes),
                         "eglStreamPostD3DTextureANGLE", GetStreamIfValid(display, streamObject),
                         EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean GetMscRateANGLE(Thread *thread,
                           Display *display,
                           SurfaceID surfaceID,
                           EGLint *numerator,
                           EGLint *denominator)
{
    Surface *eglSurface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglGetMscRateANGLE",
                                          GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, eglSurface->getMscRate(numerator, denominator),
                         "eglGetMscRateANGLE", GetSurfaceIfValid(display, surfaceID), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean GetSyncValuesCHROMIUM(Thread *thread,
                                 Display *display,
                                 SurfaceID surfaceID,
                                 EGLuint64KHR *ust,
                                 EGLuint64KHR *msc,
                                 EGLuint64KHR *sbc)
{
    Surface *eglSurface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglGetSyncValuesCHROMIUM", GetDisplayIfValid(display),
                                          EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, eglSurface->getSyncValues(ust, msc, sbc),
                         "eglGetSyncValuesCHROMIUM", GetSurfaceIfValid(display, surfaceID),
                         EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLint ProgramCacheGetAttribANGLE(Thread *thread, Display *display, EGLenum attrib)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglProgramCacheGetAttribANGLE",
                                          GetDisplayIfValid(display), 0);
    thread->setSuccess();
    return display->programCacheGetAttrib(attrib);
}

void ProgramCacheQueryANGLE(Thread *thread,
                            Display *display,
                            EGLint index,
                            void *key,
                            EGLint *keysize,
                            void *binary,
                            EGLint *binarysize)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL(thread, display->prepareForCall(), "eglProgramCacheQueryANGLE",
                                   GetDisplayIfValid(display));
    ANGLE_EGL_TRY(thread, display->programCacheQuery(index, key, keysize, binary, binarysize),
                  "eglProgramCacheQueryANGLE", GetDisplayIfValid(display));

    thread->setSuccess();
}

void ProgramCachePopulateANGLE(Thread *thread,
                               Display *display,
                               const void *key,
                               EGLint keysize,
                               const void *binary,
                               EGLint binarysize)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL(thread, display->prepareForCall(),
                                   "eglProgramCachePopulateANGLE", GetDisplayIfValid(display));
    ANGLE_EGL_TRY(thread, display->programCachePopulate(key, keysize, binary, binarysize),
                  "eglProgramCachePopulateANGLE", GetDisplayIfValid(display));

    thread->setSuccess();
}

EGLint ProgramCacheResizeANGLE(Thread *thread, Display *display, EGLint limit, EGLint mode)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglProgramCacheResizeANGLE", GetDisplayIfValid(display),
                                          0);
    thread->setSuccess();
    return display->programCacheResize(limit, mode);
}

const char *QueryStringiANGLE(Thread *thread, Display *display, EGLint name, EGLint index)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglQueryStringiANGLE",
                                          GetDisplayIfValid(display), nullptr);
    thread->setSuccess();
    return display->queryStringi(name, index);
}

void ReleaseHighPowerGPUANGLE(Thread *thread, Display *display, gl::ContextID contextID)
{
    gl::Context *context = display->getContext(contextID);
    ANGLE_EGL_TRY_PREPARE_FOR_CALL(thread, display->prepareForCall(), "eglReleaseHighPowerGPUANGLE",
                                   GetDisplayIfValid(display));
    ANGLE_EGL_TRY(thread, context->releaseHighPowerGPU(), "eglReleaseHighPowerGPUANGLE",
                  GetDisplayIfValid(display));

    thread->setSuccess();
}

void ReacquireHighPowerGPUANGLE(Thread *thread, Display *display, gl::ContextID contextID)
{
    gl::Context *context = display->getContext(contextID);
    ANGLE_EGL_TRY_PREPARE_FOR_CALL(thread, display->prepareForCall(),
                                   "eglReacquireHighPowerGPUANGLE", GetDisplayIfValid(display));
    ANGLE_EGL_TRY(thread, context->reacquireHighPowerGPU(), "eglReacquireHighPowerGPUANGLE",
                  GetDisplayIfValid(display));

    thread->setSuccess();
}

void HandleGPUSwitchANGLE(Thread *thread, Display *display)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL(thread, display->prepareForCall(), "eglHandleGPUSwitchANGLE",
                                   GetDisplayIfValid(display));
    ANGLE_EGL_TRY(thread, display->handleGPUSwitch(), "eglHandleGPUSwitchANGLE",
                  GetDisplayIfValid(display));

    thread->setSuccess();
}

void ForceGPUSwitchANGLE(Thread *thread, Display *display, EGLint gpuIDHigh, EGLint gpuIDLow)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL(thread, display->prepareForCall(), "eglForceGPUSwitchANGLE",
                                   GetDisplayIfValid(display));
    ANGLE_EGL_TRY(thread, display->forceGPUSwitch(gpuIDHigh, gpuIDLow), "eglForceGPUSwitchANGLE",
                  GetDisplayIfValid(display));

    thread->setSuccess();
}

void WaitUntilWorkScheduledANGLE(Thread *thread, Display *display)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL(thread, display->prepareForCall(),
                                   "eglWaitUntilWorkScheduledANGLE", GetDisplayIfValid(display));
    ANGLE_EGL_TRY(thread, display->waitUntilWorkScheduled(), "eglWaitUntilWorkScheduledANGLE",
                  GetDisplayIfValid(display));

    thread->setSuccess();
}

EGLBoolean QueryDisplayAttribANGLE(Thread *thread,
                                   Display *display,
                                   EGLint attribute,
                                   EGLAttrib *value)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglQueryDisplayAttribEXT", GetDisplayIfValid(display),
                                          EGL_FALSE);
    *value = display->queryAttrib(attribute);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean LockSurfaceKHR(Thread *thread,
                          egl::Display *display,
                          SurfaceID surfaceID,
                          const AttributeMap &attributes)
{
    Surface *surface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglLockSurfaceKHR",
                                          GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, surface->lockSurfaceKHR(display, attributes), "eglLockSurfaceKHR",
                         GetSurfaceIfValid(display, surfaceID), EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean UnlockSurfaceKHR(Thread *thread, egl::Display *display, SurfaceID surfaceID)
{
    Surface *surface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglUnlockSurfaceKHR",
                                          GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, surface->unlockSurfaceKHR(display), "eglQuerySurface64KHR",
                         GetSurfaceIfValid(display, surfaceID), EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean QuerySurface64KHR(Thread *thread,
                             egl::Display *display,
                             SurfaceID surfaceID,
                             EGLint attribute,
                             EGLAttribKHR *value)
{
    Surface *surface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(), "eglQuerySurface64KHR",
                                          GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(
        thread, QuerySurfaceAttrib64KHR(display, thread->getContext(), surface, attribute, value),
        "eglQuerySurface64KHR", GetSurfaceIfValid(display, surfaceID), EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean ExportVkImageANGLE(Thread *thread,
                              egl::Display *display,
                              egl::ImageID imageID,
                              void *vk_image,
                              void *vk_image_create_info)
{
    Image *image = display->getImage(imageID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglExportVkImageANGLE", GetDisplayIfValid(display),
                                          EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, image->exportVkImage(vk_image, vk_image_create_info),
                         "eglExportVkImageANGLE", GetImageIfValid(display, imageID), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean SetDamageRegionKHR(Thread *thread,
                              egl::Display *display,
                              SurfaceID surfaceID,
                              EGLint *rects,
                              EGLint n_rects)
{
    Surface *surface = display->getSurface(surfaceID);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglSetDamageRegionKHR", GetDisplayIfValid(display),
                                          EGL_FALSE);
    surface->setDamageRegion(rects, n_rects);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean QueryDmaBufFormatsEXT(Thread *thread,
                                 egl::Display *display,
                                 EGLint max_formats,
                                 EGLint *formats,
                                 EGLint *num_formats)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglQueryDmaBufFormatsEXT", GetDisplayIfValid(display),
                                          EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, display->queryDmaBufFormats(max_formats, formats, num_formats),
                         "eglQueryDmaBufFormatsEXT", GetDisplayIfValid(display), EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean QueryDmaBufModifiersEXT(Thread *thread,
                                   egl::Display *display,
                                   EGLint format,
                                   EGLint max_modifiers,
                                   EGLuint64KHR *modifiers,
                                   EGLBoolean *external_only,
                                   EGLint *num_modifiers)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglQueryDmaBufModifiersEXT", GetDisplayIfValid(display),
                                          EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread,
                         display->queryDmaBufModifiers(format, max_modifiers, modifiers,
                                                       external_only, num_modifiers),
                         "eglQueryDmaBufModifiersEXT", GetDisplayIfValid(display), EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

void *CopyMetalSharedEventANGLE(Thread *thread, Display *display, SyncID syncID)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglCopyMetalSharedEventANGLE",
                                          GetDisplayIfValid(display), nullptr);
    void *result     = nullptr;
    Sync *syncObject = display->getSync(syncID);
    ANGLE_EGL_TRY_RETURN(thread, syncObject->copyMetalSharedEventANGLE(display, &result),
                         "eglCopyMetalSharedEventANGLE", GetSyncIfValid(display, syncID), nullptr);

    thread->setSuccess();
    return result;
}

void AcquireExternalContextANGLE(Thread *thread, egl::Display *display, SurfaceID drawAndReadPacked)
{
    Surface *eglSurface = display->getSurface(drawAndReadPacked);

    ANGLE_EGL_TRY_PREPARE_FOR_CALL(thread, display->prepareForCall(),
                                   "eglAcquireExternalContextANGLE", GetDisplayIfValid(display));
    ANGLE_EGL_TRY(thread, thread->getContext()->acquireExternalContext(eglSurface),
                  "eglAcquireExternalContextANGLE", GetDisplayIfValid(display));

    thread->setSuccess();
}

void ReleaseExternalContextANGLE(Thread *thread, egl::Display *display)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL(thread, display->prepareForCall(),
                                   "eglReleaseExternalContextANGLE", GetDisplayIfValid(display));
    ANGLE_EGL_TRY(thread, thread->getContext()->releaseExternalContext(),
                  "eglReleaseExternalContextANGLE", GetDisplayIfValid(display));

    thread->setSuccess();
}

void SetValidationEnabledANGLE(Thread *thread, EGLBoolean validationState)
{
    SetEGLValidationEnabled(validationState != EGL_FALSE);
    thread->setSuccess();
}

EGLBoolean QuerySupportedCompressionRatesEXT(Thread *thread,
                                             egl::Display *display,
                                             egl::Config *configPacked,
                                             const EGLAttrib *attrib_list,
                                             EGLint *rates,
                                             EGLint rate_size,
                                             EGLint *num_rates)
{
    ANGLE_EGL_TRY_PREPARE_FOR_CALL_RETURN(thread, display->prepareForCall(),
                                          "eglQuerySupportedCompressionRatesEXT",
                                          GetDisplayIfValid(display), EGL_FALSE);

    const AttributeMap &attributes = PackParam<const AttributeMap &>((const EGLint *)attrib_list);
    ANGLE_EGL_TRY_RETURN(thread,
                         display->querySupportedCompressionRates(configPacked, attributes, rates,
                                                                 rate_size, num_rates),
                         "eglQuerySupportedCompressionRatesEXT", GetDisplayIfValid(display),
                         EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

}  // namespace egl
