From 6539d101f32c6d75856882032ce61fd3ad2eb35b Mon Sep 17 00:00:00 2001 From: Doug Binks Date: Wed, 15 Jul 2020 13:19:14 +0100 Subject: [PATCH] Added TLS for current user context and simplified code --- src/context.c | 11 +++++++++++ src/egl_context.c | 34 ++++++++++------------------------ src/glx_context.c | 20 ++++++-------------- src/init.c | 4 +++- src/internal.h | 1 + src/nsgl_context.m | 6 ++---- src/osmesa_context.c | 19 +++++++++---------- src/wgl_context.c | 20 ++++++-------------- 8 files changed, 48 insertions(+), 67 deletions(-) diff --git a/src/context.c b/src/context.c index 5bab2d01..6e558d55 100644 --- a/src/context.c +++ b/src/context.c @@ -617,6 +617,8 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow* handle) _GLFW_REQUIRE_INIT(); + _glfwPlatformSetTls(&_glfw.usercontextSlot, NULL); + if (window && window->context.client == GLFW_NO_API) { _glfwInputError(GLFW_NO_WINDOW_CONTEXT, @@ -773,11 +775,17 @@ GLFWAPI GLFWusercontext* glfwCreateUserContext(GLFWwindow* handle) GLFWAPI void glfwDestroyUserContext(GLFWusercontext* handle) { _GLFWusercontext* context = (_GLFWusercontext*)handle; + _GLFWusercontext* prev = _glfwPlatformGetTls(&_glfw.usercontextSlot); _GLFW_REQUIRE_INIT(); if (context) + { + if(prev==context) + _glfwPlatformSetTls(&_glfw.usercontextSlot,NULL); + context->destroy(context); + } } GLFWAPI void glfwMakeUserContextCurrent(GLFWusercontext* handle) @@ -786,6 +794,9 @@ GLFWAPI void glfwMakeUserContextCurrent(GLFWusercontext* handle) _GLFW_REQUIRE_INIT(); + // Call glfwMakeContextCurrent(NULL) to both clear context TLS and set + // context to NULL if required by platform & context, and this + // handles case of calling glfwMakeUserContextCurrent(NULL) glfwMakeContextCurrent(NULL); if (context) diff --git a/src/egl_context.c b/src/egl_context.c index eb8d6a74..43615794 100644 --- a/src/egl_context.c +++ b/src/egl_context.c @@ -817,32 +817,18 @@ GLFWbool _glfwChooseVisualEGL(const _GLFWwndconfig* wndconfig, static void _glfwMakeUserContextCurrentEGL(_GLFWusercontext* context) { - if(context) + if (!eglMakeCurrent(_glfw.egl.display, + context->window->context.egl.surface, + context->window->context.egl.surface, + context->egl.handle)) { - if (!eglMakeCurrent(_glfw.egl.display, - context->window->context.egl.surface, - context->window->context.egl.surface, - context->egl.handle)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "EGL: Failed to make context current: %s", - getEGLErrorString(eglGetError())); - return; - } - } - else - { - if (!eglMakeCurrent(_glfw.egl.display, - EGL_NO_SURFACE, - EGL_NO_SURFACE, - EGL_NO_CONTEXT)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "EGL: Failed to clear current context: %s", - getEGLErrorString(eglGetError())); - return; - } + _glfwInputError(GLFW_PLATFORM_ERROR, + "EGL: Failed to make user context current: %s", + getEGLErrorString(eglGetError())); + _glfwPlatformSetTls(&_glfw.usercontextSlot, NULL); + return; } + _glfwPlatformSetTls(&_glfw.usercontextSlot, context); } static void _glfwDestroyUserContextEGL(_GLFWusercontext* context) diff --git a/src/glx_context.c b/src/glx_context.c index 19ccf7f9..957be797 100644 --- a/src/glx_context.c +++ b/src/glx_context.c @@ -680,22 +680,14 @@ GLFWbool _glfwChooseVisualGLX(const _GLFWwndconfig* wndconfig, static void _glfwMakeUserContextCurrentGLX(_GLFWusercontext* context) { - if(context) + if(!glXMakeCurrent(_glfw.x11.display, context->window->context.glx.window,context->glx.handle)) { - if(!glXMakeCurrent(_glfw.x11.display, context->window->context.glx.window,context->glx.handle)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "GLX: Failed to set current user context"); - } - } - else - { - if (!glXMakeCurrent(_glfw.x11.display, None, NULL)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "GLX: Failed to clear current context"); - } + _glfwInputError(GLFW_PLATFORM_ERROR, + "GLX: Failed to make user context current"); + _glfwPlatformSetTls(&_glfw.usercontextSlot, NULL); + return; } + _glfwPlatformSetTls(&_glfw.usercontextSlot, context); } static void _glfwDestroyUserContextGLX(_GLFWusercontext* context) diff --git a/src/init.c b/src/init.c index f9ce336a..5df22d0e 100644 --- a/src/init.c +++ b/src/init.c @@ -102,6 +102,7 @@ static void terminate(void) free(error); } + _glfwPlatformDestroyTls(&_glfw.usercontextSlot); _glfwPlatformDestroyTls(&_glfw.contextSlot); _glfwPlatformDestroyTls(&_glfw.errorSlot); _glfwPlatformDestroyMutex(&_glfw.errorLock); @@ -244,7 +245,8 @@ GLFWAPI int glfwInit(void) if (!_glfwPlatformCreateMutex(&_glfw.errorLock) || !_glfwPlatformCreateTls(&_glfw.errorSlot) || - !_glfwPlatformCreateTls(&_glfw.contextSlot)) + !_glfwPlatformCreateTls(&_glfw.contextSlot) || + !_glfwPlatformCreateTls(&_glfw.usercontextSlot)) { terminate(); return GLFW_FALSE; diff --git a/src/internal.h b/src/internal.h index bf99478e..ab6c9471 100644 --- a/src/internal.h +++ b/src/internal.h @@ -564,6 +564,7 @@ struct _GLFWlibrary _GLFWtls errorSlot; _GLFWtls contextSlot; + _GLFWtls usercontextSlot; _GLFWmutex errorLock; struct { diff --git a/src/nsgl_context.m b/src/nsgl_context.m index 29430060..866cb4bd 100644 --- a/src/nsgl_context.m +++ b/src/nsgl_context.m @@ -353,10 +353,9 @@ static void _glfwMakeUserContextCurrentNSGL(_GLFWusercontext* context) { @autoreleasepool { - if (context) [context->nsgl.object makeCurrentContext]; - else - [NSOpenGLContext clearCurrentContext]; + + _glfwPlatformSetTls(&_glfw.usercontextSlot, context); } // autoreleasepool } @@ -365,7 +364,6 @@ static void _glfwDestroyUserContextNSGL(_GLFWusercontext* context) { @autoreleasepool { - if (context->nsgl.object) [context->nsgl.object release]; } // autoreleasepool diff --git a/src/osmesa_context.c b/src/osmesa_context.c index 69ae4e2e..95b4017f 100644 --- a/src/osmesa_context.c +++ b/src/osmesa_context.c @@ -301,18 +301,17 @@ GLFWbool _glfwCreateContextOSMesa(_GLFWwindow* window, static void _glfwMakeUserContextCurrentOSMesa(_GLFWusercontext* context) { - if(context) + if (!OSMesaMakeCurrent(context->osmesa.handle, + context->window->context.osmesa.buffer, + GL_UNSIGNED_BYTE, + context->window->context.osmesa.width, context->window->context.osmesa.height)) { - if (!OSMesaMakeCurrent(context->osmesa.handle, - context->window->context.osmesa.buffer, - GL_UNSIGNED_BYTE, - context->window->context.osmesa.width, context->window->context.osmesa.height)) - { - _glfwInputError(GLFW_PLATFORM_ERROR, - "OSMesa: Failed to make context current"); - return; - } + _glfwInputError(GLFW_PLATFORM_ERROR, + "OSMesa: Failed to make user context current"); + _glfwPlatformSetTls(&_glfw.usercontextSlot, NULL); + return; } + _glfwPlatformSetTls(&_glfw.usercontextSlot, context); } static void _glfwDestroyUserContextOSMesa(_GLFWusercontext* context) diff --git a/src/wgl_context.c b/src/wgl_context.c index d6d668ad..d0702b66 100644 --- a/src/wgl_context.c +++ b/src/wgl_context.c @@ -792,22 +792,14 @@ GLFWbool _glfwCreateContextWGL(_GLFWwindow* window, static void _glfwMakeUserContextCurrentWGL(_GLFWusercontext* context) { - if(context) + if(!wglMakeCurrent(context->window->context.wgl.dc,context->wgl.handle)) { - if(!wglMakeCurrent(context->window->context.wgl.dc,context->wgl.handle)) - { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "WGL: Failed to set current user context"); - } - } - else - { - if (!wglMakeCurrent(NULL, NULL)) - { - _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, - "WGL: Failed to clear current context"); - } + _glfwInputErrorWin32(GLFW_PLATFORM_ERROR, + "WGL: Failed to make user context current"); + _glfwPlatformSetTls(&_glfw.usercontextSlot, NULL); + return; } + _glfwPlatformSetTls(&_glfw.usercontextSlot, context); } static void _glfwDestroyUserContextWGL(_GLFWusercontext* context)