Fixed bug 1946 - OpenGL contexts in threads
The SDL OpenGL context code is now properly thread aware. There are two new functions which return the current OpenGL window and context for the current thread. There are still places in the cocoa driver where the OpenGL context needs to be updated when the view changes. These will need a different solution and still use the last globally set context to avoid changing behavior.
This commit is contained in:
parent
de2ec2b443
commit
35275fc714
6 changed files with 57 additions and 21 deletions
|
@ -889,6 +889,16 @@ extern DECLSPEC SDL_GLContext SDLCALL SDL_GL_CreateContext(SDL_Window *
|
||||||
extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window * window,
|
extern DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window * window,
|
||||||
SDL_GLContext context);
|
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.
|
* \brief Set the swap interval for the current OpenGL context.
|
||||||
*
|
*
|
||||||
|
|
|
@ -302,7 +302,8 @@ struct SDL_VideoDevice
|
||||||
/* Cache current GL context; don't call the OS when it hasn't changed. */
|
/* Cache current GL context; don't call the OS when it hasn't changed. */
|
||||||
SDL_Window *current_glwin;
|
SDL_Window *current_glwin;
|
||||||
SDL_GLContext current_glctx;
|
SDL_GLContext current_glctx;
|
||||||
SDL_threadID current_glthread;
|
SDL_TLSID current_glwin_tls;
|
||||||
|
SDL_TLSID current_glctx_tls;
|
||||||
|
|
||||||
/* * * */
|
/* * * */
|
||||||
/* Data private to this driver */
|
/* Data private to this driver */
|
||||||
|
|
|
@ -500,6 +500,9 @@ SDL_VideoInit(const char *driver_name)
|
||||||
_this->gl_config.profile_mask = 0;
|
_this->gl_config.profile_mask = 0;
|
||||||
_this->gl_config.share_with_current_context = 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 */
|
/* Initialize the video subsystem */
|
||||||
if (_this->VideoInit(_this) < 0) {
|
if (_this->VideoInit(_this) < 0) {
|
||||||
SDL_VideoQuit();
|
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. */
|
/* Creating a context is assumed to make it current in the SDL driver. */
|
||||||
_this->current_glwin = window;
|
_this->current_glwin = window;
|
||||||
_this->current_glctx = ctx;
|
_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;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
@ -2747,7 +2751,12 @@ int
|
||||||
SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx)
|
SDL_GL_MakeCurrent(SDL_Window * window, SDL_GLContext ctx)
|
||||||
{
|
{
|
||||||
int retval;
|
int retval;
|
||||||
SDL_threadID thread = SDL_ThreadID();
|
|
||||||
|
if (window == SDL_GL_GetCurrentWindow() &&
|
||||||
|
ctx == SDL_GL_GetCurrentContext()) {
|
||||||
|
/* We're already current. */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ctx) {
|
if (!ctx) {
|
||||||
window = NULL;
|
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);
|
retval = _this->GL_MakeCurrent(_this, window, ctx);
|
||||||
if (retval == 0) {
|
if (retval == 0) {
|
||||||
_this->current_glwin = window;
|
_this->current_glwin = window;
|
||||||
_this->current_glctx = ctx;
|
_this->current_glctx = ctx;
|
||||||
_this->current_glthread = thread;
|
SDL_TLSSet(_this->current_glwin_tls, window, NULL);
|
||||||
|
SDL_TLSSet(_this->current_glctx_tls, ctx, NULL);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return retval;
|
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
|
int
|
||||||
SDL_GL_SetSwapInterval(int interval)
|
SDL_GL_SetSwapInterval(int interval)
|
||||||
{
|
{
|
||||||
if (!_this) {
|
if (!_this) {
|
||||||
return SDL_UninitializedVideo();
|
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");
|
return SDL_SetError("No OpenGL context has been made current");
|
||||||
} else if (_this->GL_SetSwapInterval) {
|
} else if (_this->GL_SetSwapInterval) {
|
||||||
return _this->GL_SetSwapInterval(_this, interval);
|
return _this->GL_SetSwapInterval(_this, interval);
|
||||||
|
@ -2792,7 +2817,7 @@ SDL_GL_GetSwapInterval(void)
|
||||||
{
|
{
|
||||||
if (!_this) {
|
if (!_this) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (_this->current_glctx == NULL) {
|
} else if (SDL_GL_GetCurrentContext() == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
} else if (_this->GL_GetSwapInterval) {
|
} else if (_this->GL_GetSwapInterval) {
|
||||||
return _this->GL_GetSwapInterval(_this);
|
return _this->GL_GetSwapInterval(_this);
|
||||||
|
@ -2820,7 +2845,7 @@ SDL_GL_DeleteContext(SDL_GLContext context)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_this->current_glctx == context) {
|
if (SDL_GL_GetCurrentContext() == context) {
|
||||||
SDL_GL_MakeCurrent(NULL, NULL);
|
SDL_GL_MakeCurrent(NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,7 @@ Cocoa_GL_CreateContext(_THIS, SDL_Window * window)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_this->gl_config.share_with_current_context) {
|
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];
|
context = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:share_context];
|
||||||
|
|
|
@ -535,7 +535,7 @@ WIN_GL_CreateContext(_THIS, SDL_Window * window)
|
||||||
HGLRC context, share_context;
|
HGLRC context, share_context;
|
||||||
|
|
||||||
if (_this->gl_config.share_with_current_context) {
|
if (_this->gl_config.share_with_current_context) {
|
||||||
share_context = (HGLRC)(_this->current_glctx);
|
share_context = (HGLRC)SDL_GL_GetCurrentContext();
|
||||||
} else {
|
} else {
|
||||||
share_context = 0;
|
share_context = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -532,7 +532,7 @@ X11_GL_CreateContext(_THIS, SDL_Window * window)
|
||||||
GLXContext context = NULL, share_context;
|
GLXContext context = NULL, share_context;
|
||||||
|
|
||||||
if (_this->gl_config.share_with_current_context) {
|
if (_this->gl_config.share_with_current_context) {
|
||||||
share_context = (GLXContext)(_this->current_glctx);
|
share_context = SDL_GL_GetCurrentContext();
|
||||||
} else {
|
} else {
|
||||||
share_context = NULL;
|
share_context = NULL;
|
||||||
}
|
}
|
||||||
|
@ -683,7 +683,7 @@ X11_GL_SetSwapInterval(_THIS, int interval)
|
||||||
} else if (_this->gl_data->glXSwapIntervalEXT) {
|
} else if (_this->gl_data->glXSwapIntervalEXT) {
|
||||||
Display *display = ((SDL_VideoData *) _this->driverdata)->display;
|
Display *display = ((SDL_VideoData *) _this->driverdata)->display;
|
||||||
const SDL_WindowData *windowdata = (SDL_WindowData *)
|
const SDL_WindowData *windowdata = (SDL_WindowData *)
|
||||||
_this->current_glwin->driverdata;
|
SDL_GL_GetCurrentWindow()->driverdata;
|
||||||
|
|
||||||
Window drawable = windowdata->xwindow;
|
Window drawable = windowdata->xwindow;
|
||||||
|
|
||||||
|
@ -727,7 +727,7 @@ X11_GL_GetSwapInterval(_THIS)
|
||||||
if (_this->gl_data->glXSwapIntervalEXT) {
|
if (_this->gl_data->glXSwapIntervalEXT) {
|
||||||
Display *display = ((SDL_VideoData *) _this->driverdata)->display;
|
Display *display = ((SDL_VideoData *) _this->driverdata)->display;
|
||||||
const SDL_WindowData *windowdata = (SDL_WindowData *)
|
const SDL_WindowData *windowdata = (SDL_WindowData *)
|
||||||
_this->current_glwin->driverdata;
|
SDL_GL_GetCurrentWindow()->driverdata;
|
||||||
Window drawable = windowdata->xwindow;
|
Window drawable = windowdata->xwindow;
|
||||||
unsigned int allow_late_swap_tearing = 0;
|
unsigned int allow_late_swap_tearing = 0;
|
||||||
unsigned int interval = 0;
|
unsigned int interval = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue