diff options
Diffstat (limited to 'gfx/angle/checkout/src/libGLESv2/egl_stubs.cpp')
-rw-r--r-- | gfx/angle/checkout/src/libGLESv2/egl_stubs.cpp | 777 |
1 files changed, 777 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libGLESv2/egl_stubs.cpp b/gfx/angle/checkout/src/libGLESv2/egl_stubs.cpp new file mode 100644 index 0000000000..f2b8ad3dba --- /dev/null +++ b/gfx/angle/checkout/src/libGLESv2/egl_stubs.cpp @@ -0,0 +1,777 @@ +// +// 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_info.h" +#include "libANGLE/Context.h" +#include "libANGLE/Display.h" +#include "libANGLE/EGLSync.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Thread.h" +#include "libANGLE/capture/capture_egl.h" +#include "libANGLE/capture/frame_capture_utils_autogen.h" +#include "libANGLE/capture/gl_enum_utils_autogen.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 && !context->isContextLost()) + { + 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); + + ANGLE_CAPTURE_EGL(EGLBindTexImage, thread, eglSurface, buffer); + } + + 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; + } + + ANGLE_CAPTURE_EGL(EGLCreateImage, thread, context, target, buffer, attributes, 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); + + ANGLE_CAPTURE_EGL(EGLCreatePbufferSurface, thread, attributes, 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); + + ANGLE_CAPTURE_EGL(EGLDestroyImage, thread, display, img); + + thread->setSuccess(); + return EGL_TRUE; +} + +EGLBoolean DestroySurface(Thread *thread, Display *display, Surface *eglSurface) +{ + ANGLE_CAPTURE_EGL(EGLDestroySurface, thread, display, 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(EGL_PLATFORM_ANGLE_ANGLE, 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) +{ + switch (platform) + { + case EGL_PLATFORM_ANGLE_ANGLE: + case EGL_PLATFORM_GBM_KHR: + case EGL_PLATFORM_WAYLAND_EXT: + { + return Display::GetDisplayFromNativeDisplay( + platform, gl::bitCast<EGLNativeDisplayType>(native_display), attribMap); + } + case EGL_PLATFORM_DEVICE_EXT: + { + Device *eglDevice = static_cast<Device *>(native_display); + return Display::GetDisplayFromDevice(eglDevice, attribMap); + } + default: + { + 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 = kEglMajorVersion; + } + if (minor) + { + *minor = kEglMinorVersion; + } + + 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); + + ANGLE_CAPTURE_EGL(EGLMakeCurrent, thread, drawSurface, readSurface, context); + } + + 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 = display->getClientAPIString().c_str(); + 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: + { + static const char *sVersionString = + MakeStaticString(std::string("1.5 (ANGLE ") + angle::GetANGLEVersionString() + ")"); + result = sVersionString; + 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::Context *context = thread->getContext(); + if (context && !context->isContextLost()) + { + gl::Texture *texture = eglSurface->getBoundTexture(); + + if (texture) + { + ANGLE_EGL_TRY_RETURN(thread, eglSurface->releaseTexImage(thread->getContext(), buffer), + "eglReleaseTexImage", GetSurfaceIfValid(display, eglSurface), + EGL_FALSE); + ANGLE_CAPTURE_EGL(EGLReleaseTexImage, thread, eglSurface, buffer); + } + } + 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); + + ANGLE_EGL_TRY_RETURN(thread, SetSurfaceAttrib(eglSurface, attribute, value), "eglSurfaceAttrib", + GetDisplayIfValid(display), EGL_FALSE); + + 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->terminate(thread, Display::TerminateReason::Api), + "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 |