diff options
Diffstat (limited to 'src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp')
-rw-r--r-- | src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp | 1516 |
1 files changed, 520 insertions, 996 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp b/src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp index 6f9770c57c..97546ee900 100644 --- a/src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp +++ b/src/3rdparty/angle/src/libGLESv2/entry_points_egl.cpp @@ -7,33 +7,59 @@ // 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/global_state.h" +#include "common/debug.h" +#include "common/version.h" #include "libANGLE/Context.h" #include "libANGLE/Display.h" -#include "libANGLE/Texture.h" #include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/Thread.h" +#include "libANGLE/queryutils.h" #include "libANGLE/validationEGL.h" - -#include "common/debug.h" -#include "common/version.h" +#include "libGLESv2/global_state.h" +#include "libGLESv2/proc_table.h" #include <EGL/eglext.h> namespace egl { +namespace +{ + +bool CompareProc(const ProcEntry &a, const char *b) +{ + return strcmp(a.first, b) < 0; +} + +void ClipConfigs(const std::vector<const Config *> &filteredConfigs, + EGLConfig *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 + // EGL 1.0 EGLint EGLAPIENTRY GetError(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); - EGLint error = GetGlobalError(); - SetGlobalError(Error(EGL_SUCCESS)); + EGLint error = thread->getError(); + thread->setError(NoError()); return error; } @@ -41,445 +67,367 @@ EGLDisplay EGLAPIENTRY GetDisplay(EGLNativeDisplayType display_id) { EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id); - return Display::GetDisplayFromAttribs(reinterpret_cast<void *>(display_id), AttributeMap()); + return Display::GetDisplayFromNativeDisplay(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); + 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)) { - SetGlobalError(Error(EGL_BAD_DISPLAY)); + thread->setError(EglBadDisplay()); return EGL_FALSE; } Error error = display->initialize(); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (major) *major = 1; - if (minor) *minor = 4; + if (major) + *major = 1; + if (minor) + *minor = 4; - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); 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)) { - SetGlobalError(Error(EGL_BAD_DISPLAY)); + thread->setError(EglBadDisplay()); return EGL_FALSE; } - gl::Context *context = GetGlobalContext(); - - if (display->isValidContext(context)) + if (display->isValidContext(thread->getContext())) { - SetGlobalContext(NULL); - SetGlobalDisplay(NULL); + thread->setCurrent(nullptr); } - display->terminate(); + Error error = display->terminate(); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); 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); + Display *display = static_cast<Display *>(dpy); if (!(display == EGL_NO_DISPLAY && name == EGL_EXTENSIONS)) { Error error = ValidateDisplay(display); if (error.isError()) { - SetGlobalError(error); - return NULL; + thread->setError(error); + return nullptr; } } 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: - SetGlobalError(Error(EGL_BAD_PARAMETER)); - return NULL; - } - - SetGlobalError(Error(EGL_SUCCESS)); + 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(EglBadParameter()); + return nullptr; + } + + thread->setError(NoError()); return result; } -EGLBoolean EGLAPIENTRY GetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) +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); + 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); + Display *display = static_cast<Display *>(dpy); - Error error = ValidateDisplay(display); + Error error = ValidateGetConfigs(display, config_size, num_config); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (!num_config) - { - SetGlobalError(Error(EGL_BAD_PARAMETER)); - return EGL_FALSE; - } + ClipConfigs(display->getConfigs(AttributeMap()), configs, config_size, num_config); - 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()); - - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } -EGLBoolean EGLAPIENTRY ChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) +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); + 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); + Display *display = static_cast<Display *>(dpy); + AttributeMap attribMap = AttributeMap::CreateFromIntArray(attrib_list); - Error error = ValidateDisplay(display); + Error error = ValidateChooseConfig(display, attribMap, config_size, num_config); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (!num_config) - { - SetGlobalError(Error(EGL_BAD_PARAMETER)); - return EGL_FALSE; - } - - std::vector<const Config*> filteredConfigs = display->getConfigs(AttributeMap(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()); + ClipConfigs(display->getConfigs(attribMap), configs, config_size, num_config); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } -EGLBoolean EGLAPIENTRY GetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) +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); + 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); + Display *display = static_cast<Display *>(dpy); + Config *configuration = static_cast<Config *>(config); - Error error = ValidateConfig(display, configuration); + Error error = ValidateGetConfigAttrib(display, configuration, attribute); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (!display->getConfigAttrib(configuration, attribute, value)) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; - } + QueryConfigAttrib(configuration, attribute, value); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } -EGLSurface EGLAPIENTRY CreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) +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); + 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(attrib_list); + 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()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } egl::Surface *surface = nullptr; - error = display->createWindowSurface(configuration, win, attributes, &surface); + error = display->createWindowSurface(configuration, win, attributes, &surface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } return static_cast<EGLSurface>(surface); } -EGLSurface EGLAPIENTRY CreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) +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); + 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(attrib_list); + 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()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } egl::Surface *surface = nullptr; - error = display->createPbufferSurface(configuration, attributes, &surface); + error = display->createPbufferSurface(configuration, attributes, &surface); if (error.isError()) { - SetGlobalError(error); + 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) +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); + 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); + Display *display = static_cast<Display *>(dpy); + Config *configuration = static_cast<Config *>(config); Error error = ValidateConfig(display, configuration); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } - UNIMPLEMENTED(); // FIXME + UNIMPLEMENTED(); // FIXME - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); 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); + Display *display = static_cast<Display *>(dpy); + Surface *eglSurface = static_cast<Surface *>(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } if (surface == EGL_NO_SURFACE) { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(EglBadSurface()); return EGL_FALSE; } - display->destroySurface((Surface*)surface); + error = display->destroySurface(reinterpret_cast<Surface *>(surface)); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } -EGLBoolean EGLAPIENTRY QuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) +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); + 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; + const Display *display = static_cast<const Display *>(dpy); + const Surface *eglSurface = static_cast<const Surface *>(surface); - Error error = ValidateSurface(display, eglSurface); + Error error = ValidateQuerySurface(display, eglSurface, attribute, value); if (error.isError()) { - SetGlobalError(error); - return EGL_FALSE; - } - - if (surface == EGL_NO_SURFACE) - { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(error); 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) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; - } - *value = eglSurface->isPostSubBufferSupported(); - break; - case EGL_FIXED_SIZE_ANGLE: - if (!display->getExtensions().windowFixedSize) - { - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; - } - *value = eglSurface->isFixedSize(); - break; - case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE: - if (!display->getExtensions().flexibleSurfaceCompatibility) - { - SetGlobalError( - 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) - { - SetGlobalError(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) - { - SetGlobalError(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: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; - } + QuerySurfaceAttrib(eglSurface, attribute, value); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } -EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) +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); - - Display *display = static_cast<Display*>(dpy); - Config *configuration = static_cast<Config*>(config); - gl::Context* sharedGLContext = static_cast<gl::Context*>(share_context); - AttributeMap attributes(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()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_CONTEXT; } @@ -487,208 +435,115 @@ EGLContext EGLAPIENTRY CreateContext(EGLDisplay dpy, EGLConfig config, EGLContex error = display->createContext(configuration, sharedGLContext, attributes, &context); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_CONTEXT; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); 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); + Display *display = static_cast<Display *>(dpy); + gl::Context *context = static_cast<gl::Context *>(ctx); Error error = ValidateContext(display, context); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } if (ctx == EGL_NO_CONTEXT) { - SetGlobalError(Error(EGL_BAD_CONTEXT)); + thread->setError(EglBadContext()); return EGL_FALSE; } - if (context == GetGlobalContext()) + if (context == thread->getContext()) { - SetGlobalDisplay(NULL); - SetGlobalContext(NULL); + thread->setCurrent(nullptr); } - display->destroyContext(context); + error = display->destroyContext(context); + if (error.isError()) + { + thread->setError(error); + return EGL_FALSE; + } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); 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); - - 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)) - { - SetGlobalError(Error(EGL_BAD_MATCH)); - return EGL_FALSE; - } - - if (ctx != EGL_NO_CONTEXT && draw == EGL_NO_SURFACE && read == EGL_NO_SURFACE) - { - SetGlobalError(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)) - { - SetGlobalError(Error( - EGL_BAD_MATCH, "read and draw must both be valid surfaces, or both be EGL_NO_SURFACE")); - return EGL_FALSE; - } + 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(); - if (dpy == EGL_NO_DISPLAY || !Display::isValidDisplay(display)) - { - SetGlobalError(Error(EGL_BAD_DISPLAY, "'dpy' not a valid EGLDisplay handle")); - return EGL_FALSE; - } + Display *display = static_cast<Display *>(dpy); + gl::Context *context = static_cast<gl::Context *>(ctx); - // 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)) + Error error = ValidateMakeCurrent(display, draw, read, context); + if (error.isError()) { - SetGlobalError(Error(EGL_NOT_INITIALIZED, "'dpy' not initialized")); + thread->setError(error); return EGL_FALSE; } - if (ctx != EGL_NO_CONTEXT) - { - Error error = ValidateContext(display, context); - if (error.isError()) - { - SetGlobalError(error); - return EGL_FALSE; - } - } - - if (display->isInitialized()) - { - if (display->testDeviceLost()) - { - display->notifyDeviceLost(); - return EGL_FALSE; - } - - if (display->isDeviceLost()) - { - SetGlobalError(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()) - { - SetGlobalError(error); - return EGL_FALSE; - } - } - - Surface *readSurface = static_cast<Surface*>(read); - if (read != EGL_NO_SURFACE) - { - Error error = ValidateSurface(display, readSurface); - if (error.isError()) - { - SetGlobalError(error); - return EGL_FALSE; - } - } - - if (readSurface) - { - Error readCompatError = - ValidateCompatibleConfigs(display, readSurface->getConfig(), readSurface, - context->getConfig(), readSurface->getType()); - if (readCompatError.isError()) - { - SetGlobalError(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()) - { - SetGlobalError(drawCompatError); - return EGL_FALSE; - } - } - } - + Surface *readSurface = static_cast<Surface *>(read); + Surface *drawSurface = static_cast<Surface *>(draw); Error makeCurrentError = display->makeCurrent(drawSurface, readSurface, context); if (makeCurrentError.isError()) { - SetGlobalError(makeCurrentError); + thread->setError(makeCurrentError); return EGL_FALSE; } - gl::Context *previousContext = GetGlobalContext(); - - SetGlobalDisplay(display); - SetGlobalDrawSurface(drawSurface); - SetGlobalReadSurface(readSurface); - SetGlobalContext(context); + gl::Context *previousContext = thread->getContext(); + thread->setCurrent(context); // Release the surface from the previously-current context, to allow // destroyed surfaces to delete themselves. if (previousContext != nullptr && context != previousContext) { - previousContext->releaseSurface(); + auto err = previousContext->releaseSurface(display); + if (err.isError()) + { + thread->setError(err); + return EGL_FALSE; + } } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw) { EVENT("(EGLint readdraw = %d)", readdraw); + Thread *thread = GetCurrentThread(); if (readdraw == EGL_READ) { - SetGlobalError(Error(EGL_SUCCESS)); - return GetGlobalReadSurface(); + thread->setError(NoError()); + return thread->getCurrentReadSurface(); } else if (readdraw == EGL_DRAW) { - SetGlobalError(Error(EGL_SUCCESS)); - return GetGlobalDrawSurface(); + thread->setError(NoError()); + return thread->getCurrentDrawSurface(); } else { - SetGlobalError(Error(EGL_BAD_PARAMETER)); + thread->setError(EglBadParameter()); return EGL_NO_SURFACE; } } @@ -696,283 +551,294 @@ EGLSurface EGLAPIENTRY GetCurrentSurface(EGLint readdraw) EGLDisplay EGLAPIENTRY GetCurrentDisplay(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); - EGLDisplay dpy = GetGlobalDisplay(); - - SetGlobalError(Error(EGL_SUCCESS)); - return dpy; + thread->setError(NoError()); + if (thread->getContext() != nullptr) + { + return thread->getContext()->getCurrentDisplay(); + } + return EGL_NO_DISPLAY; } 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); + 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); + Display *display = static_cast<Display *>(dpy); + gl::Context *context = static_cast<gl::Context *>(ctx); - Error error = ValidateContext(display, context); + Error error = ValidateQueryContext(display, context, attribute, value); if (error.isError()) { - SetGlobalError(error); + 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->getClientVersion(); - break; - case EGL_RENDER_BUFFER: - *value = context->getRenderBuffer(); - break; - default: - SetGlobalError(Error(EGL_BAD_ATTRIBUTE)); - return EGL_FALSE; - } + QueryContextAttrib(context, attribute, value); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLBoolean EGLAPIENTRY WaitGL(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); - Display *display = GetGlobalDisplay(); + Display *display = thread->getCurrentDisplay(); Error error = ValidateDisplay(display); if (error.isError()) { - SetGlobalError(error); + 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(); + error = display->waitClient(thread->getContext()); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLBoolean EGLAPIENTRY WaitNative(EGLint engine) { EVENT("(EGLint engine = %d)", engine); + Thread *thread = GetCurrentThread(); - Display *display = GetGlobalDisplay(); + Display *display = thread->getCurrentDisplay(); Error error = ValidateDisplay(display); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } if (engine != EGL_CORE_NATIVE_ENGINE) { - SetGlobalError( - Error(EGL_BAD_PARAMETER, "the 'engine' parameter has an unrecognized value")); + thread->setError(EglBadParameter() << "the 'engine' parameter has an unrecognized value"); } - error = display->waitNative(engine, GetGlobalDrawSurface(), GetGlobalReadSurface()); + error = display->waitNative(thread->getContext(), engine); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); 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; + Display *display = static_cast<Display *>(dpy); + Surface *eglSurface = (Surface *)surface; Error error = ValidateSurface(display, eglSurface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (display->isDeviceLost()) + if (display->testDeviceLost()) { - SetGlobalError(Error(EGL_CONTEXT_LOST)); + thread->setError(EglContextLost()); return EGL_FALSE; } if (surface == EGL_NO_SURFACE) { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(EglBadSurface()); return EGL_FALSE; } - error = eglSurface->swap(); + if (!thread->getContext() || thread->getCurrentDrawSurface() != eglSurface) + { + thread->setError(EglBadSurface()); + return EGL_FALSE; + } + + error = eglSurface->swap(thread->getContext()); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); 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); + 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); + Display *display = static_cast<Display *>(dpy); + Surface *eglSurface = static_cast<Surface *>(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - if (display->isDeviceLost()) + if (display->testDeviceLost()) { - SetGlobalError(Error(EGL_CONTEXT_LOST)); + thread->setError(EglContextLost()); return EGL_FALSE; } - UNIMPLEMENTED(); // FIXME + UNIMPLEMENTED(); // FIXME - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); 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); + 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); + Display *display = static_cast<Display *>(dpy); + Surface *eglSurface = static_cast<Surface *>(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } if (buffer != EGL_BACK_BUFFER) { - SetGlobalError(Error(EGL_BAD_PARAMETER)); + thread->setError(EglBadParameter()); return EGL_FALSE; } if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT) { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(EglBadSurface()); return EGL_FALSE; } if (eglSurface->getBoundTexture()) { - SetGlobalError(Error(EGL_BAD_ACCESS)); + thread->setError(EglBadAccess()); return EGL_FALSE; } if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) { - SetGlobalError(Error(EGL_BAD_MATCH)); + thread->setError(EglBadMatch()); return EGL_FALSE; } - gl::Context *context = GetGlobalContext(); + gl::Context *context = thread->getContext(); if (context) { gl::Texture *textureObject = context->getTargetTexture(GL_TEXTURE_2D); - ASSERT(textureObject != NULL); + ASSERT(textureObject != nullptr); if (textureObject->getImmutableFormat()) { - SetGlobalError(Error(EGL_BAD_MATCH)); + thread->setError(EglBadMatch()); return EGL_FALSE; } - error = eglSurface->bindTexImage(textureObject, buffer); + error = eglSurface->bindTexImage(context, textureObject, buffer); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } -EGLBoolean EGLAPIENTRY SurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) +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)", + 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); + Display *display = static_cast<Display *>(dpy); + Surface *eglSurface = static_cast<Surface *>(surface); - Error error = ValidateSurface(display, eglSurface); + Error error = ValidateSurfaceAttrib(display, eglSurface, attribute, value); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - UNIMPLEMENTED(); // FIXME + SetSurfaceAttrib(eglSurface, attribute, value); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); 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); + 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); + Display *display = static_cast<Display *>(dpy); + Surface *eglSurface = static_cast<Surface *>(surface); Error error = ValidateSurface(display, eglSurface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } if (buffer != EGL_BACK_BUFFER) { - SetGlobalError(Error(EGL_BAD_PARAMETER)); + thread->setError(EglBadParameter()); return EGL_FALSE; } if (surface == EGL_NO_SURFACE || eglSurface->getType() == EGL_WINDOW_BIT) { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(EglBadSurface()); return EGL_FALSE; } if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) { - SetGlobalError(Error(EGL_BAD_MATCH)); + thread->setError(EglBadMatch()); return EGL_FALSE; } @@ -980,105 +846,116 @@ EGLBoolean EGLAPIENTRY ReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLin if (texture) { - error = eglSurface->releaseTexImage(buffer); + error = eglSurface->releaseTexImage(thread->getContext(), buffer); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); 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); + Display *display = static_cast<Display *>(dpy); Error error = ValidateDisplay(display); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - Surface *draw_surface = static_cast<Surface*>(GetGlobalDrawSurface()); + Surface *draw_surface = static_cast<Surface *>(thread->getCurrentDrawSurface()); - if (draw_surface == NULL) + if (draw_surface == nullptr) { - SetGlobalError(Error(EGL_BAD_SURFACE)); + thread->setError(EglBadSurface()); return EGL_FALSE; } const egl::Config *surfaceConfig = draw_surface->getConfig(); - EGLint clampedInterval = std::min(std::max(interval, surfaceConfig->minSwapInterval), surfaceConfig->maxSwapInterval); + EGLint clampedInterval = std::min(std::max(interval, surfaceConfig->minSwapInterval), + surfaceConfig->maxSwapInterval); draw_surface->setSwapInterval(clampedInterval); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); 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: - SetGlobalError(Error(EGL_BAD_PARAMETER)); - return EGL_FALSE; // Not supported by this implementation - case EGL_OPENGL_ES_API: - break; - default: - SetGlobalError(Error(EGL_BAD_PARAMETER)); - return EGL_FALSE; + case EGL_OPENGL_API: + case EGL_OPENVG_API: + thread->setError(EglBadParameter()); + return EGL_FALSE; // Not supported by this implementation + case EGL_OPENGL_ES_API: + break; + default: + thread->setError(EglBadParameter()); + return EGL_FALSE; } - SetGlobalAPI(api); + thread->setAPI(api); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLenum EGLAPIENTRY QueryAPI(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); - EGLenum API = GetGlobalAPI(); + EGLenum API = thread->getAPI(); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return API; } -EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) +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); - - Display *display = static_cast<Display*>(dpy); - Config *configuration = static_cast<Config*>(config); - AttributeMap attributes(attrib_list); - - Error error = ValidateCreatePbufferFromClientBuffer(display, buftype, buffer, configuration, attributes); + 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()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } egl::Surface *surface = nullptr; - error = display->createPbufferFromClientBuffer(configuration, buffer, attributes, &surface); + error = display->createPbufferFromClientBuffer(configuration, buftype, buffer, attributes, + &surface); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_NO_SURFACE; } @@ -1088,34 +965,36 @@ EGLSurface EGLAPIENTRY CreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buf EGLBoolean EGLAPIENTRY ReleaseThread(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); MakeCurrent(EGL_NO_DISPLAY, EGL_NO_CONTEXT, EGL_NO_SURFACE, EGL_NO_SURFACE); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } EGLBoolean EGLAPIENTRY WaitClient(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); - Display *display = GetGlobalDisplay(); + Display *display = thread->getCurrentDisplay(); Error error = ValidateDisplay(display); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - error = display->waitClient(); + error = display->waitClient(thread->getContext()); if (error.isError()) { - SetGlobalError(error); + thread->setError(error); return EGL_FALSE; } - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); return EGL_TRUE; } @@ -1123,540 +1002,185 @@ EGLBoolean EGLAPIENTRY WaitClient(void) EGLContext EGLAPIENTRY GetCurrentContext(void) { EVENT("()"); + Thread *thread = GetCurrentThread(); - gl::Context *context = GetGlobalContext(); + gl::Context *context = thread->getContext(); - SetGlobalError(Error(EGL_SUCCESS)); + thread->setError(NoError()); 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); + 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(EglBadDisplay() << "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(EglBadDisplay() << "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); + 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(EglBadDisplay() << "eglClientWaitSync unimplemented."); return 0; } -EGLBoolean EGLAPIENTRY GetSyncAttrib(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value) +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); + 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(EglBadDisplay() << "eglSyncAttrib unimplemented."); return EGL_FALSE; } -EGLImage EGLAPIENTRY CreateImage(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list) +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); + 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(EglBadDisplay() << "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(EglBadDisplay() << "eglDestroyImage unimplemented."); return EGL_FALSE; } -EGLDisplay EGLAPIENTRY GetPlatformDisplay(EGLenum platform, void *native_display, const EGLAttrib *attrib_list) +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); + 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(); - return EGL_NO_DISPLAY; + Error err = ValidateGetPlatformDisplay(platform, native_display, attrib_list); + thread->setError(err); + if (err.isError()) + { + return EGL_NO_DISPLAY; + } + + const auto &attribMap = AttributeMap::CreateFromAttribArray(attrib_list); + if (platform == EGL_PLATFORM_ANGLE_ANGLE) + { + return Display::GetDisplayFromNativeDisplay( + gl::bitCast<EGLNativeDisplayType>(native_display), attribMap); + } + else if (platform == EGL_PLATFORM_DEVICE_EXT) + { + Device *eglDevice = reinterpret_cast<Device *>(native_display); + return Display::GetDisplayFromDevice(eglDevice, attribMap); + } + else + { + UNREACHABLE(); + return EGL_NO_DISPLAY; + } } -EGLSurface EGLAPIENTRY CreatePlatformWindowSurface(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list) +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); + 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(EglBadDisplay() << "eglCreatePlatformWindowSurface unimplemented."); return EGL_NO_SURFACE; } -EGLSurface EGLAPIENTRY CreatePlatformPixmapSurface(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list) +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); + 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(EglBadDisplay() << "eglCreatePlatformPixmapSurface 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); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSync sync = 0x%0.8p, EGLint flags = 0x%X)", dpy, sync, + flags); + Thread *thread = GetCurrentThread(); UNIMPLEMENTED(); + thread->setError(EglBadDisplay() << "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) - - // 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_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); - - // 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); - map["glFenceSync"] = - reinterpret_cast<__eglMustCastToProperFunctionPointerType>(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); - - // 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); - -#undef INSERT_PROC_ADDRESS - return map; - }; - - static const ProcAddressMap procAddressMap = generateProcAddressMap(); - - auto iter = procAddressMap.find(procname); - if (iter != procAddressMap.end()) - { - return iter->second; - } - else + ProcEntry *entry = + std::lower_bound(&g_procTable[0], &g_procTable[g_numProcs], procname, CompareProc); + + thread->setError(NoError()); + + if (entry == &g_procTable[g_numProcs] || strcmp(entry->first, procname) != 0) { return nullptr; } -} + return entry->second; +} } |