diff --git a/src/cocoa_opengl.m b/src/cocoa_opengl.m index 2ffd774c..1f1f0f23 100644 --- a/src/cocoa_opengl.m +++ b/src/cocoa_opengl.m @@ -30,6 +30,13 @@ #include "internal.h" +//======================================================================== +// The per-thread current context/window pointer +// TODO: Implement pthreads TLS +//======================================================================== +_GLFWwindow* _glfwCurrentWindow = NULL; + + ////////////////////////////////////////////////////////////////////////// ////// GLFW platform API ////// ////////////////////////////////////////////////////////////////////////// @@ -44,6 +51,18 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) [window->NSGL.context makeCurrentContext]; else [NSOpenGLContext clearCurrentContext]; + + _glfwCurrentWindow = window; +} + + +//======================================================================== +// Return the window object whose context is current +//======================================================================== + +_GLFWwindow* _glfwPlatformGetCurrentContext(void) +{ + return _glfwCurrentWindow; } @@ -64,7 +83,7 @@ void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapInterval(int interval) { - _GLFWwindow* window = _glfwLibrary.currentWindow; + _GLFWwindow* window = _glfwCurrentWindow; GLint sync = interval; [window->NSGL.context setValues:&sync forParameter:NSOpenGLCPSwapInterval]; diff --git a/src/internal.h b/src/internal.h index 89ac48b2..5ea2a815 100644 --- a/src/internal.h +++ b/src/internal.h @@ -216,7 +216,6 @@ struct _GLFWlibrary _GLFWhints hints; _GLFWwindow* windowListHead; - _GLFWwindow* currentWindow; _GLFWwindow* activeWindow; GLFWwindowsizefun windowSizeCallback; @@ -309,6 +308,7 @@ void _glfwPlatformWaitEvents(void); // OpenGL context management void _glfwPlatformMakeContextCurrent(_GLFWwindow* window); +_GLFWwindow* _glfwPlatformGetCurrentContext(void); void _glfwPlatformSwapBuffers(_GLFWwindow* window); void _glfwPlatformSwapInterval(int interval); void _glfwPlatformRefreshWindowParams(_GLFWwindow* window); diff --git a/src/opengl.c b/src/opengl.c index 67c6f414..dea2e387 100644 --- a/src/opengl.c +++ b/src/opengl.c @@ -350,7 +350,7 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig) GLboolean _glfwRefreshContextParams(void) { - _GLFWwindow* window = _glfwLibrary.currentWindow; + _GLFWwindow* window = _glfwPlatformGetCurrentContext(); if (!parseGLVersion(&window->glMajor, &window->glMinor, @@ -417,7 +417,7 @@ GLboolean _glfwRefreshContextParams(void) GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig) { - _GLFWwindow* window = _glfwLibrary.currentWindow; + _GLFWwindow* window = _glfwPlatformGetCurrentContext(); if (window->glMajor < wndconfig->glMajor || (window->glMajor == wndconfig->glMajor && @@ -492,16 +492,15 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow handle) return; } - if (_glfwLibrary.currentWindow == window) + if (_glfwPlatformGetCurrentContext() == window) return; _glfwPlatformMakeContextCurrent(window); - _glfwLibrary.currentWindow = window; } //======================================================================== -// Returns the window whose OpenGL context is current +// Return the window object whose context is current //======================================================================== GLFWAPI GLFWwindow glfwGetCurrentContext(void) @@ -512,7 +511,7 @@ GLFWAPI GLFWwindow glfwGetCurrentContext(void) return GL_FALSE; } - return _glfwLibrary.currentWindow; + return _glfwPlatformGetCurrentContext(); } @@ -546,7 +545,7 @@ GLFWAPI void glfwSwapInterval(int interval) return; } - if (!_glfwLibrary.currentWindow) + if (!_glfwPlatformGetCurrentContext()) { _glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL); return; @@ -571,7 +570,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension) return GL_FALSE; } - window = _glfwLibrary.currentWindow; + window = _glfwPlatformGetCurrentContext(); if (!window) { _glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL); @@ -632,7 +631,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname) return NULL; } - if (!_glfwLibrary.currentWindow) + if (!_glfwPlatformGetCurrentContext()) { _glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL); return NULL; @@ -660,7 +659,7 @@ GLFWAPI void glfwCopyContext(GLFWwindow hsrc, GLFWwindow hdst, unsigned long mas src = (_GLFWwindow*) hsrc; dst = (_GLFWwindow*) hdst; - if (_glfwLibrary.currentWindow == dst) + if (_glfwPlatformGetCurrentContext() == dst) { _glfwSetError(GLFW_INVALID_VALUE, "glfwCopyContext: Cannot copy OpenGL state to a current context"); diff --git a/src/win32_opengl.c b/src/win32_opengl.c index fe1898e7..3b30179f 100644 --- a/src/win32_opengl.c +++ b/src/win32_opengl.c @@ -31,6 +31,12 @@ #include "internal.h" +//======================================================================== +// The per-thread current context/window pointer +//======================================================================== +__declspec(thread) _GLFWwindow* _glfwCurrentWindow = NULL; + + //======================================================================== // Initialize WGL-specific extensions // This function is called once before initial context creation, i.e. before @@ -438,7 +444,7 @@ static GLboolean createContext(_GLFWwindow* window, } } - glfwMakeContextCurrent(window); + _glfwPlatformMakeContextCurrent(window); initWGLExtensions(window); return GL_TRUE; @@ -507,8 +513,8 @@ void _glfwDestroyContext(_GLFWwindow* window) { // This is duplicated from glfwDestroyWindow // TODO: Stop duplicating code - if (window == _glfwLibrary.currentWindow) - glfwMakeContextCurrent(NULL); + if (window == _glfwCurrentWindow) + _glfwPlatformMakeContextCurrent(NULL); if (window->WGL.context) { @@ -538,6 +544,18 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) wglMakeCurrent(window->WGL.DC, window->WGL.context); else wglMakeCurrent(NULL, NULL); + + _glfwCurrentWindow = window; +} + + +//======================================================================== +// Return the window object whose context is current +//======================================================================== + +_GLFWwindow* _glfwPlatformGetCurrentContext(void) +{ + return _glfwCurrentWindow; } @@ -557,7 +575,7 @@ void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapInterval(int interval) { - _GLFWwindow* window = _glfwLibrary.currentWindow; + _GLFWwindow* window = _glfwCurrentWindow; if (window->WGL.EXT_swap_control) window->WGL.SwapIntervalEXT(interval); @@ -572,7 +590,7 @@ int _glfwPlatformExtensionSupported(const char* extension) { const GLubyte* extensions; - _GLFWwindow* window = _glfwLibrary.currentWindow; + _GLFWwindow* window = _glfwCurrentWindow; if (window->WGL.GetExtensionsStringEXT != NULL) { diff --git a/src/window.c b/src/window.c index df592751..352e3ad9 100644 --- a/src/window.c +++ b/src/window.c @@ -451,8 +451,9 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow handle) return; // Clear the current context if this window's context is current - if (window == _glfwLibrary.currentWindow) - glfwMakeContextCurrent(NULL); + // TODO: Re-examine this in light of multithreading + if (window == _glfwPlatformGetCurrentContext()) + _glfwPlatformMakeContextCurrent(NULL); // Clear the active window pointer if this is the active window if (window == _glfwLibrary.activeWindow) diff --git a/src/x11_opengl.c b/src/x11_opengl.c index 2a5cc451..d7f33999 100644 --- a/src/x11_opengl.c +++ b/src/x11_opengl.c @@ -37,6 +37,11 @@ // This is the only glXGetProcAddress variant not declared by glxext.h void (*glXGetProcAddressEXT(const GLubyte* procName))(); +//======================================================================== +// The per-thread current context/window pointer +//======================================================================== +__thread _GLFWwindow* _glfwCurrentWindow = NULL; + //======================================================================== // Returns the specified attribute of the specified GLXFBConfig @@ -621,6 +626,10 @@ XVisualInfo* _glfwGetContextVisual(_GLFWwindow* window) } +////////////////////////////////////////////////////////////////////////// +////// GLFW platform API ////// +////////////////////////////////////////////////////////////////////////// + //======================================================================== // Make the OpenGL context associated with the specified window current //======================================================================== @@ -635,6 +644,18 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window) } else glXMakeCurrent(_glfwLibrary.X11.display, None, NULL); + + _glfwCurrentWindow = window; +} + + +//======================================================================== +// Return the window object whose context is current +//======================================================================== + +_GLFWwindow* _glfwPlatformGetCurrentContext(void) +{ + return _glfwCurrentWindow; } @@ -654,7 +675,7 @@ void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapInterval(int interval) { - _GLFWwindow* window = _glfwLibrary.currentWindow; + _GLFWwindow* window = _glfwCurrentWindow; if (_glfwLibrary.GLX.EXT_swap_control) {