diff --git a/include/SDL_video.h b/include/SDL_video.h index 66815197c..39e01c465 100644 --- a/include/SDL_video.h +++ b/include/SDL_video.h @@ -889,6 +889,16 @@ extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_CreateContext(SDL_Window * extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext context); +/** + * \brief Get the currently active OpenGL window. + */ +extern DECLSPEC SDL_Window* SDLCALL SDL_GL_GetCurrentWindow(void); + +/** + * \brief Get the currently active OpenGL context. + */ +extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_GetCurrentContext(void); + /** * \brief Set the swap interval for the current OpenGL context. * diff --git a/src/video/SDL_sysvideo.h b/src/video/SDL_sysvideo.h index cd3fa2717..3020bc773 100644 --- a/src/video/SDL_sysvideo.h +++ b/src/video/SDL_sysvideo.h @@ -302,7 +302,8 @@ struct SDL_VideoDevice /* Cache current GL context; don't call the OS when it hasn't changed. */ SDL_Window *current_glwin; SDL_GLContext current_glctx; - SDL_threadID current_glthread; + SDL_TLSID current_glwin_tls; + SDL_TLSID current_glctx_tls; /* * * */ /* Data private to this driver */ diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c index 1a3fbda8b..40060237e 100644 --- a/src/video/SDL_video.c +++ b/src/video/SDL_video.c @@ -500,6 +500,9 @@ SDL_VideoInit(const char *driver_name) _this->gl_config.profile_mask = 0; _this->gl_config.share_with_current_context = 0; + _this->current_glwin_tls = SDL_TLSCreate(); + _this->current_glctx_tls = SDL_TLSCreate(); + /* Initialize the video subsystem */ if (_this->VideoInit(_this) < 0) { SDL_VideoQuit(); @@ -2738,7 +2741,8 @@ SDL_GL_CreateContext(SDL_Window * window) /* Creating a context is assumed to make it current in the SDL driver. */ _this->current_glwin = window; _this->current_glctx = ctx; - _this->current_glthread = SDL_ThreadID(); + SDL_TLSSet(_this->current_glwin_tls, window, NULL); + SDL_TLSSet(_this->current_glctx_tls, ctx, NULL); return ctx; } @@ -2747,7 +2751,12 @@ int SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx) { int retval; - SDL_threadID thread = SDL_ThreadID(); + + if (window == SDL_GL_GetCurrentWindow() && + ctx == SDL_GL_GetCurrentContext()) { + /* We're already current. */ + return 0; + } if (!ctx) { window = NULL; @@ -2759,26 +2768,42 @@ SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx) } } - if ((window == _this->current_glwin) && (ctx == _this->current_glctx) && (thread == _this->current_glthread)) { - retval = 0; /* we're already current. */ - } else { - retval = _this->GL_MakeCurrent(_this, window, ctx); - if (retval == 0) { - _this->current_glwin = window; - _this->current_glctx = ctx; - _this->current_glthread = thread; - } + retval = _this->GL_MakeCurrent(_this, window, ctx); + if (retval == 0) { + _this->current_glwin = window; + _this->current_glctx = ctx; + SDL_TLSSet(_this->current_glwin_tls, window, NULL); + SDL_TLSSet(_this->current_glctx_tls, ctx, NULL); } - return retval; } +SDL_Window * +SDL_GL_GetCurrentWindow(void) +{ + if (!_this) { + SDL_UninitializedVideo(); + return NULL; + } + return (SDL_Window *)SDL_TLSGet(_this->current_glwin_tls); +} + +SDL_GLContext +SDL_GL_GetCurrentContext(void) +{ + if (!_this) { + SDL_UninitializedVideo(); + return NULL; + } + return (SDL_GLContext)SDL_TLSGet(_this->current_glctx_tls); +} + int SDL_GL_SetSwapInterval(int interval) { if (!_this) { return SDL_UninitializedVideo(); - } else if (_this->current_glctx == NULL) { + } else if (SDL_GL_GetCurrentContext() == NULL) { return SDL_SetError("No OpenGL context has been made current"); } else if (_this->GL_SetSwapInterval) { return _this->GL_SetSwapInterval(_this, interval); @@ -2792,7 +2817,7 @@ SDL_GL_GetSwapInterval(void) { if (!_this) { return 0; - } else if (_this->current_glctx == NULL) { + } else if (SDL_GL_GetCurrentContext() == NULL) { return 0; } else if (_this->GL_GetSwapInterval) { return _this->GL_GetSwapInterval(_this); @@ -2820,7 +2845,7 @@ SDL_GL_DeleteContext(SDL_GLContext context) return; } - if (_this->current_glctx == context) { + if (SDL_GL_GetCurrentContext() == context) { SDL_GL_MakeCurrent(NULL, NULL); } diff --git a/src/video/cocoa/SDL_cocoaopengl.m b/src/video/cocoa/SDL_cocoaopengl.m index 35e74e328..8289107e3 100644 --- a/src/video/cocoa/SDL_cocoaopengl.m +++ b/src/video/cocoa/SDL_cocoaopengl.m @@ -178,7 +178,7 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window) } if (_this->gl_config.share_with_current_context) { - share_context = (NSOpenGLContext*)(_this->current_glctx); + share_context = (NSOpenGLContext*)SDL_GL_GetCurrentContext(); } context = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:share_context]; diff --git a/src/video/windows/SDL_windowsopengl.c b/src/video/windows/SDL_windowsopengl.c index ec9f34a63..583220d83 100644 --- a/src/video/windows/SDL_windowsopengl.c +++ b/src/video/windows/SDL_windowsopengl.c @@ -535,7 +535,7 @@ WIN_GL_CreateContext(_THIS, SDL_Window * window) HGLRC context, share_context; if (_this->gl_config.share_with_current_context) { - share_context = (HGLRC)(_this->current_glctx); + share_context = (HGLRC)SDL_GL_GetCurrentContext(); } else { share_context = 0; } diff --git a/src/video/x11/SDL_x11opengl.c b/src/video/x11/SDL_x11opengl.c index 1e1078eff..c8ef1f156 100644 --- a/src/video/x11/SDL_x11opengl.c +++ b/src/video/x11/SDL_x11opengl.c @@ -532,7 +532,7 @@ X11_GL_CreateContext(_THIS, SDL_Window * window) GLXContext context = NULL, share_context; if (_this->gl_config.share_with_current_context) { - share_context = (GLXContext)(_this->current_glctx); + share_context = SDL_GL_GetCurrentContext(); } else { share_context = NULL; } @@ -683,7 +683,7 @@ X11_GL_SetSwapInterval(_THIS, int interval) } else if (_this->gl_data->glXSwapIntervalEXT) { Display *display = ((SDL_VideoData *) _this->driverdata)->display; const SDL_WindowData *windowdata = (SDL_WindowData *) - _this->current_glwin->driverdata; + SDL_GL_GetCurrentWindow()->driverdata; Window drawable = windowdata->xwindow; @@ -727,7 +727,7 @@ X11_GL_GetSwapInterval(_THIS) if (_this->gl_data->glXSwapIntervalEXT) { Display *display = ((SDL_VideoData *) _this->driverdata)->display; const SDL_WindowData *windowdata = (SDL_WindowData *) - _this->current_glwin->driverdata; + SDL_GL_GetCurrentWindow()->driverdata; Window drawable = windowdata->xwindow; unsigned int allow_late_swap_tearing = 0; unsigned int interval = 0;