//
// 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_stubs.cpp: Stubs for EGL entry points.
//

#include "libGLESv2/egl_stubs_autogen.h"

#include "common/angle_version.h"
#include "libANGLE/Context.h"
#include "libANGLE/Display.h"
#include "libANGLE/EGLSync.h"
#include "libANGLE/Surface.h"
#include "libANGLE/Thread.h"
#include "libANGLE/queryutils.h"
#include "libANGLE/validationEGL.h"
#include "libGLESv2/global_state.h"
#include "libGLESv2/proc_table_egl.h"

namespace egl
{
namespace
{

bool CompareProc(const ProcEntry &a, const char *b)
{
    return strcmp(a.first, b) < 0;
}

void ClipConfigs(const std::vector<const Config *> &filteredConfigs,
                 EGLConfig *outputConfigs,
                 EGLint configSize,
                 EGLint *numConfigs)
{
    EGLint resultSize = static_cast<EGLint>(filteredConfigs.size());
    if (outputConfigs)
    {
        resultSize = std::max(std::min(resultSize, configSize), 0);
        for (EGLint i = 0; i < resultSize; i++)
        {
            outputConfigs[i] = const_cast<Config *>(filteredConfigs[i]);
        }
    }
    *numConfigs = resultSize;
}
}  // anonymous namespace

EGLBoolean BindAPI(Thread *thread, EGLenum api)
{
    thread->setAPI(api);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean BindTexImage(Thread *thread, Display *display, Surface *eglSurface, EGLint buffer)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglBindTexImage",
                         GetDisplayIfValid(display), EGL_FALSE);

    gl::Context *context = thread->getContext();
    if (context)
    {
        gl::TextureType type =
            egl_gl::EGLTextureTargetToTextureType(eglSurface->getTextureTarget());
        gl::Texture *textureObject = context->getTextureByType(type);
        ANGLE_EGL_TRY_RETURN(thread, eglSurface->bindTexImage(context, textureObject, buffer),
                             "eglBindTexImage", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
    }

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean ChooseConfig(Thread *thread,
                        Display *display,
                        const AttributeMap &attribMap,
                        EGLConfig *configs,
                        EGLint config_size,
                        EGLint *num_config)
{
    ClipConfigs(display->chooseConfig(attribMap), configs, config_size, num_config);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLint ClientWaitSync(Thread *thread,
                      Display *display,
                      Sync *syncObject,
                      EGLint flags,
                      EGLTime timeout)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglClientWaitSync",
                         GetDisplayIfValid(display), EGL_FALSE);
    gl::Context *currentContext = thread->getContext();
    EGLint syncStatus           = EGL_FALSE;
    ANGLE_EGL_TRY_RETURN(
        thread, syncObject->clientWait(display, currentContext, flags, timeout, &syncStatus),
        "eglClientWaitSync", GetSyncIfValid(display, syncObject), EGL_FALSE);

    thread->setSuccess();
    return syncStatus;
}

EGLBoolean CopyBuffers(Thread *thread,
                       Display *display,
                       Surface *eglSurface,
                       EGLNativePixmapType target)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCopyBuffers",
                         GetDisplayIfValid(display), EGL_FALSE);
    UNIMPLEMENTED();  // FIXME

    thread->setSuccess();
    return 0;
}

EGLContext CreateContext(Thread *thread,
                         Display *display,
                         Config *configuration,
                         gl::Context *sharedGLContext,
                         const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateContext",
                         GetDisplayIfValid(display), EGL_NO_CONTEXT);
    gl::Context *context = nullptr;
    ANGLE_EGL_TRY_RETURN(thread,
                         display->createContext(configuration, sharedGLContext, thread->getAPI(),
                                                attributes, &context),
                         "eglCreateContext", GetDisplayIfValid(display), EGL_NO_CONTEXT);

    thread->setSuccess();
    return static_cast<EGLContext>(context);
}

EGLImage CreateImage(Thread *thread,
                     Display *display,
                     gl::Context *context,
                     EGLenum target,
                     EGLClientBuffer buffer,
                     const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateImage",
                         GetDisplayIfValid(display), EGL_FALSE);

    Image *image = nullptr;
    Error error  = display->createImage(context, target, buffer, attributes, &image);
    if (error.isError())
    {
        thread->setError(error, "eglCreateImage", GetDisplayIfValid(display));
        return EGL_NO_IMAGE;
    }

    thread->setSuccess();
    return static_cast<EGLImage>(image);
}

