Initial TLS implementation (Cocoa broken).

This commit is contained in:
Camilla Berglund 2012-08-12 14:13:18 +02:00
parent d0c7a7a2c4
commit 9e4bc36dd8
6 changed files with 78 additions and 20 deletions

View File

@ -30,6 +30,13 @@
#include "internal.h" #include "internal.h"
//========================================================================
// The per-thread current context/window pointer
// TODO: Implement pthreads TLS
//========================================================================
_GLFWwindow* _glfwCurrentWindow = NULL;
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW platform API ////// ////// GLFW platform API //////
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
@ -44,6 +51,18 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
[window->NSGL.context makeCurrentContext]; [window->NSGL.context makeCurrentContext];
else else
[NSOpenGLContext clearCurrentContext]; [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) void _glfwPlatformSwapInterval(int interval)
{ {
_GLFWwindow* window = _glfwLibrary.currentWindow; _GLFWwindow* window = _glfwCurrentWindow;
GLint sync = interval; GLint sync = interval;
[window->NSGL.context setValues:&sync forParameter:NSOpenGLCPSwapInterval]; [window->NSGL.context setValues:&sync forParameter:NSOpenGLCPSwapInterval];

View File

@ -216,7 +216,6 @@ struct _GLFWlibrary
_GLFWhints hints; _GLFWhints hints;
_GLFWwindow* windowListHead; _GLFWwindow* windowListHead;
_GLFWwindow* currentWindow;
_GLFWwindow* activeWindow; _GLFWwindow* activeWindow;
GLFWwindowsizefun windowSizeCallback; GLFWwindowsizefun windowSizeCallback;
@ -309,6 +308,7 @@ void _glfwPlatformWaitEvents(void);
// OpenGL context management // OpenGL context management
void _glfwPlatformMakeContextCurrent(_GLFWwindow* window); void _glfwPlatformMakeContextCurrent(_GLFWwindow* window);
_GLFWwindow* _glfwPlatformGetCurrentContext(void);
void _glfwPlatformSwapBuffers(_GLFWwindow* window); void _glfwPlatformSwapBuffers(_GLFWwindow* window);
void _glfwPlatformSwapInterval(int interval); void _glfwPlatformSwapInterval(int interval);
void _glfwPlatformRefreshWindowParams(_GLFWwindow* window); void _glfwPlatformRefreshWindowParams(_GLFWwindow* window);

View File

@ -350,7 +350,7 @@ GLboolean _glfwIsValidContextConfig(_GLFWwndconfig* wndconfig)
GLboolean _glfwRefreshContextParams(void) GLboolean _glfwRefreshContextParams(void)
{ {
_GLFWwindow* window = _glfwLibrary.currentWindow; _GLFWwindow* window = _glfwPlatformGetCurrentContext();
if (!parseGLVersion(&window->glMajor, if (!parseGLVersion(&window->glMajor,
&window->glMinor, &window->glMinor,
@ -417,7 +417,7 @@ GLboolean _glfwRefreshContextParams(void)
GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig) GLboolean _glfwIsValidContext(_GLFWwndconfig* wndconfig)
{ {
_GLFWwindow* window = _glfwLibrary.currentWindow; _GLFWwindow* window = _glfwPlatformGetCurrentContext();
if (window->glMajor < wndconfig->glMajor || if (window->glMajor < wndconfig->glMajor ||
(window->glMajor == wndconfig->glMajor && (window->glMajor == wndconfig->glMajor &&
@ -492,16 +492,15 @@ GLFWAPI void glfwMakeContextCurrent(GLFWwindow handle)
return; return;
} }
if (_glfwLibrary.currentWindow == window) if (_glfwPlatformGetCurrentContext() == window)
return; return;
_glfwPlatformMakeContextCurrent(window); _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) GLFWAPI GLFWwindow glfwGetCurrentContext(void)
@ -512,7 +511,7 @@ GLFWAPI GLFWwindow glfwGetCurrentContext(void)
return GL_FALSE; return GL_FALSE;
} }
return _glfwLibrary.currentWindow; return _glfwPlatformGetCurrentContext();
} }
@ -546,7 +545,7 @@ GLFWAPI void glfwSwapInterval(int interval)
return; return;
} }
if (!_glfwLibrary.currentWindow) if (!_glfwPlatformGetCurrentContext())
{ {
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL); _glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
return; return;
@ -571,7 +570,7 @@ GLFWAPI int glfwExtensionSupported(const char* extension)
return GL_FALSE; return GL_FALSE;
} }
window = _glfwLibrary.currentWindow; window = _glfwPlatformGetCurrentContext();
if (!window) if (!window)
{ {
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL); _glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
@ -632,7 +631,7 @@ GLFWAPI GLFWglproc glfwGetProcAddress(const char* procname)
return NULL; return NULL;
} }
if (!_glfwLibrary.currentWindow) if (!_glfwPlatformGetCurrentContext())
{ {
_glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL); _glfwSetError(GLFW_NO_CURRENT_CONTEXT, NULL);
return NULL; return NULL;
@ -660,7 +659,7 @@ GLFWAPI void glfwCopyContext(GLFWwindow hsrc, GLFWwindow hdst, unsigned long mas
src = (_GLFWwindow*) hsrc; src = (_GLFWwindow*) hsrc;
dst = (_GLFWwindow*) hdst; dst = (_GLFWwindow*) hdst;
if (_glfwLibrary.currentWindow == dst) if (_glfwPlatformGetCurrentContext() == dst)
{ {
_glfwSetError(GLFW_INVALID_VALUE, _glfwSetError(GLFW_INVALID_VALUE,
"glfwCopyContext: Cannot copy OpenGL state to a current context"); "glfwCopyContext: Cannot copy OpenGL state to a current context");

View File

@ -31,6 +31,12 @@
#include "internal.h" #include "internal.h"
//========================================================================
// The per-thread current context/window pointer
//========================================================================
__declspec(thread) _GLFWwindow* _glfwCurrentWindow = NULL;
//======================================================================== //========================================================================
// Initialize WGL-specific extensions // Initialize WGL-specific extensions
// This function is called once before initial context creation, i.e. before // 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); initWGLExtensions(window);
return GL_TRUE; return GL_TRUE;
@ -507,8 +513,8 @@ void _glfwDestroyContext(_GLFWwindow* window)
{ {
// This is duplicated from glfwDestroyWindow // This is duplicated from glfwDestroyWindow
// TODO: Stop duplicating code // TODO: Stop duplicating code
if (window == _glfwLibrary.currentWindow) if (window == _glfwCurrentWindow)
glfwMakeContextCurrent(NULL); _glfwPlatformMakeContextCurrent(NULL);
if (window->WGL.context) if (window->WGL.context)
{ {
@ -538,6 +544,18 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
wglMakeCurrent(window->WGL.DC, window->WGL.context); wglMakeCurrent(window->WGL.DC, window->WGL.context);
else else
wglMakeCurrent(NULL, NULL); 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) void _glfwPlatformSwapInterval(int interval)
{ {
_GLFWwindow* window = _glfwLibrary.currentWindow; _GLFWwindow* window = _glfwCurrentWindow;
if (window->WGL.EXT_swap_control) if (window->WGL.EXT_swap_control)
window->WGL.SwapIntervalEXT(interval); window->WGL.SwapIntervalEXT(interval);
@ -572,7 +590,7 @@ int _glfwPlatformExtensionSupported(const char* extension)
{ {
const GLubyte* extensions; const GLubyte* extensions;
_GLFWwindow* window = _glfwLibrary.currentWindow; _GLFWwindow* window = _glfwCurrentWindow;
if (window->WGL.GetExtensionsStringEXT != NULL) if (window->WGL.GetExtensionsStringEXT != NULL)
{ {

View File

@ -451,8 +451,9 @@ GLFWAPI void glfwDestroyWindow(GLFWwindow handle)
return; return;
// Clear the current context if this window's context is current // Clear the current context if this window's context is current
if (window == _glfwLibrary.currentWindow) // TODO: Re-examine this in light of multithreading
glfwMakeContextCurrent(NULL); if (window == _glfwPlatformGetCurrentContext())
_glfwPlatformMakeContextCurrent(NULL);
// Clear the active window pointer if this is the active window // Clear the active window pointer if this is the active window
if (window == _glfwLibrary.activeWindow) if (window == _glfwLibrary.activeWindow)

View File

@ -37,6 +37,11 @@
// This is the only glXGetProcAddress variant not declared by glxext.h // This is the only glXGetProcAddress variant not declared by glxext.h
void (*glXGetProcAddressEXT(const GLubyte* procName))(); void (*glXGetProcAddressEXT(const GLubyte* procName))();
//========================================================================
// The per-thread current context/window pointer
//========================================================================
__thread _GLFWwindow* _glfwCurrentWindow = NULL;
//======================================================================== //========================================================================
// Returns the specified attribute of the specified GLXFBConfig // 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 // Make the OpenGL context associated with the specified window current
//======================================================================== //========================================================================
@ -635,6 +644,18 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
} }
else else
glXMakeCurrent(_glfwLibrary.X11.display, None, NULL); 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) void _glfwPlatformSwapInterval(int interval)
{ {
_GLFWwindow* window = _glfwLibrary.currentWindow; _GLFWwindow* window = _glfwCurrentWindow;
if (_glfwLibrary.GLX.EXT_swap_control) if (_glfwLibrary.GLX.EXT_swap_control)
{ {