summaryrefslogtreecommitdiffstats
path: root/gfx/angle/src/libGLESv2/entry_points_egl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/src/libGLESv2/entry_points_egl.cpp')
-rwxr-xr-xgfx/angle/src/libGLESv2/entry_points_egl.cpp1895
1 files changed, 1895 insertions, 0 deletions
diff --git a/gfx/angle/src/libGLESv2/entry_points_egl.cpp b/gfx/angle/src/libGLESv2/entry_points_egl.cpp
new file mode 100755
index 000000000..dc0ccb5f7
--- /dev/null
+++ b/gfx/angle/src/libGLESv2/entry_points_egl.cpp
@@ -0,0 +1,1895 @@
+//
+// 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 "libGLESv2/entry_points_egl_ext.h"
+#include "libGLESv2/entry_points_gles_2_0.h"
+#include "libGLESv2/entry_points_gles_2_0_ext.h"
+#include "libGLESv2/entry_points_gles_3_0.h"
+#include "libGLESv2/entry_points_gles_3_1.h"
+#include "libGLESv2/global_state.h"
+
+#include "libANGLE/Context.h"
+#include "libANGLE/Display.h"
+#include "libANGLE/Texture.h"
+#include "libANGLE/Thread.h"
+#include "libANGLE/Surface.h"
+#include "libANGLE/validationEGL.h"
+
+#include "common/debug.h"
+#include "common/version.h"
+
+#include "platform/Platform.h"
+
+#include <EGL/eglext.h>
+
+namespace egl
+{
+
+// EGL 1.0
+EGLint EGLAPIENTRY GetError(void)
+{
+ EVENT("()");
+ Thread *thread = GetCurrentThread();
+
+ EGLint error = thread->getError();
+ thread->setError(Error(EGL_SUCCESS));
+ return error;
+}
+
+EGLDisplay EGLAPIENTRY GetDisplay(EGLNativeDisplayType display_id)
+{
+ EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id);
+
+ return Display::GetDisplayFromAttribs(reinterpret_cast<void *>(display_id), AttributeMap());
+}
+
+EGLBoolean EGLAPIENTRY Initialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", dpy,
+ major, minor);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display *>(dpy);
+ if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display))
+ {
+ thread->setError(Error(EGL_BAD_DISPLAY));
+ return EGL_FALSE;
+ }
+
+ Error error = display->initialize();
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ if (major) *major = 1;
+ if (minor) *minor = 4;
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY Terminate(EGLDisplay dpy)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display *>(dpy);
+ if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display))
+ {
+ thread->setError(Error(EGL_BAD_DISPLAY));
+ return EGL_FALSE;
+ }
+
+ if (display->isValidContext(thread->getContext()))
+ {
+ thread->setCurrent(nullptr, nullptr, nullptr, nullptr);
+ }
+
+ display->terminate();
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+const char *EGLAPIENTRY QueryString(EGLDisplay dpy, EGLint name)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ if (!(display == EGL_NO_DISPLAY && name == EGL_EXTENSIONS))
+ {
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return NULL;
+ }
+ }
+
+ const char *result;
+ 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.4 (ANGLE " ANGLE_VERSION_STRING ")";
+ break;
+ default:
+ thread->setError(Error(EGL_BAD_PARAMETER));
+ return NULL;
+ }
+
+ thread->setError(Error(EGL_SUCCESS));
+ return result;
+}
+
+EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+ EVENT(
+ "(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, "
+ "EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
+ dpy, configs, config_size, num_config);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ if (!num_config)
+ {
+ thread->setError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+
+ std::vector<const Config*> filteredConfigs = display->getConfigs(AttributeMap());
+ if (configs)
+ {
+ filteredConfigs.resize(std::min<size_t>(filteredConfigs.size(), config_size));
+ for (size_t i = 0; i < filteredConfigs.size(); i++)
+ {
+ configs[i] = const_cast<Config*>(filteredConfigs[i]);
+ }
+ }
+ *num_config = static_cast<EGLint>(filteredConfigs.size());
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+{
+ EVENT(
+ "(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, "
+ "EGLConfig *configs = 0x%0.8p, EGLint config_size = %d, EGLint *num_config = 0x%0.8p)",
+ dpy, attrib_list, configs, config_size, num_config);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ if (!num_config)
+ {
+ thread->setError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+
+ std::vector<const Config *> filteredConfigs =
+ display->getConfigs(AttributeMap::CreateFromIntArray(attrib_list));
+ if (configs)
+ {
+ filteredConfigs.resize(std::min<size_t>(filteredConfigs.size(), config_size));
+ for (size_t i = 0; i < filteredConfigs.size(); i++)
+ {
+ configs[i] = const_cast<Config*>(filteredConfigs[i]);
+ }
+ }
+ *num_config = static_cast<EGLint>(filteredConfigs.size());
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+{
+ EVENT(
+ "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint "
+ "*value = 0x%0.8p)",
+ dpy, config, attribute, value);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Config *configuration = static_cast<Config*>(config);
+
+ Error error = ValidateConfig(display, configuration);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ if (!display->getConfigAttrib(configuration, attribute, value))
+ {
+ thread->setError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
+ }
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list)
+{
+ EVENT(
+ "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, "
+ "const EGLint *attrib_list = 0x%0.8p)",
+ dpy, config, win, attrib_list);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Config *configuration = static_cast<Config*>(config);
+ AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
+
+ Error error = ValidateCreateWindowSurface(display, configuration, win, attributes);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ egl::Surface *surface = nullptr;
+ error = display->createWindowSurface(configuration, win, attributes, &surface);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+{
+ EVENT(
+ "(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = "
+ "0x%0.8p)",
+ dpy, config, attrib_list);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Config *configuration = static_cast<Config*>(config);
+ AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
+
+ Error error = ValidateCreatePbufferSurface(display, configuration, attributes);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ egl::Surface *surface = nullptr;
+ error = display->createPbufferSurface(configuration, attributes, &surface);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLSurface EGLAPIENTRY CreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, "
+ "const EGLint *attrib_list = 0x%0.8p)", dpy, config, pixmap, attrib_list);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Config *configuration = static_cast<Config*>(config);
+
+ Error error = ValidateConfig(display, configuration);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ UNIMPLEMENTED(); // FIXME
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_NO_SURFACE;
+}
+
+EGLBoolean EGLAPIENTRY DestroySurface(EGLDisplay dpy, EGLSurface surface)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = static_cast<Surface*>(surface);
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ if (surface == EGL_NO_SURFACE)
+ {
+ thread->setError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ display->destroySurface((Surface*)surface);
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
+ dpy, surface, attribute, value);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = (Surface*)surface;
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ if (surface == EGL_NO_SURFACE)
+ {
+ thread->setError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ switch (attribute)
+ {
+ case EGL_VG_ALPHA_FORMAT:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_VG_COLORSPACE:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_CONFIG_ID:
+ *value = eglSurface->getConfig()->configID;
+ break;
+ case EGL_HEIGHT:
+ *value = eglSurface->getHeight();
+ break;
+ case EGL_HORIZONTAL_RESOLUTION:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_LARGEST_PBUFFER:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_MIPMAP_TEXTURE:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_MIPMAP_LEVEL:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_MULTISAMPLE_RESOLVE:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_PIXEL_ASPECT_RATIO:
+ *value = eglSurface->getPixelAspectRatio();
+ break;
+ case EGL_RENDER_BUFFER:
+ *value = eglSurface->getRenderBuffer();
+ break;
+ case EGL_SWAP_BEHAVIOR:
+ *value = eglSurface->getSwapBehavior();
+ break;
+ case EGL_TEXTURE_FORMAT:
+ *value = eglSurface->getTextureFormat();
+ break;
+ case EGL_TEXTURE_TARGET:
+ *value = eglSurface->getTextureTarget();
+ break;
+ case EGL_VERTICAL_RESOLUTION:
+ UNIMPLEMENTED(); // FIXME
+ break;
+ case EGL_WIDTH:
+ *value = eglSurface->getWidth();
+ break;
+ case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
+ if (!display->getExtensions().postSubBuffer)
+ {
+ thread->setError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
+ }
+ *value = eglSurface->isPostSubBufferSupported();
+ break;
+ case EGL_FIXED_SIZE_ANGLE:
+ if (!display->getExtensions().windowFixedSize)
+ {
+ thread->setError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
+ }
+ *value = eglSurface->isFixedSize();
+ break;
+ case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE:
+ if (!display->getExtensions().flexibleSurfaceCompatibility)
+ {
+ thread->setError(
+ Error(EGL_BAD_ATTRIBUTE,
+ "EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE cannot be used without "
+ "EGL_ANGLE_flexible_surface_compatibility support."));
+ return EGL_FALSE;
+ }
+ *value = eglSurface->flexibleSurfaceCompatibilityRequested();
+ break;
+ case EGL_SURFACE_ORIENTATION_ANGLE:
+ if (!display->getExtensions().surfaceOrientation)
+ {
+ thread->setError(Error(EGL_BAD_ATTRIBUTE,
+ "EGL_SURFACE_ORIENTATION_ANGLE cannot be queried without "
+ "EGL_ANGLE_surface_orientation support."));
+ return EGL_FALSE;
+ }
+ *value = eglSurface->getOrientation();
+ break;
+ case EGL_DIRECT_COMPOSITION_ANGLE:
+ if (!display->getExtensions().directComposition)
+ {
+ thread->setError(Error(EGL_BAD_ATTRIBUTE,
+ "EGL_DIRECT_COMPOSITION_ANGLE cannot be used without "
+ "EGL_ANGLE_direct_composition support."));
+ return EGL_FALSE;
+ }
+ *value = eglSurface->directComposition();
+ break;
+ default:
+ thread->setError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
+ }
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, "
+ "const EGLint *attrib_list = 0x%0.8p)", dpy, config, share_context, attrib_list);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Config *configuration = static_cast<Config*>(config);
+ gl::Context* sharedGLContext = static_cast<gl::Context*>(share_context);
+ AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
+
+ Error error = ValidateCreateContext(display, configuration, sharedGLContext, attributes);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_NO_CONTEXT;
+ }
+
+ gl::Context *context = nullptr;
+ error = display->createContext(configuration, sharedGLContext, attributes, &context);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_NO_CONTEXT;
+ }
+
+ thread->setError(Error(EGL_SUCCESS));
+ return static_cast<EGLContext>(context);
+}
+
+EGLBoolean EGLAPIENTRY DestroyContext(EGLDisplay dpy, EGLContext ctx)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ gl::Context *context = static_cast<gl::Context*>(ctx);
+
+ Error error = ValidateContext(display, context);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ if (ctx == EGL_NO_CONTEXT)
+ {
+ thread->setError(Error(EGL_BAD_CONTEXT));
+ return EGL_FALSE;
+ }
+
+ if (context == thread->getContext())
+ {
+ thread->setCurrent(nullptr, thread->getDrawSurface(), thread->getReadSurface(), nullptr);
+ }
+
+ display->destroyContext(context);
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY MakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)",
+ dpy, draw, read, ctx);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ gl::Context *context = static_cast<gl::Context*>(ctx);
+
+ // If ctx is EGL_NO_CONTEXT and either draw or read are not EGL_NO_SURFACE, an EGL_BAD_MATCH
+ // error is generated.
+ if (ctx == EGL_NO_CONTEXT && (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
+ {
+ thread->setError(Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
+ }
+
+ if (ctx != EGL_NO_CONTEXT && draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE)
+ {
+ thread->setError(Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
+ }
+
+ // If either of draw or read is a valid surface and the other is EGL_NO_SURFACE, an
+ // EGL_BAD_MATCH error is generated.
+ if ((read == EGL_NO_SURFACE) != (draw == EGL_NO_SURFACE))
+ {
+ thread->setError(Error(
+ EGL_BAD_MATCH, "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE"));
+ return EGL_FALSE;
+ }
+
+ if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display))
+ {
+ thread->setError(Error(EGL_BAD_DISPLAY, "'dpy' not a valid EGLDisplay handle"));
+ return EGL_FALSE;
+ }
+
+ // EGL 1.5 spec: dpy can be uninitialized if all other parameters are null
+ if (!display->isInitialized() && (ctx != EGL_NO_CONTEXT || draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE))
+ {
+ thread->setError(Error(EGL_NOT_INITIALIZED, "'dpy' not initialized"));
+ return EGL_FALSE;
+ }
+
+ if (ctx != EGL_NO_CONTEXT)
+ {
+ Error error = ValidateContext(display, context);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+ }
+
+ if (display->isInitialized() && display->testDeviceLost())
+ {
+ thread->setError(Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
+ }
+
+ Surface *drawSurface = static_cast<Surface*>(draw);
+ if (draw != EGL_NO_SURFACE)
+ {
+ Error error = ValidateSurface(display, drawSurface);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+ }
+
+ Surface *readSurface = static_cast<Surface*>(read);
+ if (read != EGL_NO_SURFACE)
+ {
+ Error error = ValidateSurface(display, readSurface);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+ }
+
+ if (readSurface)
+ {
+ Error readCompatError =
+ ValidateCompatibleConfigs(display, readSurface->getConfig(), readSurface,
+ context->getConfig(), readSurface->getType());
+ if (readCompatError.isError())
+ {
+ thread->setError(readCompatError);
+ return EGL_FALSE;
+ }
+ }
+
+ if (draw != read)
+ {
+ UNIMPLEMENTED(); // FIXME
+
+ if (drawSurface)
+ {
+ Error drawCompatError =
+ ValidateCompatibleConfigs(display, drawSurface->getConfig(), drawSurface,
+ context->getConfig(), drawSurface->getType());
+ if (drawCompatError.isError())
+ {
+ thread->setError(drawCompatError);
+ return EGL_FALSE;
+ }
+ }
+ }
+
+ Error makeCurrentError = display->makeCurrent(drawSurface, readSurface, context);
+ if (makeCurrentError.isError())
+ {
+ thread->setError(makeCurrentError);
+ return EGL_FALSE;
+ }
+
+ gl::Context *previousContext = thread->getContext();
+ thread->setCurrent(display, drawSurface, readSurface, context);
+
+ // Release the surface from the previously-current context, to allow
+ // destroyed surfaces to delete themselves.
+ if (previousContext != nullptr && context != previousContext)
+ {
+ previousContext->releaseSurface();
+ }
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw)
+{
+ EVENT("(EGLint readdraw = %d)", readdraw);
+ Thread *thread = GetCurrentThread();
+
+ if (readdraw == EGL_READ)
+ {
+ thread->setError(Error(EGL_SUCCESS));
+ return thread->getReadSurface();
+ }
+ else if (readdraw == EGL_DRAW)
+ {
+ thread->setError(Error(EGL_SUCCESS));
+ return thread->getDrawSurface();
+ }
+ else
+ {
+ thread->setError(Error(EGL_BAD_PARAMETER));
+ return EGL_NO_SURFACE;
+ }
+}
+
+EGLDisplay EGLAPIENTRY GetCurrentDisplay(void)
+{
+ EVENT("()");
+ Thread *thread = GetCurrentThread();
+
+ EGLDisplay dpy = thread->getDisplay();
+
+ thread->setError(Error(EGL_SUCCESS));
+ return dpy;
+}
+
+EGLBoolean EGLAPIENTRY QueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)",
+ dpy, ctx, attribute, value);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ gl::Context *context = static_cast<gl::Context*>(ctx);
+
+ Error error = ValidateContext(display, context);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ switch (attribute)
+ {
+ case EGL_CONFIG_ID:
+ *value = context->getConfig()->configID;
+ break;
+ case EGL_CONTEXT_CLIENT_TYPE:
+ *value = context->getClientType();
+ break;
+ case EGL_CONTEXT_CLIENT_VERSION:
+ *value = context->getClientMajorVersion();
+ break;
+ case EGL_RENDER_BUFFER:
+ *value = context->getRenderBuffer();
+ break;
+ default:
+ thread->setError(Error(EGL_BAD_ATTRIBUTE));
+ return EGL_FALSE;
+ }
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY WaitGL(void)
+{
+ EVENT("()");
+ Thread *thread = GetCurrentThread();
+
+ Display *display = thread->getDisplay();
+
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ // eglWaitGL like calling eglWaitClient with the OpenGL ES API bound. Since we only implement
+ // OpenGL ES we can do the call directly.
+ error = display->waitClient();
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY WaitNative(EGLint engine)
+{
+ EVENT("(EGLint engine = %d)", engine);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = thread->getDisplay();
+
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ if (engine != EGL_CORE_NATIVE_ENGINE)
+ {
+ thread->setError(
+ Error(EGL_BAD_PARAMETER, "the 'engine' parameter has an unrecognized value"));
+ }
+
+ error = display->waitNative(engine, thread->getDrawSurface(), thread->getReadSurface());
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY SwapBuffers(EGLDisplay dpy, EGLSurface surface)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = (Surface*)surface;
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ if (display->testDeviceLost())
+ {
+ thread->setError(Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
+ }
+
+ if (surface == EGL_NO_SURFACE)
+ {
+ thread->setError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ error = eglSurface->swap();
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY CopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLNativePixmapType target = 0x%0.8p)", dpy, surface, target);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = static_cast<Surface*>(surface);
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ if (display->testDeviceLost())
+ {
+ thread->setError(Error(EGL_CONTEXT_LOST));
+ return EGL_FALSE;
+ }
+
+ UNIMPLEMENTED(); // FIXME
+
+ thread->setError(Error(EGL_SUCCESS));
+ return 0;
+}
+
+// EGL 1.1
+EGLBoolean EGLAPIENTRY BindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = static_cast<Surface*>(surface);
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ if (buffer != EGL_BACK_BUFFER)
+ {
+ thread->setError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+
+ if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT)
+ {
+ thread->setError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ if (eglSurface->getBoundTexture())
+ {
+ thread->setError(Error(EGL_BAD_ACCESS));
+ return EGL_FALSE;
+ }
+
+ if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
+ {
+ thread->setError(Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
+ }
+
+ gl::Context *context = thread->getContext();
+ if (context)
+ {
+ gl::Texture *textureObject = context->getTargetTexture(GL_TEXTURE_2D);
+ ASSERT(textureObject != NULL);
+
+ if (textureObject->getImmutableFormat())
+ {
+ thread->setError(Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
+ }
+
+ error = eglSurface->bindTexImage(textureObject, buffer);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+ }
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint value = %d)",
+ dpy, surface, attribute, value);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = static_cast<Surface*>(surface);
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ UNIMPLEMENTED(); // FIXME
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint buffer = %d)", dpy, surface, buffer);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Surface *eglSurface = static_cast<Surface*>(surface);
+
+ Error error = ValidateSurface(display, eglSurface);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ if (buffer != EGL_BACK_BUFFER)
+ {
+ thread->setError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+
+ if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT)
+ {
+ thread->setError(Error(EGL_BAD_SURFACE));
+ return EGL_FALSE;
+ }
+
+ if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE)
+ {
+ thread->setError(Error(EGL_BAD_MATCH));
+ return EGL_FALSE;
+ }
+
+ gl::Texture *texture = eglSurface->getBoundTexture();
+
+ if (texture)
+ {
+ error = eglSurface->releaseTexImage(buffer);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+ }
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY SwapInterval(EGLDisplay dpy, EGLint interval)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ Surface *draw_surface = static_cast<Surface *>(thread->getDrawSurface());
+
+ if (draw_surface == NULL)
+ {
+ thread->setError(Error(EGL_BAD_SURFACE));
+ return 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->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+
+// EGL 1.2
+EGLBoolean EGLAPIENTRY BindAPI(EGLenum api)
+{
+ EVENT("(EGLenum api = 0x%X)", api);
+ Thread *thread = GetCurrentThread();
+
+ switch (api)
+ {
+ case EGL_OPENGL_API:
+ case EGL_OPENVG_API:
+ thread->setError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE; // Not supported by this implementation
+ case EGL_OPENGL_ES_API:
+ break;
+ default:
+ thread->setError(Error(EGL_BAD_PARAMETER));
+ return EGL_FALSE;
+ }
+
+ thread->setAPI(api);
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLenum EGLAPIENTRY QueryAPI(void)
+{
+ EVENT("()");
+ Thread *thread = GetCurrentThread();
+
+ EGLenum API = thread->getAPI();
+
+ thread->setError(Error(EGL_SUCCESS));
+ return API;
+}
+
+EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, "
+ "EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)",
+ dpy, buftype, buffer, config, attrib_list);
+ Thread *thread = GetCurrentThread();
+
+ Display *display = static_cast<Display*>(dpy);
+ Config *configuration = static_cast<Config*>(config);
+ AttributeMap attributes = AttributeMap::CreateFromIntArray(attrib_list);
+
+ Error error = ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ egl::Surface *surface = nullptr;
+ error = display->createPbufferFromClientBuffer(configuration, buftype, buffer, attributes,
+ &surface);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_NO_SURFACE;
+ }
+
+ return static_cast<EGLSurface>(surface);
+}
+
+EGLBoolean EGLAPIENTRY ReleaseThread(void)
+{
+ EVENT("()");
+ Thread *thread = GetCurrentThread();
+
+ MakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE);
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+EGLBoolean EGLAPIENTRY WaitClient(void)
+{
+ EVENT("()");
+ Thread *thread = GetCurrentThread();
+
+ Display *display = thread->getDisplay();
+
+ Error error = ValidateDisplay(display);
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ error = display->waitClient();
+ if (error.isError())
+ {
+ thread->setError(error);
+ return EGL_FALSE;
+ }
+
+ thread->setError(Error(EGL_SUCCESS));
+ return EGL_TRUE;
+}
+
+// EGL 1.4
+EGLContext EGLAPIENTRY GetCurrentContext(void)
+{
+ EVENT("()");
+ Thread *thread = GetCurrentThread();
+
+ gl::Context *context = thread->getContext();
+
+ thread->setError(Error(EGL_SUCCESS));
+ return static_cast<EGLContext>(context);
+}
+
+// EGL 1.5
+EGLSync EGLAPIENTRY CreateSync(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLenum type = 0x%X, const EGLint* attrib_list = 0x%0.8p)", dpy, type, attrib_list);
+ Thread *thread = GetCurrentThread();
+
+ UNIMPLEMENTED();
+ thread->setError(Error(EGL_BAD_DISPLAY, "eglCreateSync unimplemented."));
+ return EGL_NO_SYNC;
+}
+
+EGLBoolean EGLAPIENTRY DestroySync(EGLDisplay dpy, EGLSync sync)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p)", dpy, sync);
+ Thread *thread = GetCurrentThread();
+
+ UNIMPLEMENTED();
+ thread->setError(Error(EGL_BAD_DISPLAY, "eglDestroySync unimplemented."));
+ return EGL_FALSE;
+}
+
+EGLint EGLAPIENTRY ClientWaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X, EGLTime timeout = %d)", dpy, sync, flags, timeout);
+ Thread *thread = GetCurrentThread();
+
+ UNIMPLEMENTED();
+ thread->setError(Error(EGL_BAD_DISPLAY, "eglClientWaitSync unimplemented."));
+ return 0;
+}
+
+EGLBoolean EGLAPIENTRY GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint attribute = 0x%X, EGLAttrib *value = 0x%0.8p)", dpy, sync, attribute, value);
+ Thread *thread = GetCurrentThread();
+
+ UNIMPLEMENTED();
+ thread->setError(Error(EGL_BAD_DISPLAY, "eglSyncAttrib unimplemented."));
+ return EGL_FALSE;
+}
+
+EGLImage EGLAPIENTRY CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLenum target = 0x%X, "
+ "EGLClientBuffer buffer = 0x%0.8p, const EGLAttrib *attrib_list = 0x%0.8p)",
+ dpy, ctx, target, buffer, attrib_list);
+ Thread *thread = GetCurrentThread();
+
+ UNIMPLEMENTED();
+ thread->setError(Error(EGL_BAD_DISPLAY, "eglCreateImage unimplemented."));
+ return EGL_NO_IMAGE;
+}
+
+EGLBoolean EGLAPIENTRY DestroyImage(EGLDisplay dpy, EGLImage image)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLImage image = 0x%0.8p)", dpy, image);
+ Thread *thread = GetCurrentThread();
+
+ UNIMPLEMENTED();
+ thread->setError(Error(EGL_BAD_DISPLAY, "eglDestroyImage unimplemented."));
+ return EGL_FALSE;
+}
+
+EGLDisplay EGLAPIENTRY GetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list)
+{
+ EVENT("(EGLenum platform = %d, void* native_display = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
+ platform, native_display, attrib_list);
+ Thread *thread = GetCurrentThread();
+
+ UNIMPLEMENTED();
+ thread->setError(Error(EGL_BAD_DISPLAY, "eglGetPlatformDisplay unimplemented."));
+ return EGL_NO_DISPLAY;
+}
+
+EGLSurface EGLAPIENTRY CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_window = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
+ dpy, config, native_window, attrib_list);
+ Thread *thread = GetCurrentThread();
+
+ UNIMPLEMENTED();
+ thread->setError(Error(EGL_BAD_DISPLAY, "eglCreatePlatformWindowSurface unimplemented."));
+ return EGL_NO_SURFACE;
+}
+
+EGLSurface EGLAPIENTRY CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, void* native_pixmap = 0x%0.8p, const EGLint* attrib_list = 0x%0.8p)",
+ dpy, config, native_pixmap, attrib_list);
+ Thread *thread = GetCurrentThread();
+
+ UNIMPLEMENTED();
+ thread->setError(Error(EGL_BAD_DISPLAY, "eglCraetePlatformPixmaSurface unimplemented."));
+ return EGL_NO_SURFACE;
+}
+
+EGLBoolean EGLAPIENTRY WaitSync(EGLDisplay dpy, EGLSync sync, EGLint flags)
+{
+ EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X)", dpy, sync, flags);
+ Thread *thread = GetCurrentThread();
+
+ UNIMPLEMENTED();
+ thread->setError(Error(EGL_BAD_DISPLAY, "eglWaitSync unimplemented."));
+ return EGL_FALSE;
+}
+
+__eglMustCastToProperFunctionPointerType EGLAPIENTRY GetProcAddress(const char *procname)
+{
+ EVENT("(const char *procname = \"%s\")", procname);
+ Thread *thread = GetCurrentThread();
+
+ typedef std::map<std::string, __eglMustCastToProperFunctionPointerType> ProcAddressMap;
+ auto generateProcAddressMap = []()
+ {
+ ProcAddressMap map;
+#define INSERT_PROC_ADDRESS(ns, proc) \
+ map[#ns #proc] = reinterpret_cast<__eglMustCastToProperFunctionPointerType>(ns::proc)
+
+#define INSERT_PROC_ADDRESS_NO_NS(name, proc) \
+ map[name] = reinterpret_cast<__eglMustCastToProperFunctionPointerType>(proc)
+
+ // GLES2 core
+ INSERT_PROC_ADDRESS(gl, ActiveTexture);
+ INSERT_PROC_ADDRESS(gl, AttachShader);
+ INSERT_PROC_ADDRESS(gl, BindAttribLocation);
+ INSERT_PROC_ADDRESS(gl, BindBuffer);
+ INSERT_PROC_ADDRESS(gl, BindFramebuffer);
+ INSERT_PROC_ADDRESS(gl, BindRenderbuffer);
+ INSERT_PROC_ADDRESS(gl, BindTexture);
+ INSERT_PROC_ADDRESS(gl, BlendColor);
+ INSERT_PROC_ADDRESS(gl, BlendEquation);
+ INSERT_PROC_ADDRESS(gl, BlendEquationSeparate);
+ INSERT_PROC_ADDRESS(gl, BlendFunc);
+ INSERT_PROC_ADDRESS(gl, BlendFuncSeparate);
+ INSERT_PROC_ADDRESS(gl, BufferData);
+ INSERT_PROC_ADDRESS(gl, BufferSubData);
+ INSERT_PROC_ADDRESS(gl, CheckFramebufferStatus);
+ INSERT_PROC_ADDRESS(gl, Clear);
+ INSERT_PROC_ADDRESS(gl, ClearColor);
+ INSERT_PROC_ADDRESS(gl, ClearDepthf);
+ INSERT_PROC_ADDRESS(gl, ClearStencil);
+ INSERT_PROC_ADDRESS(gl, ColorMask);
+ INSERT_PROC_ADDRESS(gl, CompileShader);
+ INSERT_PROC_ADDRESS(gl, CompressedTexImage2D);
+ INSERT_PROC_ADDRESS(gl, CompressedTexSubImage2D);
+ INSERT_PROC_ADDRESS(gl, CopyTexImage2D);
+ INSERT_PROC_ADDRESS(gl, CopyTexSubImage2D);
+ INSERT_PROC_ADDRESS(gl, CreateProgram);
+ INSERT_PROC_ADDRESS(gl, CreateShader);
+ INSERT_PROC_ADDRESS(gl, CullFace);
+ INSERT_PROC_ADDRESS(gl, DeleteBuffers);
+ INSERT_PROC_ADDRESS(gl, DeleteFramebuffers);
+ INSERT_PROC_ADDRESS(gl, DeleteProgram);
+ INSERT_PROC_ADDRESS(gl, DeleteRenderbuffers);
+ INSERT_PROC_ADDRESS(gl, DeleteShader);
+ INSERT_PROC_ADDRESS(gl, DeleteTextures);
+ INSERT_PROC_ADDRESS(gl, DepthFunc);
+ INSERT_PROC_ADDRESS(gl, DepthMask);
+ INSERT_PROC_ADDRESS(gl, DepthRangef);
+ INSERT_PROC_ADDRESS(gl, DetachShader);
+ INSERT_PROC_ADDRESS(gl, Disable);
+ INSERT_PROC_ADDRESS(gl, DisableVertexAttribArray);
+ INSERT_PROC_ADDRESS(gl, DrawArrays);
+ INSERT_PROC_ADDRESS(gl, DrawElements);
+ INSERT_PROC_ADDRESS(gl, Enable);
+ INSERT_PROC_ADDRESS(gl, EnableVertexAttribArray);
+ INSERT_PROC_ADDRESS(gl, Finish);
+ INSERT_PROC_ADDRESS(gl, Flush);
+ INSERT_PROC_ADDRESS(gl, FramebufferRenderbuffer);
+ INSERT_PROC_ADDRESS(gl, FramebufferTexture2D);
+ INSERT_PROC_ADDRESS(gl, FrontFace);
+ INSERT_PROC_ADDRESS(gl, GenBuffers);
+ INSERT_PROC_ADDRESS(gl, GenerateMipmap);
+ INSERT_PROC_ADDRESS(gl, GenFramebuffers);
+ INSERT_PROC_ADDRESS(gl, GenRenderbuffers);
+ INSERT_PROC_ADDRESS(gl, GenTextures);
+ INSERT_PROC_ADDRESS(gl, GetActiveAttrib);
+ INSERT_PROC_ADDRESS(gl, GetActiveUniform);
+ INSERT_PROC_ADDRESS(gl, GetAttachedShaders);
+ INSERT_PROC_ADDRESS(gl, GetAttribLocation);
+ INSERT_PROC_ADDRESS(gl, GetBooleanv);
+ INSERT_PROC_ADDRESS(gl, GetBufferParameteriv);
+ INSERT_PROC_ADDRESS(gl, GetError);
+ INSERT_PROC_ADDRESS(gl, GetFloatv);
+ INSERT_PROC_ADDRESS(gl, GetFramebufferAttachmentParameteriv);
+ INSERT_PROC_ADDRESS(gl, GetIntegerv);
+ INSERT_PROC_ADDRESS(gl, GetProgramiv);
+ INSERT_PROC_ADDRESS(gl, GetProgramInfoLog);
+ INSERT_PROC_ADDRESS(gl, GetRenderbufferParameteriv);
+ INSERT_PROC_ADDRESS(gl, GetShaderiv);
+ INSERT_PROC_ADDRESS(gl, GetShaderInfoLog);
+ INSERT_PROC_ADDRESS(gl, GetShaderPrecisionFormat);
+ INSERT_PROC_ADDRESS(gl, GetShaderSource);
+ INSERT_PROC_ADDRESS(gl, GetString);
+ INSERT_PROC_ADDRESS(gl, GetTexParameterfv);
+ INSERT_PROC_ADDRESS(gl, GetTexParameteriv);
+ INSERT_PROC_ADDRESS(gl, GetUniformfv);
+ INSERT_PROC_ADDRESS(gl, GetUniformiv);
+ INSERT_PROC_ADDRESS(gl, GetUniformLocation);
+ INSERT_PROC_ADDRESS(gl, GetVertexAttribfv);
+ INSERT_PROC_ADDRESS(gl, GetVertexAttribiv);
+ INSERT_PROC_ADDRESS(gl, GetVertexAttribPointerv);
+ INSERT_PROC_ADDRESS(gl, Hint);
+ INSERT_PROC_ADDRESS(gl, IsBuffer);
+ INSERT_PROC_ADDRESS(gl, IsEnabled);
+ INSERT_PROC_ADDRESS(gl, IsFramebuffer);
+ INSERT_PROC_ADDRESS(gl, IsProgram);
+ INSERT_PROC_ADDRESS(gl, IsRenderbuffer);
+ INSERT_PROC_ADDRESS(gl, IsShader);
+ INSERT_PROC_ADDRESS(gl, IsTexture);
+ INSERT_PROC_ADDRESS(gl, LineWidth);
+ INSERT_PROC_ADDRESS(gl, LinkProgram);
+ INSERT_PROC_ADDRESS(gl, PixelStorei);
+ INSERT_PROC_ADDRESS(gl, PolygonOffset);
+ INSERT_PROC_ADDRESS(gl, ReadPixels);
+ INSERT_PROC_ADDRESS(gl, ReleaseShaderCompiler);
+ INSERT_PROC_ADDRESS(gl, RenderbufferStorage);
+ INSERT_PROC_ADDRESS(gl, SampleCoverage);
+ INSERT_PROC_ADDRESS(gl, Scissor);
+ INSERT_PROC_ADDRESS(gl, ShaderBinary);
+ INSERT_PROC_ADDRESS(gl, ShaderSource);
+ INSERT_PROC_ADDRESS(gl, StencilFunc);
+ INSERT_PROC_ADDRESS(gl, StencilFuncSeparate);
+ INSERT_PROC_ADDRESS(gl, StencilMask);
+ INSERT_PROC_ADDRESS(gl, StencilMaskSeparate);
+ INSERT_PROC_ADDRESS(gl, StencilOp);
+ INSERT_PROC_ADDRESS(gl, StencilOpSeparate);
+ INSERT_PROC_ADDRESS(gl, TexImage2D);
+ INSERT_PROC_ADDRESS(gl, TexParameterf);
+ INSERT_PROC_ADDRESS(gl, TexParameterfv);
+ INSERT_PROC_ADDRESS(gl, TexParameteri);
+ INSERT_PROC_ADDRESS(gl, TexParameteriv);
+ INSERT_PROC_ADDRESS(gl, TexSubImage2D);
+ INSERT_PROC_ADDRESS(gl, Uniform1f);
+ INSERT_PROC_ADDRESS(gl, Uniform1fv);
+ INSERT_PROC_ADDRESS(gl, Uniform1i);
+ INSERT_PROC_ADDRESS(gl, Uniform1iv);
+ INSERT_PROC_ADDRESS(gl, Uniform2f);
+ INSERT_PROC_ADDRESS(gl, Uniform2fv);
+ INSERT_PROC_ADDRESS(gl, Uniform2i);
+ INSERT_PROC_ADDRESS(gl, Uniform2iv);
+ INSERT_PROC_ADDRESS(gl, Uniform3f);
+ INSERT_PROC_ADDRESS(gl, Uniform3fv);
+ INSERT_PROC_ADDRESS(gl, Uniform3i);
+ INSERT_PROC_ADDRESS(gl, Uniform3iv);
+ INSERT_PROC_ADDRESS(gl, Uniform4f);
+ INSERT_PROC_ADDRESS(gl, Uniform4fv);
+ INSERT_PROC_ADDRESS(gl, Uniform4i);
+ INSERT_PROC_ADDRESS(gl, Uniform4iv);
+ INSERT_PROC_ADDRESS(gl, UniformMatrix2fv);
+ INSERT_PROC_ADDRESS(gl, UniformMatrix3fv);
+ INSERT_PROC_ADDRESS(gl, UniformMatrix4fv);
+ INSERT_PROC_ADDRESS(gl, UseProgram);
+ INSERT_PROC_ADDRESS(gl, ValidateProgram);
+ INSERT_PROC_ADDRESS(gl, VertexAttrib1f);
+ INSERT_PROC_ADDRESS(gl, VertexAttrib1fv);
+ INSERT_PROC_ADDRESS(gl, VertexAttrib2f);
+ INSERT_PROC_ADDRESS(gl, VertexAttrib2fv);
+ INSERT_PROC_ADDRESS(gl, VertexAttrib3f);
+ INSERT_PROC_ADDRESS(gl, VertexAttrib3fv);
+ INSERT_PROC_ADDRESS(gl, VertexAttrib4f);
+ INSERT_PROC_ADDRESS(gl, VertexAttrib4fv);
+ INSERT_PROC_ADDRESS(gl, VertexAttribPointer);
+ INSERT_PROC_ADDRESS(gl, Viewport);
+
+ // GL_ANGLE_framebuffer_blit
+ INSERT_PROC_ADDRESS(gl, BlitFramebufferANGLE);
+
+ // GL_ANGLE_framebuffer_multisample
+ INSERT_PROC_ADDRESS(gl, RenderbufferStorageMultisampleANGLE);
+
+ // GL_EXT_discard_framebuffer
+ INSERT_PROC_ADDRESS(gl, DiscardFramebufferEXT);
+
+ // GL_NV_fence
+ INSERT_PROC_ADDRESS(gl, DeleteFencesNV);
+ INSERT_PROC_ADDRESS(gl, GenFencesNV);
+ INSERT_PROC_ADDRESS(gl, IsFenceNV);
+ INSERT_PROC_ADDRESS(gl, TestFenceNV);
+ INSERT_PROC_ADDRESS(gl, GetFenceivNV);
+ INSERT_PROC_ADDRESS(gl, FinishFenceNV);
+ INSERT_PROC_ADDRESS(gl, SetFenceNV);
+
+ // GL_ANGLE_translated_shader_source
+ INSERT_PROC_ADDRESS(gl, GetTranslatedShaderSourceANGLE);
+
+ // GL_EXT_texture_storage
+ INSERT_PROC_ADDRESS(gl, TexStorage2DEXT);
+
+ // GL_EXT_robustness
+ INSERT_PROC_ADDRESS(gl, GetGraphicsResetStatusEXT);
+ INSERT_PROC_ADDRESS(gl, ReadnPixelsEXT);
+ INSERT_PROC_ADDRESS(gl, GetnUniformfvEXT);
+ INSERT_PROC_ADDRESS(gl, GetnUniformivEXT);
+
+ // GL_EXT_occlusion_query_boolean
+ INSERT_PROC_ADDRESS(gl, GenQueriesEXT);
+ INSERT_PROC_ADDRESS(gl, DeleteQueriesEXT);
+ INSERT_PROC_ADDRESS(gl, IsQueryEXT);
+ INSERT_PROC_ADDRESS(gl, BeginQueryEXT);
+ INSERT_PROC_ADDRESS(gl, EndQueryEXT);
+ INSERT_PROC_ADDRESS(gl, GetQueryivEXT);
+ INSERT_PROC_ADDRESS(gl, GetQueryObjectuivEXT);
+
+ // GL_EXT_disjoint_timer_query
+ INSERT_PROC_ADDRESS(gl, GenQueriesEXT);
+ INSERT_PROC_ADDRESS(gl, DeleteQueriesEXT);
+ INSERT_PROC_ADDRESS(gl, IsQueryEXT);
+ INSERT_PROC_ADDRESS(gl, BeginQueryEXT);
+ INSERT_PROC_ADDRESS(gl, EndQueryEXT);
+ INSERT_PROC_ADDRESS(gl, QueryCounterEXT);
+ INSERT_PROC_ADDRESS(gl, GetQueryivEXT);
+ INSERT_PROC_ADDRESS(gl, GetQueryObjectivEXT);
+ INSERT_PROC_ADDRESS(gl, GetQueryObjectuivEXT);
+ INSERT_PROC_ADDRESS(gl, GetQueryObjecti64vEXT);
+ INSERT_PROC_ADDRESS(gl, GetQueryObjectui64vEXT);
+
+ // GL_EXT_draw_buffers
+ INSERT_PROC_ADDRESS(gl, DrawBuffersEXT);
+
+ // GL_ANGLE_instanced_arrays
+ INSERT_PROC_ADDRESS(gl, DrawArraysInstancedANGLE);
+ INSERT_PROC_ADDRESS(gl, DrawElementsInstancedANGLE);
+ INSERT_PROC_ADDRESS(gl, VertexAttribDivisorANGLE);
+
+ // GL_OES_get_program_binary
+ INSERT_PROC_ADDRESS(gl, GetProgramBinaryOES);
+ INSERT_PROC_ADDRESS(gl, ProgramBinaryOES);
+
+ // GL_OES_mapbuffer
+ INSERT_PROC_ADDRESS(gl, MapBufferOES);
+ INSERT_PROC_ADDRESS(gl, UnmapBufferOES);
+ INSERT_PROC_ADDRESS(gl, GetBufferPointervOES);
+
+ // GL_EXT_map_buffer_range
+ INSERT_PROC_ADDRESS(gl, MapBufferRangeEXT);
+ INSERT_PROC_ADDRESS(gl, FlushMappedBufferRangeEXT);
+
+ // GL_EXT_debug_marker
+ INSERT_PROC_ADDRESS(gl, InsertEventMarkerEXT);
+ INSERT_PROC_ADDRESS(gl, PushGroupMarkerEXT);
+ INSERT_PROC_ADDRESS(gl, PopGroupMarkerEXT);
+
+ // GL_OES_EGL_image
+ INSERT_PROC_ADDRESS(gl, EGLImageTargetTexture2DOES);
+ INSERT_PROC_ADDRESS(gl, EGLImageTargetRenderbufferStorageOES);
+
+ // GL_OES_vertex_array_object
+ INSERT_PROC_ADDRESS(gl, BindVertexArrayOES);
+ INSERT_PROC_ADDRESS(gl, DeleteVertexArraysOES);
+ INSERT_PROC_ADDRESS(gl, GenVertexArraysOES);
+ INSERT_PROC_ADDRESS(gl, IsVertexArrayOES);
+
+ // GL_KHR_debug
+ INSERT_PROC_ADDRESS(gl, DebugMessageControlKHR);
+ INSERT_PROC_ADDRESS(gl, DebugMessageInsertKHR);
+ INSERT_PROC_ADDRESS(gl, DebugMessageCallbackKHR);
+ INSERT_PROC_ADDRESS(gl, GetDebugMessageLogKHR);
+ INSERT_PROC_ADDRESS(gl, PushDebugGroupKHR);
+ INSERT_PROC_ADDRESS(gl, PopDebugGroupKHR);
+ INSERT_PROC_ADDRESS(gl, ObjectLabelKHR);
+ INSERT_PROC_ADDRESS(gl, GetObjectLabelKHR);
+ INSERT_PROC_ADDRESS(gl, ObjectPtrLabelKHR);
+ INSERT_PROC_ADDRESS(gl, GetObjectPtrLabelKHR);
+ INSERT_PROC_ADDRESS(gl, GetPointervKHR);
+
+ // GL_CHROMIUM_bind_uniform_location
+ INSERT_PROC_ADDRESS(gl, BindUniformLocationCHROMIUM);
+
+ // GL_CHROMIUM_copy_texture
+ INSERT_PROC_ADDRESS(gl, CopyTextureCHROMIUM);
+ INSERT_PROC_ADDRESS(gl, CopySubTextureCHROMIUM);
+
+ // GL_CHROMIUM_copy_compressed_texture
+ INSERT_PROC_ADDRESS(gl, CompressedCopyTextureCHROMIUM);
+
+ // GL_ANGLE_webgl_compatibility
+ INSERT_PROC_ADDRESS(gl, EnableExtensionANGLE);
+
+ // GL_ANGLE_robust_client_memory
+ INSERT_PROC_ADDRESS(gl, GetBooleanvRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetBufferParameterivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetFloatvRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetFramebufferAttachmentParameterivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetIntegervRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetProgramivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetRenderbufferParameterivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetShaderivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetTexParameterfvRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetTexParameterivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetUniformfvRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetUniformivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetVertexAttribfvRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetVertexAttribivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetVertexAttribPointervRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, ReadPixelsRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, TexImage2DRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, TexParameterfvRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, TexParameterivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, TexSubImage2DRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, TexImage3DRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, TexSubImage3DRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetQueryivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetQueryObjectuivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetBufferPointervRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetIntegeri_vRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetInternalformativRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetVertexAttribIivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetVertexAttribIuivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetUniformuivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetInteger64vRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetInteger64i_vRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetBufferParameteri64vRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, SamplerParameterivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, SamplerParameterfvRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetSamplerParameterivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetSamplerParameterfvRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetFramebufferParameterivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetProgramInterfaceivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetBooleani_vRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetMultisamplefvRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetTexLevelParameterivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetTexLevelParameterfvRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetPointervRobustANGLERobustANGLE);
+ INSERT_PROC_ADDRESS(gl, ReadnPixelsRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetnUniformfvRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetnUniformivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetnUniformuivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, TexParameterIivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, TexParameterIuivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetTexParameterIivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetTexParameterIuivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, SamplerParameterIivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, SamplerParameterIuivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetSamplerParameterIivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetSamplerParameterIuivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetQueryObjectivRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetQueryObjecti64vRobustANGLE);
+ INSERT_PROC_ADDRESS(gl, GetQueryObjectui64vRobustANGLE);
+
+ // GLES3 core
+ INSERT_PROC_ADDRESS(gl, ReadBuffer);
+ INSERT_PROC_ADDRESS(gl, DrawRangeElements);
+ INSERT_PROC_ADDRESS(gl, TexImage3D);
+ INSERT_PROC_ADDRESS(gl, TexSubImage3D);
+ INSERT_PROC_ADDRESS(gl, CopyTexSubImage3D);
+ INSERT_PROC_ADDRESS(gl, CompressedTexImage3D);
+ INSERT_PROC_ADDRESS(gl, CompressedTexSubImage3D);
+ INSERT_PROC_ADDRESS(gl, GenQueries);
+ INSERT_PROC_ADDRESS(gl, DeleteQueries);
+ INSERT_PROC_ADDRESS(gl, IsQuery);
+ INSERT_PROC_ADDRESS(gl, BeginQuery);
+ INSERT_PROC_ADDRESS(gl, EndQuery);
+ INSERT_PROC_ADDRESS(gl, GetQueryiv);
+ INSERT_PROC_ADDRESS(gl, GetQueryObjectuiv);
+ INSERT_PROC_ADDRESS(gl, UnmapBuffer);
+ INSERT_PROC_ADDRESS(gl, GetBufferPointerv);
+ INSERT_PROC_ADDRESS(gl, DrawBuffers);
+ INSERT_PROC_ADDRESS(gl, UniformMatrix2x3fv);
+ INSERT_PROC_ADDRESS(gl, UniformMatrix3x2fv);
+ INSERT_PROC_ADDRESS(gl, UniformMatrix2x4fv);
+ INSERT_PROC_ADDRESS(gl, UniformMatrix4x2fv);
+ INSERT_PROC_ADDRESS(gl, UniformMatrix3x4fv);
+ INSERT_PROC_ADDRESS(gl, UniformMatrix4x3fv);
+ INSERT_PROC_ADDRESS(gl, BlitFramebuffer);
+ INSERT_PROC_ADDRESS(gl, RenderbufferStorageMultisample);
+ INSERT_PROC_ADDRESS(gl, FramebufferTextureLayer);
+ INSERT_PROC_ADDRESS(gl, MapBufferRange);
+ INSERT_PROC_ADDRESS(gl, FlushMappedBufferRange);
+ INSERT_PROC_ADDRESS(gl, BindVertexArray);
+ INSERT_PROC_ADDRESS(gl, DeleteVertexArrays);
+ INSERT_PROC_ADDRESS(gl, GenVertexArrays);
+ INSERT_PROC_ADDRESS(gl, IsVertexArray);
+ INSERT_PROC_ADDRESS(gl, GetIntegeri_v);
+ INSERT_PROC_ADDRESS(gl, BeginTransformFeedback);
+ INSERT_PROC_ADDRESS(gl, EndTransformFeedback);
+ INSERT_PROC_ADDRESS(gl, BindBufferRange);
+ INSERT_PROC_ADDRESS(gl, BindBufferBase);
+ INSERT_PROC_ADDRESS(gl, TransformFeedbackVaryings);
+ INSERT_PROC_ADDRESS(gl, GetTransformFeedbackVarying);
+ INSERT_PROC_ADDRESS(gl, VertexAttribIPointer);
+ INSERT_PROC_ADDRESS(gl, GetVertexAttribIiv);
+ INSERT_PROC_ADDRESS(gl, GetVertexAttribIuiv);
+ INSERT_PROC_ADDRESS(gl, VertexAttribI4i);
+ INSERT_PROC_ADDRESS(gl, VertexAttribI4ui);
+ INSERT_PROC_ADDRESS(gl, VertexAttribI4iv);
+ INSERT_PROC_ADDRESS(gl, VertexAttribI4uiv);
+ INSERT_PROC_ADDRESS(gl, GetUniformuiv);
+ INSERT_PROC_ADDRESS(gl, GetFragDataLocation);
+ INSERT_PROC_ADDRESS(gl, Uniform1ui);
+ INSERT_PROC_ADDRESS(gl, Uniform2ui);
+ INSERT_PROC_ADDRESS(gl, Uniform3ui);
+ INSERT_PROC_ADDRESS(gl, Uniform4ui);
+ INSERT_PROC_ADDRESS(gl, Uniform1uiv);
+ INSERT_PROC_ADDRESS(gl, Uniform2uiv);
+ INSERT_PROC_ADDRESS(gl, Uniform3uiv);
+ INSERT_PROC_ADDRESS(gl, Uniform4uiv);
+ INSERT_PROC_ADDRESS(gl, ClearBufferiv);
+ INSERT_PROC_ADDRESS(gl, ClearBufferuiv);
+ INSERT_PROC_ADDRESS(gl, ClearBufferfv);
+ INSERT_PROC_ADDRESS(gl, ClearBufferfi);
+ INSERT_PROC_ADDRESS(gl, GetStringi);
+ INSERT_PROC_ADDRESS(gl, CopyBufferSubData);
+ INSERT_PROC_ADDRESS(gl, GetUniformIndices);
+ INSERT_PROC_ADDRESS(gl, GetActiveUniformsiv);
+ INSERT_PROC_ADDRESS(gl, GetUniformBlockIndex);
+ INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockiv);
+ INSERT_PROC_ADDRESS(gl, GetActiveUniformBlockName);
+ INSERT_PROC_ADDRESS(gl, UniformBlockBinding);
+ INSERT_PROC_ADDRESS(gl, DrawArraysInstanced);
+ INSERT_PROC_ADDRESS(gl, DrawElementsInstanced);
+ // FenceSync is the name of a class, the function has an added _ to prevent a name conflict.
+ INSERT_PROC_ADDRESS_NO_NS("glFenceSync", gl::FenceSync_);
+ INSERT_PROC_ADDRESS(gl, IsSync);
+ INSERT_PROC_ADDRESS(gl, DeleteSync);
+ INSERT_PROC_ADDRESS(gl, ClientWaitSync);
+ INSERT_PROC_ADDRESS(gl, WaitSync);
+ INSERT_PROC_ADDRESS(gl, GetInteger64v);
+ INSERT_PROC_ADDRESS(gl, GetSynciv);
+ INSERT_PROC_ADDRESS(gl, GetInteger64i_v);
+ INSERT_PROC_ADDRESS(gl, GetBufferParameteri64v);
+ INSERT_PROC_ADDRESS(gl, GenSamplers);
+ INSERT_PROC_ADDRESS(gl, DeleteSamplers);
+ INSERT_PROC_ADDRESS(gl, IsSampler);
+ INSERT_PROC_ADDRESS(gl, BindSampler);
+ INSERT_PROC_ADDRESS(gl, SamplerParameteri);
+ INSERT_PROC_ADDRESS(gl, SamplerParameteriv);
+ INSERT_PROC_ADDRESS(gl, SamplerParameterf);
+ INSERT_PROC_ADDRESS(gl, SamplerParameterfv);
+ INSERT_PROC_ADDRESS(gl, GetSamplerParameteriv);
+ INSERT_PROC_ADDRESS(gl, GetSamplerParameterfv);
+ INSERT_PROC_ADDRESS(gl, VertexAttribDivisor);
+ INSERT_PROC_ADDRESS(gl, BindTransformFeedback);
+ INSERT_PROC_ADDRESS(gl, DeleteTransformFeedbacks);
+ INSERT_PROC_ADDRESS(gl, GenTransformFeedbacks);
+ INSERT_PROC_ADDRESS(gl, IsTransformFeedback);
+ INSERT_PROC_ADDRESS(gl, PauseTransformFeedback);
+ INSERT_PROC_ADDRESS(gl, ResumeTransformFeedback);
+ INSERT_PROC_ADDRESS(gl, GetProgramBinary);
+ INSERT_PROC_ADDRESS(gl, ProgramBinary);
+ INSERT_PROC_ADDRESS(gl, ProgramParameteri);
+ INSERT_PROC_ADDRESS(gl, InvalidateFramebuffer);
+ INSERT_PROC_ADDRESS(gl, InvalidateSubFramebuffer);
+ INSERT_PROC_ADDRESS(gl, TexStorage2D);
+ INSERT_PROC_ADDRESS(gl, TexStorage3D);
+ INSERT_PROC_ADDRESS(gl, GetInternalformativ);
+
+ // GLES31 core
+ INSERT_PROC_ADDRESS(gl, DispatchCompute);
+ INSERT_PROC_ADDRESS(gl, DispatchComputeIndirect);
+ INSERT_PROC_ADDRESS(gl, DrawArraysIndirect);
+ INSERT_PROC_ADDRESS(gl, DrawElementsIndirect);
+ INSERT_PROC_ADDRESS(gl, FramebufferParameteri);
+ INSERT_PROC_ADDRESS(gl, GetFramebufferParameteriv);
+ INSERT_PROC_ADDRESS(gl, GetProgramInterfaceiv);
+ INSERT_PROC_ADDRESS(gl, GetProgramResourceIndex);
+ INSERT_PROC_ADDRESS(gl, GetProgramResourceName);
+ INSERT_PROC_ADDRESS(gl, GetProgramResourceiv);
+ INSERT_PROC_ADDRESS(gl, GetProgramResourceLocation);
+ INSERT_PROC_ADDRESS(gl, UseProgramStages);
+ INSERT_PROC_ADDRESS(gl, ActiveShaderProgram);
+ INSERT_PROC_ADDRESS(gl, CreateShaderProgramv);
+ INSERT_PROC_ADDRESS(gl, BindProgramPipeline);
+ INSERT_PROC_ADDRESS(gl, DeleteProgramPipelines);
+ INSERT_PROC_ADDRESS(gl, GenProgramPipelines);
+ INSERT_PROC_ADDRESS(gl, IsProgramPipeline);
+ INSERT_PROC_ADDRESS(gl, GetProgramPipelineiv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform1i);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform2i);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform3i);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform4i);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform1ui);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform2ui);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform3ui);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform4ui);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform1f);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform2f);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform3f);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform4f);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform1iv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform2iv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform3iv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform4iv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform1uiv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform2uiv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform3uiv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform4uiv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform1fv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform2fv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform3fv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniform4fv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix2fv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix3fv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix4fv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix2x3fv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix3x2fv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix2x4fv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix4x2fv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix3x4fv);
+ INSERT_PROC_ADDRESS(gl, ProgramUniformMatrix4x3fv);
+ INSERT_PROC_ADDRESS(gl, ValidateProgramPipeline);
+ INSERT_PROC_ADDRESS(gl, GetProgramPipelineInfoLog);
+ INSERT_PROC_ADDRESS(gl, BindImageTexture);
+ INSERT_PROC_ADDRESS(gl, GetBooleani_v);
+ INSERT_PROC_ADDRESS(gl, MemoryBarrier);
+ INSERT_PROC_ADDRESS(gl, MemoryBarrierByRegion);
+ INSERT_PROC_ADDRESS(gl, TexStorage2DMultisample);
+ INSERT_PROC_ADDRESS(gl, GetMultisamplefv);
+ INSERT_PROC_ADDRESS(gl, SampleMaski);
+ INSERT_PROC_ADDRESS(gl, GetTexLevelParameteriv);
+ INSERT_PROC_ADDRESS(gl, GetTexLevelParameterfv);
+ INSERT_PROC_ADDRESS(gl, BindVertexBuffer);
+ INSERT_PROC_ADDRESS(gl, VertexAttribFormat);
+ INSERT_PROC_ADDRESS(gl, VertexAttribIFormat);
+ INSERT_PROC_ADDRESS(gl, VertexAttribBinding);
+ INSERT_PROC_ADDRESS(gl, VertexBindingDivisor);
+
+ // EGL 1.0
+ INSERT_PROC_ADDRESS(egl, ChooseConfig);
+ INSERT_PROC_ADDRESS(egl, CopyBuffers);
+ INSERT_PROC_ADDRESS(egl, CreateContext);
+ INSERT_PROC_ADDRESS(egl, CreatePbufferSurface);
+ INSERT_PROC_ADDRESS(egl, CreatePixmapSurface);
+ INSERT_PROC_ADDRESS(egl, CreateWindowSurface);
+ INSERT_PROC_ADDRESS(egl, DestroyContext);
+ INSERT_PROC_ADDRESS(egl, DestroySurface);
+ INSERT_PROC_ADDRESS(egl, GetConfigAttrib);
+ INSERT_PROC_ADDRESS(egl, GetConfigs);
+ INSERT_PROC_ADDRESS(egl, GetCurrentDisplay);
+ INSERT_PROC_ADDRESS(egl, GetCurrentSurface);
+ INSERT_PROC_ADDRESS(egl, GetDisplay);
+ INSERT_PROC_ADDRESS(egl, GetError);
+ INSERT_PROC_ADDRESS(egl, GetProcAddress);
+ INSERT_PROC_ADDRESS(egl, Initialize);
+ INSERT_PROC_ADDRESS(egl, MakeCurrent);
+ INSERT_PROC_ADDRESS(egl, QueryContext);
+ INSERT_PROC_ADDRESS(egl, QueryString);
+ INSERT_PROC_ADDRESS(egl, QuerySurface);
+ INSERT_PROC_ADDRESS(egl, SwapBuffers);
+ INSERT_PROC_ADDRESS(egl, Terminate);
+ INSERT_PROC_ADDRESS(egl, WaitGL);
+ INSERT_PROC_ADDRESS(egl, WaitNative);
+
+ // EGL 1.1
+ INSERT_PROC_ADDRESS(egl, BindTexImage);
+ INSERT_PROC_ADDRESS(egl, ReleaseTexImage);
+ INSERT_PROC_ADDRESS(egl, SurfaceAttrib);
+ INSERT_PROC_ADDRESS(egl, SwapInterval);
+
+ // EGL 1.2
+ INSERT_PROC_ADDRESS(egl, BindAPI);
+ INSERT_PROC_ADDRESS(egl, QueryAPI);
+ INSERT_PROC_ADDRESS(egl, CreatePbufferFromClientBuffer);
+ INSERT_PROC_ADDRESS(egl, ReleaseThread);
+ INSERT_PROC_ADDRESS(egl, WaitClient);
+
+ // EGL 1.4
+ INSERT_PROC_ADDRESS(egl, GetCurrentContext);
+
+ // EGL 1.5
+ INSERT_PROC_ADDRESS(egl, CreateSync);
+ INSERT_PROC_ADDRESS(egl, DestroySync);
+ INSERT_PROC_ADDRESS(egl, ClientWaitSync);
+ INSERT_PROC_ADDRESS(egl, GetSyncAttrib);
+ INSERT_PROC_ADDRESS(egl, CreateImage);
+ INSERT_PROC_ADDRESS(egl, DestroyImage);
+ INSERT_PROC_ADDRESS(egl, GetPlatformDisplay);
+ INSERT_PROC_ADDRESS(egl, CreatePlatformWindowSurface);
+ INSERT_PROC_ADDRESS(egl, CreatePlatformPixmapSurface);
+ INSERT_PROC_ADDRESS(egl, WaitSync);
+
+ // EGL_ANGLE_query_surface_pointer
+ INSERT_PROC_ADDRESS(egl, QuerySurfacePointerANGLE);
+
+ // EGL_NV_post_sub_buffer
+ INSERT_PROC_ADDRESS(egl, PostSubBufferNV);
+
+ // EGL_EXT_platform_base
+ INSERT_PROC_ADDRESS(egl, GetPlatformDisplayEXT);
+
+ // EGL_EXT_device_query
+ INSERT_PROC_ADDRESS(egl, QueryDisplayAttribEXT);
+ INSERT_PROC_ADDRESS(egl, QueryDeviceAttribEXT);
+ INSERT_PROC_ADDRESS(egl, QueryDeviceStringEXT);
+
+ // EGL_KHR_image_base/EGL_KHR_image
+ INSERT_PROC_ADDRESS(egl, CreateImageKHR);
+ INSERT_PROC_ADDRESS(egl, DestroyImageKHR);
+
+ // EGL_EXT_device_creation
+ INSERT_PROC_ADDRESS(egl, CreateDeviceANGLE);
+ INSERT_PROC_ADDRESS(egl, ReleaseDeviceANGLE);
+
+ // EGL_KHR_stream
+ INSERT_PROC_ADDRESS(egl, CreateStreamKHR);
+ INSERT_PROC_ADDRESS(egl, DestroyStreamKHR);
+ INSERT_PROC_ADDRESS(egl, StreamAttribKHR);
+ INSERT_PROC_ADDRESS(egl, QueryStreamKHR);
+ INSERT_PROC_ADDRESS(egl, QueryStreamu64KHR);
+
+ // EGL_KHR_stream_consumer_gltexture
+ INSERT_PROC_ADDRESS(egl, StreamConsumerGLTextureExternalKHR);
+ INSERT_PROC_ADDRESS(egl, StreamConsumerAcquireKHR);
+ INSERT_PROC_ADDRESS(egl, StreamConsumerReleaseKHR);
+
+ // EGL_NV_stream_consumer_gltexture_yuv
+ INSERT_PROC_ADDRESS(egl, StreamConsumerGLTextureExternalAttribsNV);
+
+ // EGL_ANGLE_stream_producer_d3d_texture_nv12
+ INSERT_PROC_ADDRESS(egl, CreateStreamProducerD3DTextureNV12ANGLE);
+ INSERT_PROC_ADDRESS(egl, StreamPostD3DTextureNV12ANGLE);
+
+ // EGL_EXT_swap_buffers_with_damage
+ INSERT_PROC_ADDRESS(egl, SwapBuffersWithDamageEXT);
+
+ // angle::Platform related entry points
+ INSERT_PROC_ADDRESS_NO_NS("ANGLEPlatformInitialize", ANGLEPlatformInitialize);
+ INSERT_PROC_ADDRESS_NO_NS("ANGLEPlatformShutdown", ANGLEPlatformShutdown);
+
+#undef INSERT_PROC_ADDRESS
+#undef INSERT_PROC_ADDRESS_NO_NS
+
+ return map;
+ };
+
+ static const ProcAddressMap procAddressMap = generateProcAddressMap();
+
+ thread->setError(Error(EGL_SUCCESS));
+ auto iter = procAddressMap.find(procname);
+ return iter != procAddressMap.end() ? iter->second : nullptr;
+}
+
+}