EGLSurface CreatePbufferFromClientBuffer(Thread *thread,
                                         Display *display,
                                         EGLenum buftype,
                                         EGLClientBuffer buffer,
                                         Config *configuration,
                                         const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePbufferFromClientBuffer",
                         GetDisplayIfValid(display), EGL_NO_SURFACE);
    Surface *surface = nullptr;
    ANGLE_EGL_TRY_RETURN(thread,
                         display->createPbufferFromClientBuffer(configuration, buftype, buffer,
                                                                attributes, &surface),
                         "eglCreatePbufferFromClientBuffer", GetDisplayIfValid(display),
                         EGL_NO_SURFACE);

    return static_cast<EGLSurface>(surface);
}

EGLSurface CreatePbufferSurface(Thread *thread,
                                Display *display,
                                Config *configuration,
                                const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePbufferSurface",
                         GetDisplayIfValid(display), EGL_NO_SURFACE);
    Surface *surface = nullptr;
    ANGLE_EGL_TRY_RETURN(thread, display->createPbufferSurface(configuration, attributes, &surface),
                         "eglCreatePbufferSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);

    return static_cast<EGLSurface>(surface);
}

EGLSurface CreatePixmapSurface(Thread *thread,
                               Display *display,
                               Config *configuration,
                               EGLNativePixmapType pixmap,
                               const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePixmapSurface",
                         GetDisplayIfValid(display), EGL_NO_SURFACE);
    Surface *surface = nullptr;
    ANGLE_EGL_TRY_RETURN(thread,
                         display->createPixmapSurface(configuration, pixmap, attributes, &surface),
                         "eglCreatePixmapSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);

    thread->setSuccess();
    return static_cast<EGLSurface>(surface);
}

EGLSurface CreatePlatformPixmapSurface(Thread *thread,
                                       Display *display,
                                       Config *configuration,
                                       void *pixmap,
                                       const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePlatformPixmapSurface",
                         GetDisplayIfValid(display), EGL_NO_SURFACE);
    Surface *surface                 = nullptr;
    EGLNativePixmapType nativePixmap = reinterpret_cast<EGLNativePixmapType>(pixmap);
    ANGLE_EGL_TRY_RETURN(
        thread, display->createPixmapSurface(configuration, nativePixmap, attributes, &surface),
        "eglCreatePlatformPixmapSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);

    thread->setSuccess();
    return static_cast<EGLSurface>(surface);
}

EGLSurface CreatePlatformWindowSurface(Thread *thread,
                                       Display *display,
                                       Config *configuration,
                                       void *win,
                                       const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreatePlatformWindowSurface",
                         GetDisplayIfValid(display), EGL_NO_SURFACE);
    Surface *surface                 = nullptr;
    EGLNativeWindowType nativeWindow = reinterpret_cast<EGLNativeWindowType>(win);
    ANGLE_EGL_TRY_RETURN(
        thread, display->createWindowSurface(configuration, nativeWindow, attributes, &surface),
        "eglPlatformCreateWindowSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);

    return static_cast<EGLSurface>(surface);
}

EGLSync CreateSync(Thread *thread, Display *display, EGLenum type, const AttributeMap &attributes)
{
    gl::Context *currentContext = thread->getContext();

    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateSync",
                         GetDisplayIfValid(display), EGL_FALSE);
    Sync *syncObject = nullptr;
    ANGLE_EGL_TRY_RETURN(thread, display->createSync(currentContext, type, attributes, &syncObject),
                         "eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);

    thread->setSuccess();
    return static_cast<EGLSync>(syncObject);
}

EGLSurface CreateWindowSurface(Thread *thread,
                               Display *display,
                               Config *configuration,
                               EGLNativeWindowType win,
                               const AttributeMap &attributes)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglCreateWindowSurface",
                         GetDisplayIfValid(display), EGL_NO_SURFACE);

    Surface *surface = nullptr;
    ANGLE_EGL_TRY_RETURN(thread,
                         display->createWindowSurface(configuration, win, attributes, &surface),
                         "eglCreateWindowSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);

    return static_cast<EGLSurface>(surface);
}

