summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/libGLESv2/entry_points_egl.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /gfx/angle/checkout/src/libGLESv2/entry_points_egl.cpp
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/angle/checkout/src/libGLESv2/entry_points_egl.cpp')
-rw-r--r--gfx/angle/checkout/src/libGLESv2/entry_points_egl.cpp1096
1 files changed, 1096 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/libGLESv2/entry_points_egl.cpp b/gfx/angle/checkout/src/libGLESv2/entry_points_egl.cpp
new file mode 100644
index 0000000000..ba0ab78e33
--- /dev/null
+++ b/gfx/angle/checkout/src/libGLESv2/entry_points_egl.cpp
@@ -0,0 +1,1096 @@
+//
+// Copyright(c) 2014 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.
+//
+
+// entry_points_egl.cpp : Implements the EGL entry points.
+
+#include "libGLESv2/entry_points_egl.h"
+
+#include "common/debug.h"
+#include "common/utilities.h"
+#include "common/version.h"
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/EGLSync.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/Thread.h"
+#include "libANGLE/queryutils.h"
+#include "libANGLE/validationEGL.h"
+#include "libGLESv2/global_state.h"
+#include "libGLESv2/proc_table_egl.h"
+
+using 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 *output_configs,
+ EGLint config_size,
+ EGLint *num_config)
+{
+ EGLint result_size = static_cast<EGLint>(filteredConfigs.size());
+ if (output_configs)
+ {
+ result_size = std::max(std::min(result_size, config_size), 0);
+ for (EGLint i = 0; i < result_size; i++)
+ {
+ output_configs[i] = const_cast<Config *>(filteredConfigs[i]);
+ }
+ }
+ *num_config = result_size;
+}
+} // anonymous namespace
+
+extern "C" {
+// EGL 1.0
+EGLint EGLAPIENTRY EGL_GetError(void)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("()");
+ Thread *thread = egl::GetCurrentThread();
+
+ EGLint error = thread->getError();
+ thread->setSuccess();
+ return error;
+}
+
+EGLDisplay EGLAPIENTRY EGL_GetDisplay(EGLNativeDisplayType display_id)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLNativeDisplayType display_id = 0x%016" PRIxPTR ")", (uintptr_t)display_id);
+
+ return egl::Display::GetDisplayFromNativeDisplay(display_id, AttributeMap());
+}
+
+EGLBoolean EGLAPIENTRY EGL_Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLint *major = 0x%016" PRIxPTR
+ ", EGLint *minor = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)major, (uintptr_t)minor);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ ANGLE_EGL_TRY_RETURN(thread, ValidateInitialize(display), "eglInitialize",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ ANGLE_EGL_TRY_RETURN(thread, display->initialize(), "eglInitialize", GetDisplayIfValid(display),
+ EGL_FALSE);
+
+ if (major)
+ *major = 1;
+ if (minor)
+ *minor = 4;
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_Terminate(EGLDisplay dpy)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ")", (uintptr_t)dpy);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ ANGLE_EGL_TRY_RETURN(thread, ValidateTerminate(display), "eglTerminate",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ ANGLE_EGL_TRY_RETURN(thread, display->makeCurrent(thread, nullptr, nullptr, nullptr),
+ "eglTerminate", GetDisplayIfValid(display), EGL_FALSE);
+ SetContextCurrent(thread, nullptr);
+ ANGLE_EGL_TRY_RETURN(thread, display->terminate(thread), "eglTerminate",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+const char *EGLAPIENTRY EGL_QueryString(EGLDisplay dpy, EGLint name)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLint name = %d)", (uintptr_t)dpy, name);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ if (!(display == EGL_NO_DISPLAY && name == EGL_EXTENSIONS))
+ {
+ ANGLE_EGL_TRY_RETURN(thread, ValidateDisplay(display), "eglQueryString",
+ GetDisplayIfValid(display), nullptr);
+ }
+
+ const char *result;
+ switch (name)
+ {
+ case EGL_CLIENT_APIS:
+ result = "OpenGL_ES";
+ break;
+ case EGL_EXTENSIONS:
+ if (display == EGL_NO_DISPLAY)
+ {
+ result = egl::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.4 (ANGLE " ANGLE_VERSION_STRING ")";
+ break;
+ default:
+ thread->setError(EglBadParameter(), GetDebug(), "eglQueryString",
+ GetDisplayIfValid(display));
+ return nullptr;
+ }
+
+ thread->setSuccess();
+ return result;
+}
+
+EGLBoolean EGLAPIENTRY EGL_GetConfigs(EGLDisplay dpy,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLConfig *configs = 0x%016" PRIxPTR
+ ", "
+ "EGLint config_size = %d, EGLint *num_config = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)configs, config_size, (uintptr_t)num_config);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateGetConfigs(display, config_size, num_config),
+ "eglGetConfigs", GetDisplayIfValid(display), EGL_FALSE);
+
+ ClipConfigs(display->getConfigs(AttributeMap()), configs, config_size, num_config);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_ChooseConfig(EGLDisplay dpy,
+ const EGLint *attrib_list,
+ EGLConfig *configs,
+ EGLint config_size,
+ EGLint *num_config)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", const EGLint *attrib_list = 0x%016" PRIxPTR
+ ", "
+ "EGLConfig *configs = 0x%016" PRIxPTR
+ ", EGLint config_size = %d, EGLint *num_config = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)attrib_list, (uintptr_t)configs, config_size,
+ (uintptr_t)num_config);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ AttributeMap attribMap = AttributeMap::CreateFromIntArray(attrib_list);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateChooseConfig(display, attribMap, config_size, num_config),
+ "eglChooseConfig", GetDisplayIfValid(display), EGL_FALSE);
+
+ ClipConfigs(display->chooseConfig(attribMap), configs, config_size, num_config);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_GetConfigAttrib(EGLDisplay dpy,
+ EGLConfig config,
+ EGLint attribute,
+ EGLint *value)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLConfig config = 0x%016" PRIxPTR
+ ", EGLint attribute = %d, EGLint "
+ "*value = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)config, attribute, (uintptr_t)value);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Config *configuration = static_cast<Config *>(config);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateGetConfigAttrib(display, configuration, attribute),
+ "eglGetConfigAttrib", GetDisplayIfValid(display), EGL_FALSE);
+
+ QueryConfigAttrib(configuration, attribute, value);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLSurface EGLAPIENTRY EGL_CreateWindowSurface(EGLDisplay dpy,
+ EGLConfig config,
+ EGLNativeWindowType win,
+ const EGLint *attrib_list)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLConfig config = 0x%016" PRIxPTR
+ ", EGLNativeWindowType win = 0x%016" PRIxPTR
+ ", "
+ "const EGLint *attrib_list = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)win, (uintptr_t)attrib_list);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Config *configuration = static_cast<Config *>(config);
+ AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
+
+ ANGLE_EGL_TRY_RETURN(thread,
+ ValidateCreateWindowSurface(display, configuration, win, attributes),
+ "eglCreateWindowSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
+
+ egl::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);
+}
+
+EGLSurface EGLAPIENTRY EGL_CreatePbufferSurface(EGLDisplay dpy,
+ EGLConfig config,
+ const EGLint *attrib_list)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLConfig config = 0x%016" PRIxPTR
+ ", const EGLint *attrib_list = "
+ "0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)attrib_list);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Config *configuration = static_cast<Config *>(config);
+ AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateCreatePbufferSurface(display, configuration, attributes),
+ "eglCreatePbufferSurface", GetDisplayIfValid(display), EGL_NO_SURFACE);
+
+ egl::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 EGLAPIENTRY EGL_CreatePixmapSurface(EGLDisplay dpy,
+ EGLConfig config,
+ EGLNativePixmapType pixmap,
+ const EGLint *attrib_list)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLConfig config = 0x%016" PRIxPTR
+ ", EGLNativePixmapType pixmap = "
+ "0x%016" PRIxPTR
+ ", "
+ "const EGLint *attrib_list = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)pixmap, (uintptr_t)attrib_list);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Config *configuration = static_cast<Config *>(config);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateConfig(display, configuration), "eglCreatePixmapSurface",
+ GetDisplayIfValid(display), EGL_NO_SURFACE);
+
+ UNIMPLEMENTED(); // FIXME
+
+ thread->setSuccess();
+ return EGL_NO_SURFACE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_DestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)surface);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Surface *eglSurface = static_cast<Surface *>(surface);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateDestroySurface(display, eglSurface, surface),
+ "eglDestroySurface", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ ANGLE_EGL_TRY_RETURN(thread, display->destroySurface(eglSurface), "eglDestroySurface",
+ GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_QuerySurface(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLint *value)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
+ ", EGLint attribute = %d, EGLint "
+ "*value = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)surface, attribute, (uintptr_t)value);
+ Thread *thread = egl::GetCurrentThread();
+
+ const egl::Display *display = static_cast<const egl::Display *>(dpy);
+ const Surface *eglSurface = static_cast<const Surface *>(surface);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateQuerySurface(display, eglSurface, attribute, value),
+ "eglQuerySurface", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ QuerySurfaceAttrib(eglSurface, attribute, value);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLContext EGLAPIENTRY EGL_CreateContext(EGLDisplay dpy,
+ EGLConfig config,
+ EGLContext share_context,
+ const EGLint *attrib_list)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLConfig config = 0x%016" PRIxPTR
+ ", EGLContext share_context = "
+ "0x%016" PRIxPTR
+ ", "
+ "const EGLint *attrib_list = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)share_context, (uintptr_t)attrib_list);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Config *configuration = static_cast<Config *>(config);
+ gl::Context *sharedGLContext = static_cast<gl::Context *>(share_context);
+ AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
+
+ ANGLE_EGL_TRY_RETURN(thread,
+ ValidateCreateContext(display, configuration, sharedGLContext, attributes),
+ "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);
+}
+
+EGLBoolean EGLAPIENTRY EGL_DestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLContext ctx = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)ctx);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ gl::Context *context = static_cast<gl::Context *>(ctx);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateDestroyContext(display, context, ctx), "eglDestroyContext",
+ GetContextIfValid(display, context), EGL_FALSE);
+
+ bool contextWasCurrent = context == thread->getContext();
+
+ ANGLE_EGL_TRY_RETURN(thread, display->destroyContext(thread, context), "eglDestroyContext",
+ GetContextIfValid(display, context), EGL_FALSE);
+
+ if (contextWasCurrent)
+ {
+ SetContextCurrent(thread, nullptr);
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_MakeCurrent(EGLDisplay dpy,
+ EGLSurface draw,
+ EGLSurface read,
+ EGLContext ctx)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface draw = 0x%016" PRIxPTR
+ ", EGLSurface read = 0x%016" PRIxPTR
+ ", "
+ "EGLContext ctx = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)draw, (uintptr_t)read, (uintptr_t)ctx);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Surface *drawSurface = static_cast<Surface *>(draw);
+ Surface *readSurface = static_cast<Surface *>(read);
+ gl::Context *context = static_cast<gl::Context *>(ctx);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateMakeCurrent(display, drawSurface, readSurface, context),
+ "eglMakeCurrent", GetContextIfValid(display, context), EGL_FALSE);
+
+ 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, drawSurface, readSurface, context),
+ "eglMakeCurrent", GetContextIfValid(display, context), EGL_FALSE);
+
+ SetContextCurrent(thread, context);
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLSurface EGLAPIENTRY EGL_GetCurrentSurface(EGLint readdraw)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLint readdraw = %d)", readdraw);
+ Thread *thread = egl::GetCurrentThread();
+
+ if (readdraw == EGL_READ)
+ {
+ thread->setSuccess();
+ return thread->getCurrentReadSurface();
+ }
+ else if (readdraw == EGL_DRAW)
+ {
+ thread->setSuccess();
+ return thread->getCurrentDrawSurface();
+ }
+ else
+ {
+ thread->setError(EglBadParameter(), GetDebug(), "eglGetCurrentSurface", nullptr);
+ return EGL_NO_SURFACE;
+ }
+}
+
+EGLDisplay EGLAPIENTRY EGL_GetCurrentDisplay(void)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("()");
+ Thread *thread = egl::GetCurrentThread();
+
+ thread->setSuccess();
+ if (thread->getContext() != nullptr)
+ {
+ return thread->getContext()->getDisplay();
+ }
+ return EGL_NO_DISPLAY;
+}
+
+EGLBoolean EGLAPIENTRY EGL_QueryContext(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLint attribute,
+ EGLint *value)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLContext ctx = 0x%016" PRIxPTR
+ ", EGLint attribute = %d, EGLint *value "
+ "= 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)ctx, attribute, (uintptr_t)value);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ gl::Context *context = static_cast<gl::Context *>(ctx);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateQueryContext(display, context, attribute, value),
+ "eglQueryContext", GetContextIfValid(display, context), EGL_FALSE);
+
+ QueryContextAttrib(context, attribute, value);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_WaitGL(void)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("()");
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = thread->getDisplay();
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateDisplay(display), "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 EGLAPIENTRY EGL_WaitNative(EGLint engine)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLint engine = %d)", engine);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = thread->getDisplay();
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateWaitNative(display, engine), "eglWaitNative",
+ GetThreadIfValid(thread), EGL_FALSE);
+
+ ANGLE_EGL_TRY_RETURN(thread, display->waitNative(thread->getContext(), engine), "eglWaitNative",
+ GetThreadIfValid(thread), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_SwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)surface);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Surface *eglSurface = (Surface *)surface;
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateSwapBuffers(thread, display, eglSurface), "eglSwapBuffers",
+ GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->swap(thread->getContext()), "eglSwapBuffers",
+ GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_CopyBuffers(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLNativePixmapType target)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
+ ", EGLNativePixmapType target = "
+ "0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)surface, (uintptr_t)target);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Surface *eglSurface = static_cast<Surface *>(surface);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateCopyBuffers(display, eglSurface), "eglCopyBuffers",
+ GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ UNIMPLEMENTED(); // FIXME
+
+ thread->setSuccess();
+ return 0;
+}
+
+// EGL 1.1
+EGLBoolean EGLAPIENTRY EGL_BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
+ ", EGLint buffer = %d)",
+ (uintptr_t)dpy, (uintptr_t)surface, buffer);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Surface *eglSurface = static_cast<Surface *>(surface);
+ gl::Context *context = thread->getContext();
+ gl::Texture *textureObject = nullptr;
+
+ ANGLE_EGL_TRY_RETURN(
+ thread, ValidateBindTexImage(display, eglSurface, surface, buffer, context, &textureObject),
+ "eglBindTexImage", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ if (context)
+ {
+ ANGLE_EGL_TRY_RETURN(thread, eglSurface->bindTexImage(context, textureObject, buffer),
+ "eglBindTexImage", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_SurfaceAttrib(EGLDisplay dpy,
+ EGLSurface surface,
+ EGLint attribute,
+ EGLint value)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
+ ", EGLint attribute = %d, EGLint "
+ "value = %d)",
+ (uintptr_t)dpy, (uintptr_t)surface, attribute, value);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Surface *eglSurface = static_cast<Surface *>(surface);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateSurfaceAttrib(display, eglSurface, attribute, value),
+ "eglSurfaceAttrib", GetSurfaceIfValid(display, eglSurface), EGL_FALSE);
+
+ SetSurfaceAttrib(eglSurface, attribute, value);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSurface surface = 0x%016" PRIxPTR
+ ", EGLint buffer = %d)",
+ (uintptr_t)dpy, (uintptr_t)surface, buffer);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Surface *eglSurface = static_cast<Surface *>(surface);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateReleaseTexImage(display, eglSurface, surface, buffer),
+ "eglReleaseTexImage", GetSurfaceIfValid(display, eglSurface), 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 EGLAPIENTRY EGL_SwapInterval(EGLDisplay dpy, EGLint interval)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLint interval = %d)", (uintptr_t)dpy, interval);
+ Thread *thread = egl::GetCurrentThread();
+ gl::Context *context = thread->getContext();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Surface *draw_surface = static_cast<Surface *>(thread->getCurrentDrawSurface());
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateSwapInterval(display, draw_surface, context),
+ "eglSwapInterval", GetDisplayIfValid(display), EGL_FALSE);
+
+ const egl::Config *surfaceConfig = draw_surface->getConfig();
+ EGLint clampedInterval = std::min(std::max(interval, surfaceConfig->minSwapInterval),
+ surfaceConfig->maxSwapInterval);
+
+ draw_surface->setSwapInterval(clampedInterval);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+// EGL 1.2
+EGLBoolean EGLAPIENTRY EGL_BindAPI(EGLenum api)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLenum api = 0x%X)", api);
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateBindAPI(api), "eglBindAPI", GetThreadIfValid(thread),
+ EGL_FALSE);
+
+ thread->setAPI(api);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLenum EGLAPIENTRY EGL_QueryAPI(void)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("()");
+ Thread *thread = egl::GetCurrentThread();
+
+ EGLenum API = thread->getAPI();
+
+ thread->setSuccess();
+ return API;
+}
+
+EGLSurface EGLAPIENTRY EGL_CreatePbufferFromClientBuffer(EGLDisplay dpy,
+ EGLenum buftype,
+ EGLClientBuffer buffer,
+ EGLConfig config,
+ const EGLint *attrib_list)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR
+ ", EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%016" PRIxPTR
+ ", "
+ "EGLConfig config = 0x%016" PRIxPTR ", const EGLint *attrib_list = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, buftype, (uintptr_t)buffer, (uintptr_t)config, (uintptr_t)attrib_list);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Config *configuration = static_cast<Config *>(config);
+ AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
+
+ ANGLE_EGL_TRY_RETURN(
+ thread,
+ ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes),
+ "eglCreatePbufferFromClientBuffer", GetDisplayIfValid(display), EGL_NO_SURFACE);
+
+ egl::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);
+}
+
+EGLBoolean EGLAPIENTRY EGL_ReleaseThread(void)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("()");
+ Thread *thread = egl::GetCurrentThread();
+
+ Surface *previousDraw = thread->getCurrentDrawSurface();
+ Surface *previousRead = thread->getCurrentReadSurface();
+ gl::Context *previousContext = thread->getContext();
+ egl::Display *previousDisplay = thread->getDisplay();
+
+ // Only call makeCurrent if the context or surfaces have changed.
+ if (previousDraw != EGL_NO_SURFACE || previousRead != EGL_NO_SURFACE ||
+ previousContext != EGL_NO_CONTEXT)
+ {
+ if (previousDisplay != EGL_NO_DISPLAY)
+ {
+ ANGLE_EGL_TRY_RETURN(thread,
+ previousDisplay->makeCurrent(thread, nullptr, nullptr, nullptr),
+ "eglReleaseThread", nullptr, EGL_FALSE);
+ }
+
+ SetContextCurrent(thread, nullptr);
+ }
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_WaitClient(void)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("()");
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = thread->getDisplay();
+ gl::Context *context = thread->getContext();
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateDisplay(display), "eglWaitClient",
+ GetContextIfValid(display, context), EGL_FALSE);
+
+ ANGLE_EGL_TRY_RETURN(thread, display->waitClient(context), "eglWaitClient",
+ GetContextIfValid(display, context), EGL_FALSE);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+// EGL 1.4
+EGLContext EGLAPIENTRY EGL_GetCurrentContext(void)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("()");
+ Thread *thread = egl::GetCurrentThread();
+
+ gl::Context *context = thread->getContext();
+
+ thread->setSuccess();
+ return static_cast<EGLContext>(context);
+}
+
+// EGL 1.5
+EGLSync EGLAPIENTRY EGL_CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR
+ ", EGLenum type = 0x%X, const EGLint* attrib_list = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, type, (uintptr_t)attrib_list);
+
+ Thread *thread = egl::GetCurrentThread();
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ AttributeMap attributes = AttributeMap::CreateFromAttribArray(attrib_list);
+
+ gl::Context *currentContext = thread->getContext();
+ egl::Display *currentDisplay = currentContext ? currentContext->getDisplay() : nullptr;
+
+ ANGLE_EGL_TRY_RETURN(
+ thread, ValidateCreateSyncKHR(display, type, attributes, currentDisplay, currentContext),
+ "eglCreateSync", GetDisplayIfValid(display), EGL_NO_SYNC);
+
+ egl::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);
+}
+
+EGLBoolean EGLAPIENTRY EGL_DestroySync(EGLDisplay dpy, EGLSync sync)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSync sync = 0x%016" PRIxPTR ")", (uintptr_t)dpy,
+ (uintptr_t)sync);
+
+ Thread *thread = egl::GetCurrentThread();
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ egl::Sync *syncObject = static_cast<Sync *>(sync);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateDestroySync(display, syncObject), "eglDestroySync",
+ GetDisplayIfValid(display), EGL_FALSE);
+
+ display->destroySync(syncObject);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLint EGLAPIENTRY EGL_ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSync sync = 0x%016" PRIxPTR
+ ", EGLint flags = 0x%X, EGLTime timeout = "
+ "%llu)",
+ (uintptr_t)dpy, (uintptr_t)sync, flags, static_cast<unsigned long long>(timeout));
+
+ Thread *thread = egl::GetCurrentThread();
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ egl::Sync *syncObject = static_cast<Sync *>(sync);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateClientWaitSync(display, syncObject, flags, timeout),
+ "eglClientWaitSync", GetSyncIfValid(display, syncObject), 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 EGLAPIENTRY EGL_GetSyncAttrib(EGLDisplay dpy,
+ EGLSync sync,
+ EGLint attribute,
+ EGLAttrib *value)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLSync sync = 0x%016" PRIxPTR
+ ", EGLint attribute = 0x%X, EGLAttrib "
+ "*value = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)sync, attribute, (uintptr_t)value);
+
+ Thread *thread = egl::GetCurrentThread();
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ egl::Sync *syncObject = static_cast<Sync *>(sync);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateGetSyncAttrib(display, syncObject, attribute, value),
+ "eglGetSyncAttrib", GetSyncIfValid(display, syncObject), EGL_FALSE);
+
+ 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;
+}
+
+EGLImage EGLAPIENTRY EGL_CreateImage(EGLDisplay dpy,
+ EGLContext ctx,
+ EGLenum target,
+ EGLClientBuffer buffer,
+ const EGLAttrib *attrib_list)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLContext ctx = 0x%016" PRIxPTR
+ ", EGLenum target = 0x%X, "
+ "EGLClientBuffer buffer = 0x%016" PRIxPTR
+ ", const EGLAttrib *attrib_list = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)ctx, target, (uintptr_t)buffer, (uintptr_t)attrib_list);
+ Thread *thread = egl::GetCurrentThread();
+
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ gl::Context *context = static_cast<gl::Context *>(ctx);
+ AttributeMap attributes = AttributeMap::CreateFromIntArray((const EGLint *)attrib_list);
+
+ Error error = ValidateCreateImage(display, context, target, buffer, attributes);
+ if (error.isError())
+ {
+ thread->setError(error, GetDebug(), "eglCreateImage", GetDisplayIfValid(display));
+ return EGL_NO_IMAGE;
+ }
+
+ Image *image = nullptr;
+ error = display->createImage(context, target, buffer, attributes, &image);
+ if (error.isError())
+ {
+ thread->setError(error, GetDebug(), "eglCreateImage", GetDisplayIfValid(display));
+ return EGL_NO_IMAGE;
+ }
+
+ thread->setSuccess();
+ return static_cast<EGLImage>(image);
+}
+
+EGLBoolean EGLAPIENTRY EGL_DestroyImage(EGLDisplay dpy, EGLImage image)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLImage image = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)image);
+ Thread *thread = egl::GetCurrentThread();
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ Image *img = static_cast<Image *>(image);
+
+ Error error = ValidateDestroyImage(display, img);
+ if (error.isError())
+ {
+ thread->setError(error, GetDebug(), "eglDestroyImage", GetImageIfValid(display, img));
+ return EGL_FALSE;
+ }
+
+ display->destroyImage(img);
+
+ thread->setSuccess();
+ return EGL_TRUE;
+}
+
+EGLDisplay EGLAPIENTRY EGL_GetPlatformDisplay(EGLenum platform,
+ void *native_display,
+ const EGLAttrib *attrib_list)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLenum platform = %d, void* native_display = 0x%016" PRIxPTR
+ ", const EGLint* attrib_list = "
+ "0x%016" PRIxPTR ")",
+ platform, (uintptr_t)native_display, (uintptr_t)attrib_list);
+ Thread *thread = egl::GetCurrentThread();
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateGetPlatformDisplay(platform, native_display, attrib_list),
+ "eglGetPlatformDisplay", GetThreadIfValid(thread), EGL_NO_DISPLAY);
+
+ const auto &attribMap = AttributeMap::CreateFromAttribArray(attrib_list);
+ if (platform == EGL_PLATFORM_ANGLE_ANGLE)
+ {
+ return egl::Display::GetDisplayFromNativeDisplay(
+ gl::bitCast<EGLNativeDisplayType>(native_display), attribMap);
+ }
+ else if (platform == EGL_PLATFORM_DEVICE_EXT)
+ {
+ Device *eglDevice = static_cast<Device *>(native_display);
+ return egl::Display::GetDisplayFromDevice(eglDevice, attribMap);
+ }
+ else
+ {
+ UNREACHABLE();
+ return EGL_NO_DISPLAY;
+ }
+}
+
+EGLSurface EGLAPIENTRY EGL_CreatePlatformWindowSurface(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_window,
+ const EGLAttrib *attrib_list)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLConfig config = 0x%016" PRIxPTR
+ ", void* native_window = 0x%016" PRIxPTR
+ ", "
+ "const EGLint* attrib_list = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)native_window, (uintptr_t)attrib_list);
+ Thread *thread = egl::GetCurrentThread();
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+
+ UNIMPLEMENTED();
+ thread->setError(EglBadDisplay() << "eglCreatePlatformWindowSurface unimplemented.", GetDebug(),
+ "eglCreatePlatformWindowSurface", GetDisplayIfValid(display));
+ return EGL_NO_SURFACE;
+}
+
+EGLSurface EGLAPIENTRY EGL_CreatePlatformPixmapSurface(EGLDisplay dpy,
+ EGLConfig config,
+ void *native_pixmap,
+ const EGLAttrib *attrib_list)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy = 0x%016" PRIxPTR ", EGLConfig config = 0x%016" PRIxPTR
+ ", void* native_pixmap = 0x%016" PRIxPTR
+ ", "
+ "const EGLint* attrib_list = 0x%016" PRIxPTR ")",
+ (uintptr_t)dpy, (uintptr_t)config, (uintptr_t)native_pixmap, (uintptr_t)attrib_list);
+ Thread *thread = egl::GetCurrentThread();
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+
+ UNIMPLEMENTED();
+ thread->setError(EglBadDisplay() << "eglCreatePlatformPixmapSurface unimplemented.", GetDebug(),
+ "eglCreatePlatformPixmapSurface", GetDisplayIfValid(display));
+ return EGL_NO_SURFACE;
+}
+
+EGLBoolean EGLAPIENTRY EGL_WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(EGLDisplay dpy =0x%016" PRIxPTR "p, EGLSync sync = 0x%016" PRIxPTR
+ ", EGLint flags = 0x%X)",
+ (uintptr_t)dpy, (uintptr_t)sync, flags);
+
+ Thread *thread = egl::GetCurrentThread();
+ egl::Display *display = static_cast<egl::Display *>(dpy);
+ gl::Context *context = thread->getContext();
+ egl::Sync *syncObject = static_cast<Sync *>(sync);
+
+ ANGLE_EGL_TRY_RETURN(thread, ValidateWaitSync(display, context, syncObject, flags),
+ "eglWaitSync", GetSyncIfValid(display, syncObject), 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;
+}
+
+__eglMustCastToProperFunctionPointerType EGLAPIENTRY EGL_GetProcAddress(const char *procname)
+{
+ ANGLE_SCOPED_GLOBAL_LOCK();
+ EVENT("(const char *procname = \"%s\")", procname);
+ Thread *thread = egl::GetCurrentThread();
+
+ 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;
+}
+} // extern "C"