diff options
Diffstat (limited to 'Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp')
-rw-r--r-- | Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp | 453 |
1 files changed, 257 insertions, 196 deletions
diff --git a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp index 8dfe6e5..4b7f9e1 100644 --- a/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp +++ b/Source/ThirdParty/ANGLE/src/libEGL/libEGL.cpp @@ -9,13 +9,15 @@ #include <exception> #include "common/debug.h" +#include "common/version.h" #include "libGLESv2/Context.h" +#include "libGLESv2/Texture.h" #include "libEGL/main.h" #include "libEGL/Display.h" -bool validate(egl::Display *display) +bool validateDisplay(egl::Display *display) { if (display == EGL_NO_DISPLAY) { @@ -30,9 +32,9 @@ bool validate(egl::Display *display) return true; } -bool validate(egl::Display *display, EGLConfig config) +bool validateConfig(egl::Display *display, EGLConfig config) { - if (!validate(display)) + if (!validateDisplay(display)) { return false; } @@ -45,9 +47,9 @@ bool validate(egl::Display *display, EGLConfig config) return true; } -bool validate(egl::Display *display, gl::Context *context) +bool validateContext(egl::Display *display, gl::Context *context) { - if (!validate(display)) + if (!validateDisplay(display)) { return false; } @@ -60,9 +62,9 @@ bool validate(egl::Display *display, gl::Context *context) return true; } -bool validate(egl::Display *display, egl::Surface *surface) +bool validateSurface(egl::Display *display, egl::Surface *surface) { - if (!validate(display)) + if (!validateDisplay(display)) { return false; } @@ -79,7 +81,7 @@ extern "C" { EGLint __stdcall eglGetError(void) { - TRACE("()"); + EVENT("()"); EGLint error = egl::getCurrentError(); @@ -93,34 +95,21 @@ EGLint __stdcall eglGetError(void) EGLDisplay __stdcall eglGetDisplay(EGLNativeDisplayType display_id) { - TRACE("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id); + EVENT("(EGLNativeDisplayType display_id = 0x%0.8p)", display_id); try { - // FIXME: Return the same EGLDisplay handle when display_id already created a display - - if (display_id == EGL_DEFAULT_DISPLAY) - { - return new egl::Display((HDC)NULL); - } - else - { - // FIXME: Check if display_id is a valid display device context - - return new egl::Display((HDC)display_id); - } + return egl::Display::getDisplay(display_id); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY); } - - return EGL_NO_DISPLAY; } EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint *major = 0x%0.8p, EGLint *minor = 0x%0.8p)", dpy, major, minor); try @@ -146,13 +135,11 @@ EGLBoolean __stdcall eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglTerminate(EGLDisplay dpy) { - TRACE("(EGLDisplay dpy = 0x%0.8p)", dpy); + EVENT("(EGLDisplay dpy = 0x%0.8p)", dpy); try { @@ -171,19 +158,17 @@ EGLBoolean __stdcall eglTerminate(EGLDisplay dpy) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint name = %d)", dpy, name); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display)) + if (!validateDisplay(display)) { return NULL; } @@ -193,11 +178,11 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name) case EGL_CLIENT_APIS: return success("OpenGL_ES"); case EGL_EXTENSIONS: - return success(""); + return display->getExtensionString(); case EGL_VENDOR: - return success("TransGaming Inc."); + return success("Google Inc."); case EGL_VERSION: - return success("1.4 (git-devel "__DATE__" " __TIME__")"); + return success("1.4 (ANGLE "VERSION_STRING")"); } return error(EGL_BAD_PARAMETER, (const char*)NULL); @@ -206,13 +191,11 @@ const char *__stdcall eglQueryString(EGLDisplay dpy, EGLint name) { return error(EGL_BAD_ALLOC, (const char*)NULL); } - - return NULL; } EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig *configs = 0x%0.8p, " + 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); @@ -220,7 +203,7 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display)) + if (!validateDisplay(display)) { return EGL_FALSE; } @@ -243,13 +226,11 @@ EGLBoolean __stdcall eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint co { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) { - TRACE("(EGLDisplay dpy = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p, " + 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); @@ -257,7 +238,7 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display)) + if (!validateDisplay(display)) { return EGL_FALSE; } @@ -282,20 +263,18 @@ EGLBoolean __stdcall eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", dpy, config, attribute, value); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_FALSE; } @@ -311,20 +290,18 @@ EGLBoolean __stdcall eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativeWindowType win = 0x%0.8p, " + 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); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_SURFACE; } @@ -336,113 +313,70 @@ EGLSurface __stdcall eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EG return error(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); } - if (attrib_list) - { - while (*attrib_list != EGL_NONE) - { - switch (attrib_list[0]) - { - case EGL_RENDER_BUFFER: - switch (attrib_list[1]) - { - case EGL_BACK_BUFFER: - break; - case EGL_SINGLE_BUFFER: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); // Rendering directly to front buffer not supported - default: - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); - } - break; - case EGL_VG_COLORSPACE: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); - case EGL_VG_ALPHA_FORMAT: - return error(EGL_BAD_MATCH, EGL_NO_SURFACE); - default: - return error(EGL_BAD_ATTRIBUTE, EGL_NO_SURFACE); - } - - attrib_list += 2; - } - } - - if (display->hasExistingWindowSurface(window)) - { - return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); - } - - EGLSurface surface = (EGLSurface)display->createWindowSurface(window, config); - - return success(surface); + return display->createWindowSurface(window, config, attrib_list); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLSurface __stdcall eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, const EGLint *attrib_list = 0x%0.8p)", dpy, config, attrib_list); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_SURFACE; } - UNIMPLEMENTED(); // FIXME - - return success(EGL_NO_DISPLAY); + return display->createOffscreenSurface(config, NULL, attrib_list); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLSurface __stdcall eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLNativePixmapType pixmap = 0x%0.8p, " + 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); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_SURFACE; } UNIMPLEMENTED(); // FIXME - return success(EGL_NO_DISPLAY); + return success(EGL_NO_SURFACE); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } @@ -460,20 +394,19 @@ EGLBoolean __stdcall eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", dpy, surface, attribute, value); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = (egl::Surface*)surface; - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } @@ -483,8 +416,6 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint return error(EGL_BAD_SURFACE, EGL_FALSE); } - egl::Surface *eglSurface = (egl::Surface*)surface; - switch (attribute) { case EGL_VG_ALPHA_FORMAT: @@ -535,6 +466,9 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint case EGL_WIDTH: *value = eglSurface->getWidth(); break; + case EGL_POST_SUB_BUFFER_SUPPORTED_NV: + *value = eglSurface->isPostSubBufferSupported(); + break; default: return error(EGL_BAD_ATTRIBUTE, EGL_FALSE); } @@ -545,13 +479,48 @@ EGLBoolean __stdcall eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint { return error(EGL_BAD_ALLOC, EGL_FALSE); } +} - return EGL_FALSE; +EGLBoolean __stdcall eglQuerySurfacePointerANGLE(EGLDisplay dpy, EGLSurface surface, EGLint attribute, void **value) +{ + TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint attribute = %d, void **value = 0x%0.8p)", + dpy, surface, attribute, value); + + try + { + egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = (egl::Surface*)surface; + + if (!validateSurface(display, eglSurface)) + { + return EGL_FALSE; + } + + if (surface == EGL_NO_SURFACE) + { + return error(EGL_BAD_SURFACE, EGL_FALSE); + } + + switch (attribute) + { + case EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE: + *value = (void*) eglSurface->getShareHandle(); + break; + default: + return error(EGL_BAD_ATTRIBUTE, EGL_FALSE); + } + + return success(EGL_TRUE); + } + catch(std::bad_alloc&) + { + return error(EGL_BAD_ALLOC, EGL_FALSE); + } } EGLBoolean __stdcall eglBindAPI(EGLenum api) { - TRACE("(EGLenum api = 0x%X)", api); + EVENT("(EGLenum api = 0x%X)", api); try { @@ -574,13 +543,11 @@ EGLBoolean __stdcall eglBindAPI(EGLenum api) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLenum __stdcall eglQueryAPI(void) { - TRACE("()"); + EVENT("()"); try { @@ -592,13 +559,11 @@ EGLenum __stdcall eglQueryAPI(void) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglWaitClient(void) { - TRACE("()"); + EVENT("()"); try { @@ -610,13 +575,11 @@ EGLBoolean __stdcall eglWaitClient(void) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglReleaseThread(void) { - TRACE("()"); + EVENT("()"); try { @@ -628,13 +591,11 @@ EGLBoolean __stdcall eglReleaseThread(void) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLenum buftype = 0x%X, EGLClientBuffer buffer = 0x%0.8p, " + 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); @@ -642,33 +603,35 @@ EGLSurface __stdcall eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum bu { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_SURFACE; } - UNIMPLEMENTED(); // FIXME + if (buftype != EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE || !buffer) + { + return error(EGL_BAD_PARAMETER, EGL_NO_SURFACE); + } - return success(EGL_NO_SURFACE); + return display->createOffscreenSurface(config, (HANDLE)buffer, attrib_list); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { - TRACE("(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); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } @@ -681,24 +644,46 @@ EGLBoolean __stdcall eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - TRACE("(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); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } - UNIMPLEMENTED(); // FIXME + if (buffer != EGL_BACK_BUFFER) + { + return error(EGL_BAD_PARAMETER, EGL_FALSE); + } + + if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle()) + { + return error(EGL_BAD_SURFACE, EGL_FALSE); + } + + if (eglSurface->getBoundTexture()) + { + return error(EGL_BAD_ACCESS, EGL_FALSE); + } + + if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) + { + return error(EGL_BAD_MATCH, EGL_FALSE); + } + + if (!glBindTexImage(eglSurface)) + { + return error(EGL_BAD_MATCH, EGL_FALSE); + } return success(EGL_TRUE); } @@ -706,24 +691,43 @@ EGLBoolean __stdcall eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - TRACE("(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); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } - UNIMPLEMENTED(); // FIXME + if (buffer != EGL_BACK_BUFFER) + { + return error(EGL_BAD_PARAMETER, EGL_FALSE); + } + + if (surface == EGL_NO_SURFACE || eglSurface->getWindowHandle()) + { + return error(EGL_BAD_SURFACE, EGL_FALSE); + } + + if (eglSurface->getTextureFormat() == EGL_NO_TEXTURE) + { + return error(EGL_BAD_MATCH, EGL_FALSE); + } + + gl::Texture2D *texture = eglSurface->getBoundTexture(); + + if (texture) + { + texture->releaseTexImage(); + } return success(EGL_TRUE); } @@ -731,19 +735,17 @@ EGLBoolean __stdcall eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLi { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLint interval = %d)", dpy, interval); try { egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display)) + if (!validateDisplay(display)) { return EGL_FALSE; } @@ -763,29 +765,45 @@ EGLBoolean __stdcall eglSwapInterval(EGLDisplay dpy, EGLint interval) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLConfig config = 0x%0.8p, EGLContext share_context = 0x%0.8p, " + 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); try { // Get the requested client version (default is 1) and check it is two. EGLint client_version = 1; + bool reset_notification = false; + bool robust_access = false; + if (attrib_list) { for (const EGLint* attribute = attrib_list; attribute[0] != EGL_NONE; attribute += 2) { - if (attribute[0] == EGL_CONTEXT_CLIENT_VERSION) + switch (attribute[0]) { + case EGL_CONTEXT_CLIENT_VERSION: client_version = attribute[1]; - } - else - { + break; + case EGL_CONTEXT_OPENGL_ROBUST_ACCESS_EXT: + if (attribute[1] == EGL_TRUE) + { + return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); // Unimplemented + // robust_access = true; + } + else if (attribute[1] != EGL_FALSE) + return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); + break; + case EGL_CONTEXT_OPENGL_RESET_NOTIFICATION_STRATEGY_EXT: + if (attribute[1] == EGL_LOSE_CONTEXT_ON_RESET_EXT) + reset_notification = true; + else if (attribute[1] != EGL_NO_RESET_NOTIFICATION_EXT) + return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); + break; + default: return error(EGL_BAD_ATTRIBUTE, EGL_NO_CONTEXT); } } @@ -796,34 +814,41 @@ EGLContext __stdcall eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLConte return error(EGL_BAD_CONFIG, EGL_NO_CONTEXT); } + if (share_context && static_cast<gl::Context*>(share_context)->isResetNotificationEnabled() != reset_notification) + { + return error(EGL_BAD_MATCH, EGL_NO_CONTEXT); + } + egl::Display *display = static_cast<egl::Display*>(dpy); - if (!validate(display, config)) + if (!validateConfig(display, config)) { return EGL_NO_CONTEXT; } - EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context)); + EGLContext context = display->createContext(config, static_cast<gl::Context*>(share_context), reset_notification, robust_access); - return success(context); + if (context) + return success(context); + else + return error(EGL_CONTEXT_LOST, EGL_NO_CONTEXT); } catch(std::bad_alloc&) { return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT); } - - return EGL_NO_CONTEXT; } EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p)", dpy, ctx); try { egl::Display *display = static_cast<egl::Display*>(dpy); + gl::Context *context = static_cast<gl::Context*>(ctx); - if (!validate(display)) + if (!validateContext(display, context)) { return EGL_FALSE; } @@ -833,7 +858,7 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx) return error(EGL_BAD_CONTEXT, EGL_FALSE); } - display->destroyContext((gl::Context*)ctx); + display->destroyContext(context); return success(EGL_TRUE); } @@ -841,13 +866,11 @@ EGLBoolean __stdcall eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface draw = 0x%0.8p, EGLSurface read = 0x%0.8p, EGLContext ctx = 0x%0.8p)", + 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); try @@ -856,18 +879,24 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface gl::Context *context = static_cast<gl::Context*>(ctx); IDirect3DDevice9 *device = display->getDevice(); - if (!device || FAILED(device->TestCooperativeLevel())) + if (!device || display->testDeviceLost()) + { + display->notifyDeviceLost(); + return EGL_FALSE; + } + + if (display->isDeviceLost()) { return error(EGL_CONTEXT_LOST, EGL_FALSE); } - if (ctx != EGL_NO_CONTEXT && !validate(display, context)) + if (ctx != EGL_NO_CONTEXT && !validateContext(display, context)) { return EGL_FALSE; } - if ((draw != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(draw))) || - (read != EGL_NO_SURFACE && !validate(display, static_cast<egl::Surface*>(read)))) + if ((draw != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(draw))) || + (read != EGL_NO_SURFACE && !validateSurface(display, static_cast<egl::Surface*>(read)))) { return EGL_FALSE; } @@ -889,13 +918,11 @@ EGLBoolean __stdcall eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLContext __stdcall eglGetCurrentContext(void) { - TRACE("()"); + EVENT("()"); try { @@ -907,13 +934,11 @@ EGLContext __stdcall eglGetCurrentContext(void) { return error(EGL_BAD_ALLOC, EGL_NO_CONTEXT); } - - return EGL_NO_CONTEXT; } EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw) { - TRACE("(EGLint readdraw = %d)", readdraw); + EVENT("(EGLint readdraw = %d)", readdraw); try { @@ -936,13 +961,11 @@ EGLSurface __stdcall eglGetCurrentSurface(EGLint readdraw) { return error(EGL_BAD_ALLOC, EGL_NO_SURFACE); } - - return EGL_NO_SURFACE; } EGLDisplay __stdcall eglGetCurrentDisplay(void) { - TRACE("()"); + EVENT("()"); try { @@ -954,20 +977,19 @@ EGLDisplay __stdcall eglGetCurrentDisplay(void) { return error(EGL_BAD_ALLOC, EGL_NO_DISPLAY); } - - return EGL_NO_DISPLAY; } EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLContext ctx = 0x%0.8p, EGLint attribute = %d, EGLint *value = 0x%0.8p)", dpy, ctx, attribute, value); try { egl::Display *display = static_cast<egl::Display*>(dpy); + gl::Context *context = static_cast<gl::Context*>(ctx); - if (!validate(display)) + if (!validateContext(display, context)) { return EGL_FALSE; } @@ -980,13 +1002,11 @@ EGLBoolean __stdcall eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attr { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglWaitGL(void) { - TRACE("()"); + EVENT("()"); try { @@ -998,13 +1018,11 @@ EGLBoolean __stdcall eglWaitGL(void) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglWaitNative(EGLint engine) { - TRACE("(EGLint engine = %d)", engine); + EVENT("(EGLint engine = %d)", engine); try { @@ -1016,30 +1034,32 @@ EGLBoolean __stdcall eglWaitNative(EGLint engine) { return error(EGL_BAD_ALLOC, EGL_FALSE); } - - return EGL_FALSE; } EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { - TRACE("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p)", dpy, surface); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = (egl::Surface*)surface; - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } + if (display->isDeviceLost()) + { + return error(EGL_CONTEXT_LOST, EGL_FALSE); + } + if (surface == EGL_NO_SURFACE) { return error(EGL_BAD_SURFACE, EGL_FALSE); } - egl::Surface *eglSurface = (egl::Surface*)surface; - if (eglSurface->swap()) { return success(EGL_TRUE); @@ -1055,17 +1075,23 @@ EGLBoolean __stdcall eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { - TRACE("(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); try { egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); - if (!validate(display)) + if (!validateSurface(display, eglSurface)) { return EGL_FALSE; } + if (display->isDeviceLost()) + { + return error(EGL_CONTEXT_LOST, EGL_FALSE); + } + UNIMPLEMENTED(); // FIXME return success(0); @@ -1074,13 +1100,48 @@ EGLBoolean __stdcall eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativ { return error(EGL_BAD_ALLOC, EGL_FALSE); } +} + +EGLBoolean __stdcall eglPostSubBufferNV(EGLDisplay dpy, EGLSurface surface, EGLint x, EGLint y, EGLint width, EGLint height) +{ + EVENT("(EGLDisplay dpy = 0x%0.8p, EGLSurface surface = 0x%0.8p, EGLint x = %d, EGLint y = %d, EGLint width = %d, EGLint height = %d)", dpy, surface, x, y, width, height); + + try + { + egl::Display *display = static_cast<egl::Display*>(dpy); + egl::Surface *eglSurface = static_cast<egl::Surface*>(surface); + + if (!validateSurface(display, eglSurface)) + { + return EGL_FALSE; + } + + if (display->isDeviceLost()) + { + return error(EGL_CONTEXT_LOST, EGL_FALSE); + } + + if (surface == EGL_NO_SURFACE) + { + return error(EGL_BAD_SURFACE, EGL_FALSE); + } + + if (eglSurface->postSubBuffer(x, y, width, height)) + { + return success(EGL_TRUE); + } + } + catch(std::bad_alloc&) + { + return error(EGL_BAD_ALLOC, EGL_FALSE); + } return EGL_FALSE; } __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char *procname) { - TRACE("(const char *procname = \"%s\")", procname); + EVENT("(const char *procname = \"%s\")", procname); try { @@ -1092,6 +1153,8 @@ __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char static const Extension eglExtensions[] = { + {"eglQuerySurfacePointerANGLE", (__eglMustCastToProperFunctionPointerType)eglQuerySurfacePointerANGLE}, + {"eglPostSubBufferNV", (__eglMustCastToProperFunctionPointerType)eglPostSubBufferNV}, {"", NULL}, }; @@ -1109,7 +1172,5 @@ __eglMustCastToProperFunctionPointerType __stdcall eglGetProcAddress(const char { return error(EGL_BAD_ALLOC, (__eglMustCastToProperFunctionPointerType)NULL); } - - return NULL; } } |