EGLBoolean DestroyContext(Thread *thread, Display *display, gl::Context *context)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroyContext",
                         GetDisplayIfValid(display), EGL_FALSE);

    ScopedSyncCurrentContextFromThread scopedSyncCurrent(thread);

    ANGLE_EGL_TRY_RETURN(thread, display->destroyContext(thread, context), "eglDestroyContext",
                         GetContextIfValid(display, context), EGL_FALSE);
    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean DestroyImage(Thread *thread, Display *display, Image *img)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroyImage",
                         GetDisplayIfValid(display), EGL_FALSE);
    display->destroyImage(img);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean DestroySurface(Thread *thread, Display *display, Surface *eglSurface)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroySurface",
                         GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, display->destroySurface(eglSurface), "eglDestroySurface",
                         GetSurfaceIfValid(display, eglSurface), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean DestroySync(Thread *thread, Display *display, Sync *syncObject)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglDestroySync",
                         GetDisplayIfValid(display), EGL_FALSE);
    display->destroySync(syncObject);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean GetConfigAttrib(Thread *thread,
                           Display *display,
                           Config *configuration,
                           EGLint attribute,
                           EGLint *value)
{
    QueryConfigAttrib(configuration, attribute, value);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean GetConfigs(Thread *thread,
                      Display *display,
                      EGLConfig *configs,
                      EGLint config_size,
                      EGLint *num_config)
{
    ClipConfigs(display->getConfigs(AttributeMap()), configs, config_size, num_config);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLContext GetCurrentContext(Thread *thread)
{
    gl::Context *context = thread->getContext();

    thread->setSuccess();
    return static_cast<EGLContext>(context);
}

EGLDisplay GetCurrentDisplay(Thread *thread)
{
    thread->setSuccess();
    if (thread->getContext() != nullptr)
    {
        return thread->getContext()->getDisplay();
    }
    return EGL_NO_DISPLAY;
}

EGLSurface GetCurrentSurface(Thread *thread, EGLint readdraw)
{
    if (readdraw == EGL_READ)
    {
        thread->setSuccess();
        return thread->getCurrentReadSurface();
    }
    else if (readdraw == EGL_DRAW)
    {
        thread->setSuccess();
        return thread->getCurrentDrawSurface();
    }
    else
    {
        thread->setError(EglBadParameter(), "eglGetCurrentSurface", nullptr);
        return EGL_NO_SURFACE;
    }
}

EGLDisplay GetDisplay(Thread *thread, EGLNativeDisplayType display_id)
{
    return Display::GetDisplayFromNativeDisplay(display_id, AttributeMap());
}

EGLint GetError(Thread *thread)
{
    EGLint error = thread->getError();
    thread->setSuccess();
    return error;
}

EGLDisplay GetPlatformDisplay(Thread *thread,
                              EGLenum platform,
                              void *native_display,
                              const AttributeMap &attribMap)
{
    if (platform == EGL_PLATFORM_ANGLE_ANGLE)
    {
        return Display::GetDisplayFromNativeDisplay(
            gl::bitCast<EGLNativeDisplayType>(native_display), attribMap);
    }
    else if (platform == EGL_PLATFORM_DEVICE_EXT)
    {
        Device *eglDevice = static_cast<Device *>(native_display);
        return Display::GetDisplayFromDevice(eglDevice, attribMap);
    }
    else
    {
        UNREACHABLE();
        return EGL_NO_DISPLAY;
    }
}

__eglMustCastToProperFunctionPointerType GetProcAddress(Thread *thread, const char *procname)
{
    const ProcEntry *entry =
        std::lower_bound(&g_procTable[0], &g_procTable[g_numProcs], procname, CompareProc);

    thread->setSuccess();

    if (entry == &g_procTable[g_numProcs] || strcmp(entry->first, procname) != 0)
    {
        return nullptr;
    }

    return entry->second;
}

EGLBoolean GetSyncAttrib(Thread *thread,
                         Display *display,
                         Sync *syncObject,
                         EGLint attribute,
                         EGLAttrib *value)
{
    EGLint valueExt;
    ANGLE_EGL_TRY_RETURN(thread, GetSyncAttrib(display, syncObject, attribute, &valueExt),
                         "eglGetSyncAttrib", GetSyncIfValid(display, syncObject), EGL_FALSE);
    *value = valueExt;

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean Initialize(Thread *thread, Display *display, EGLint *major, EGLint *minor)
{
    ANGLE_EGL_TRY_RETURN(thread, display->initialize(), "eglInitialize", GetDisplayIfValid(display),
                         EGL_FALSE);

    if (major)
        *major = 1;
    if (minor)
        *minor = 5;

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean MakeCurrent(Thread *thread,
                       Display *display,
                       Surface *drawSurface,
                       Surface *readSurface,
                       gl::Context *context)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglMakeCurrent",
                         GetDisplayIfValid(display), EGL_FALSE);
    ScopedSyncCurrentContextFromThread scopedSyncCurrent(thread);

    Surface *previousDraw        = thread->getCurrentDrawSurface();
    Surface *previousRead        = thread->getCurrentReadSurface();
    gl::Context *previousContext = thread->getContext();

    // Only call makeCurrent if the context or surfaces have changed.
    if (previousDraw != drawSurface || previousRead != readSurface || previousContext != context)
    {
        ANGLE_EGL_TRY_RETURN(
            thread,
            display->makeCurrent(thread, previousContext, drawSurface, readSurface, context),
            "eglMakeCurrent", GetContextIfValid(display, context), EGL_FALSE);
    }

    thread->setSuccess();
    return EGL_TRUE;
}

EGLenum QueryAPI(Thread *thread)
{
    EGLenum API = thread->getAPI();

    thread->setSuccess();
    return API;
}

EGLBoolean QueryContext(Thread *thread,
                        Display *display,
                        gl::Context *context,
                        EGLint attribute,
                        EGLint *value)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryContext",
                         GetDisplayIfValid(display), EGL_FALSE);
    QueryContextAttrib(context, attribute, value);

    thread->setSuccess();
    return EGL_TRUE;
}

const char *QueryString(Thread *thread, Display *display, EGLint name)
{
    if (display)
    {
        ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQueryString",
                             GetDisplayIfValid(display), nullptr);
    }

    const char *result = nullptr;
    switch (name)
    {
        case EGL_CLIENT_APIS:
            result = "OpenGL_ES";
            break;
        case EGL_EXTENSIONS:
            if (display == EGL_NO_DISPLAY)
            {
                result = Display::GetClientExtensionString().c_str();
            }
            else
            {
                result = display->getExtensionString().c_str();
            }
            break;
        case EGL_VENDOR:
            result = display->getVendorString().c_str();
            break;
        case EGL_VERSION:
            result = "1.5 (ANGLE " ANGLE_VERSION_STRING ")";
            break;
        default:
            UNREACHABLE();
            break;
    }

    thread->setSuccess();
    return result;
}

EGLBoolean QuerySurface(Thread *thread,
                        Display *display,
                        Surface *eglSurface,
                        EGLint attribute,
                        EGLint *value)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglQuerySurface",
                         GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(
        thread, QuerySurfaceAttrib(display, thread->getContext(), eglSurface, attribute, value),
        "eglQuerySurface", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean ReleaseTexImage(Thread *thread, Display *display, Surface *eglSurface, EGLint buffer)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglReleaseTexImage",
                         GetDisplayIfValid(display), EGL_FALSE);
    gl::Texture *texture = eglSurface->getBoundTexture();

    if (texture)
    {
        ANGLE_EGL_TRY_RETURN(thread, eglSurface->releaseTexImage(thread->getContext(), buffer),
                             "eglReleaseTexImage", GetSurfaceIfValid(display, eglSurface),
                             EGL_FALSE);
    }

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean ReleaseThread(Thread *thread)
{
    ScopedSyncCurrentContextFromThread scopedSyncCurrent(thread);

    Surface *previousDraw        = thread->getCurrentDrawSurface();
    Surface *previousRead        = thread->getCurrentReadSurface();
    gl::Context *previousContext = thread->getContext();
    Display *previousDisplay     = thread->getDisplay();

    if (previousDisplay != EGL_NO_DISPLAY)
    {
        ANGLE_EGL_TRY_RETURN(thread, previousDisplay->prepareForCall(), "eglReleaseThread",
                             GetDisplayIfValid(previousDisplay), EGL_FALSE);
        // Only call makeCurrent if the context or surfaces have changed.
        if (previousDraw != EGL_NO_SURFACE || previousRead != EGL_NO_SURFACE ||
            previousContext != EGL_NO_CONTEXT)
        {
            ANGLE_EGL_TRY_RETURN(
                thread,
                previousDisplay->makeCurrent(thread, previousContext, nullptr, nullptr, nullptr),
                "eglReleaseThread", nullptr, EGL_FALSE);
        }
        ANGLE_EGL_TRY_RETURN(thread, previousDisplay->releaseThread(), "eglReleaseThread",
                             GetDisplayIfValid(previousDisplay), EGL_FALSE);
    }

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean SurfaceAttrib(Thread *thread,
                         Display *display,
                         Surface *eglSurface,
                         EGLint attribute,
                         EGLint value)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSurfaceAttrib",
                         GetDisplayIfValid(display), EGL_FALSE);
    SetSurfaceAttrib(eglSurface, attribute, value);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean SwapBuffers(Thread *thread, Display *display, Surface *eglSurface)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSwapBuffers",
                         GetDisplayIfValid(display), EGL_FALSE);

    ANGLE_EGL_TRY_RETURN(thread, eglSurface->swap(thread->getContext()), "eglSwapBuffers",
                         GetSurfaceIfValid(display, eglSurface), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean SwapInterval(Thread *thread, Display *display, EGLint interval)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglSwapInterval",
                         GetDisplayIfValid(display), EGL_FALSE);

    Surface *drawSurface        = static_cast<Surface *>(thread->getCurrentDrawSurface());
    const Config *surfaceConfig = drawSurface->getConfig();
    EGLint clampedInterval      = std::min(std::max(interval, surfaceConfig->minSwapInterval),
                                      surfaceConfig->maxSwapInterval);

    drawSurface->setSwapInterval(clampedInterval);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean Terminate(Thread *thread, Display *display)
{
    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglTerminate",
                         GetDisplayIfValid(display), EGL_FALSE);

    ScopedSyncCurrentContextFromThread scopedSyncCurrent(thread);

    ANGLE_EGL_TRY_RETURN(
        thread, display->makeCurrent(thread, thread->getContext(), nullptr, nullptr, nullptr),
        "eglTerminate", GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, display->terminate(thread), "eglTerminate",
                         GetDisplayIfValid(display), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean WaitClient(Thread *thread)
{
    Display *display = thread->getDisplay();
    if (display == nullptr)
    {
        // EGL spec says this about eglWaitClient -
        //    If there is no current context for the current rendering API,
        //    the function has no effect but still returns EGL_TRUE.
        return EGL_TRUE;
    }

    gl::Context *context = thread->getContext();

    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitClient",
                         GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, display->waitClient(context), "eglWaitClient",
                         GetContextIfValid(display, context), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean WaitGL(Thread *thread)
{
    Display *display = thread->getDisplay();
    if (display == nullptr)
    {
        // EGL spec says this about eglWaitGL -
        //    eglWaitGL is ignored if there is no current EGL rendering context for OpenGL ES.
        return EGL_TRUE;
    }

    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitGL", GetDisplayIfValid(display),
                         EGL_FALSE);

    // eglWaitGL like calling eglWaitClient with the OpenGL ES API bound. Since we only implement
    // OpenGL ES we can do the call directly.
    ANGLE_EGL_TRY_RETURN(thread, display->waitClient(thread->getContext()), "eglWaitGL",
                         GetDisplayIfValid(display), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

EGLBoolean WaitNative(Thread *thread, EGLint engine)
{
    Display *display = thread->getDisplay();
    if (display == nullptr)
    {
        // EGL spec says this about eglWaitNative -
        //    eglWaitNative is ignored if there is no current EGL rendering context.
        return EGL_TRUE;
    }

    ANGLE_EGL_TRY_RETURN(thread, display->prepareForCall(), "eglWaitNative",
                         GetDisplayIfValid(display), EGL_FALSE);
    ANGLE_EGL_TRY_RETURN(thread, display->waitNative(thread->getContext(), engine), "eglWaitNative",
                         GetThreadIfValid(thread), EGL_FALSE);

    thread->setSuccess();
    return EGL_TRUE;
}

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

    thread->setSuccess();
    return EGL_TRUE;
}
}  // namespace egl
