1
0
Fork 0
mirror of https://github.com/gwm17/glfw.git synced 2024-11-23 02:38:52 -05:00

Split out TLS code into separate modules.

This allows the TLS code to be re-used by partial ports like EGL.
This commit is contained in:
Camilla Berglund 2014-03-30 14:37:20 +02:00
parent 2889f484f4
commit 78efc18079
16 changed files with 278 additions and 88 deletions

View File

@ -12,20 +12,20 @@ set(common_SOURCES clipboard.c context.c gamma.c init.c input.c joystick.c
monitor.c time.c window.c) monitor.c time.c window.c)
if (_GLFW_COCOA) if (_GLFW_COCOA)
set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h) set(glfw_HEADERS ${common_HEADERS} cocoa_platform.h posix_tls.h)
set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_gamma.c set(glfw_SOURCES ${common_SOURCES} cocoa_clipboard.m cocoa_gamma.c
cocoa_init.m cocoa_joystick.m cocoa_monitor.m cocoa_time.c cocoa_init.m cocoa_joystick.m cocoa_monitor.m cocoa_time.c
cocoa_window.m) cocoa_window.m posix_tls.c)
elseif (_GLFW_WIN32) elseif (_GLFW_WIN32)
set(glfw_HEADERS ${common_HEADERS} win32_platform.h) set(glfw_HEADERS ${common_HEADERS} win32_platform.h win32_tls.h)
set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_gamma.c set(glfw_SOURCES ${common_SOURCES} win32_clipboard.c win32_gamma.c
win32_init.c win32_joystick.c win32_monitor.c win32_time.c win32_init.c win32_joystick.c win32_monitor.c win32_time.c
win32_window.c) win32_tls.c win32_window.c)
elseif (_GLFW_X11) elseif (_GLFW_X11)
set(glfw_HEADERS ${common_HEADERS} x11_platform.h) set(glfw_HEADERS ${common_HEADERS} x11_platform.h posix_tls.h)
set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_gamma.c x11_init.c set(glfw_SOURCES ${common_SOURCES} x11_clipboard.c x11_gamma.c x11_init.c
x11_joystick.c x11_monitor.c x11_time.c x11_window.c x11_joystick.c x11_monitor.c x11_time.c x11_window.c
x11_unicode.c) x11_unicode.c posix_tls.c)
endif() endif()
if (_GLFW_EGL) if (_GLFW_EGL)

View File

@ -37,6 +37,8 @@
typedef void* id; typedef void* id;
#endif #endif
#include "posix_tls.h"
#if defined(_GLFW_NSGL) #if defined(_GLFW_NSGL)
#include "nsgl_platform.h" #include "nsgl_platform.h"
#else #else

View File

@ -32,22 +32,6 @@
#include <assert.h> #include <assert.h>
// Thread local storage attribute macro
//
#if defined(_MSC_VER)
#define _GLFW_TLS __declspec(thread)
#elif defined(__GNUC__)
#define _GLFW_TLS __thread
#else
#define _GLFW_TLS
#endif
// The per-thread current context/window pointer
//
static _GLFW_TLS _GLFWwindow* _glfwCurrentWindow = NULL;
// Return a description of the specified EGL error // Return a description of the specified EGL error
// //
static const char* getErrorString(EGLint error) static const char* getErrorString(EGLint error)
@ -207,6 +191,9 @@ static GLboolean chooseFBConfigs(const _GLFWctxconfig* ctxconfig,
// //
int _glfwInitContextAPI(void) int _glfwInitContextAPI(void)
{ {
if (!_glfwInitTLS())
return GL_FALSE;
_glfw.egl.display = eglGetDisplay((EGLNativeDisplayType)_GLFW_EGL_NATIVE_DISPLAY); _glfw.egl.display = eglGetDisplay((EGLNativeDisplayType)_GLFW_EGL_NATIVE_DISPLAY);
if (_glfw.egl.display == EGL_NO_DISPLAY) if (_glfw.egl.display == EGL_NO_DISPLAY)
{ {
@ -237,6 +224,8 @@ int _glfwInitContextAPI(void)
void _glfwTerminateContextAPI(void) void _glfwTerminateContextAPI(void)
{ {
eglTerminate(_glfw.egl.display); eglTerminate(_glfw.egl.display);
_glfwTerminateTLS();
} }
#define setEGLattrib(attribName, attribValue) \ #define setEGLattrib(attribName, attribValue) \
@ -482,12 +471,7 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
} }
_glfwCurrentWindow = window; _glfwSetCurrentContext(window);
}
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return _glfwCurrentWindow;
} }
void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapBuffers(_GLFWwindow* window)

View File

@ -165,6 +165,9 @@ static GLXContext createLegacyContext(_GLFWwindow* window,
// //
int _glfwInitContextAPI(void) int _glfwInitContextAPI(void)
{ {
if (!_glfwInitTLS())
return GL_FALSE;
#ifdef _GLFW_DLOPEN_LIBGL #ifdef _GLFW_DLOPEN_LIBGL
_glfw.glx.libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); _glfw.glx.libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL);
if (!_glfw.glx.libGL) if (!_glfw.glx.libGL)
@ -174,13 +177,6 @@ int _glfwInitContextAPI(void)
} }
#endif #endif
if (pthread_key_create(&_glfw.glx.current, NULL) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"GLX: Failed to create context TLS");
return GL_FALSE;
}
if (!glXQueryExtension(_glfw.x11.display, if (!glXQueryExtension(_glfw.x11.display,
&_glfw.glx.errorBase, &_glfw.glx.errorBase,
&_glfw.glx.eventBase)) &_glfw.glx.eventBase))
@ -272,7 +268,7 @@ void _glfwTerminateContextAPI(void)
} }
#endif #endif
pthread_key_delete(_glfw.glx.current); _glfwTerminateTLS();
} }
#define setGLXattrib(attribName, attribValue) \ #define setGLXattrib(attribName, attribValue) \
@ -478,12 +474,7 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
else else
glXMakeCurrent(_glfw.x11.display, None, NULL); glXMakeCurrent(_glfw.x11.display, None, NULL);
pthread_setspecific(_glfw.glx.current, window); _glfwSetCurrentContext(window);
}
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return (_GLFWwindow*) pthread_getspecific(_glfw.glx.current);
} }
void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapBuffers(_GLFWwindow* window)

View File

@ -41,8 +41,6 @@
#include <dlfcn.h> #include <dlfcn.h>
#endif #endif
#include <pthread.h>
// We support four different ways for getting addresses for GL/GLX // We support four different ways for getting addresses for GL/GLX
// extension functions: glXGetProcAddress, glXGetProcAddressARB, // extension functions: glXGetProcAddress, glXGetProcAddressARB,
// glXGetProcAddressEXT, and dlsym // glXGetProcAddressEXT, and dlsym
@ -93,9 +91,6 @@ typedef struct _GLFWlibraryGLX
int eventBase; int eventBase;
int errorBase; int errorBase;
// TLS key for per-thread current context/window
pthread_key_t current;
// GLX extensions // GLX extensions
PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI; PFNGLXSWAPINTERVALSGIPROC SwapIntervalSGI;
PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT; PFNGLXSWAPINTERVALEXTPROC SwapIntervalEXT;

View File

@ -348,6 +348,8 @@ struct _GLFWlibrary
_GLFW_PLATFORM_LIBRARY_WINDOW_STATE; _GLFW_PLATFORM_LIBRARY_WINDOW_STATE;
// This is defined in the context API's platform.h // This is defined in the context API's platform.h
_GLFW_PLATFORM_LIBRARY_OPENGL_STATE; _GLFW_PLATFORM_LIBRARY_OPENGL_STATE;
// This is defined in the platform's tls.h
_GLFW_PLATFORM_TLS_STATE;
}; };

View File

@ -26,8 +26,6 @@
#include "internal.h" #include "internal.h"
#include <pthread.h>
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
////// GLFW internal API ////// ////// GLFW internal API //////
@ -37,12 +35,8 @@
// //
int _glfwInitContextAPI(void) int _glfwInitContextAPI(void)
{ {
if (pthread_key_create(&_glfw.nsgl.current, NULL) != 0) if (!_glfwInitTLS())
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"NSGL: Failed to create context TLS");
return GL_FALSE; return GL_FALSE;
}
_glfw.nsgl.framework = _glfw.nsgl.framework =
CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
@ -60,7 +54,7 @@ int _glfwInitContextAPI(void)
// //
void _glfwTerminateContextAPI(void) void _glfwTerminateContextAPI(void)
{ {
pthread_key_delete(_glfw.nsgl.current); _glfwTerminateTLS();
} }
// Create the OpenGL context // Create the OpenGL context
@ -235,12 +229,7 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
else else
[NSOpenGLContext clearCurrentContext]; [NSOpenGLContext clearCurrentContext];
pthread_setspecific(_glfw.nsgl.current, window); _glfwSetCurrentContext(window);
}
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return (_GLFWwindow*) pthread_getspecific(_glfw.nsgl.current);
} }
void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapBuffers(_GLFWwindow* window)

View File

@ -27,7 +27,6 @@
#ifndef _nsgl_platform_h_ #ifndef _nsgl_platform_h_
#define _nsgl_platform_h_ #define _nsgl_platform_h_
#define _GLFW_PLATFORM_FBCONFIG #define _GLFW_PLATFORM_FBCONFIG
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextNSGL nsgl
#define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryNSGL nsgl #define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryNSGL nsgl
@ -55,9 +54,6 @@ typedef struct _GLFWlibraryNSGL
// dlopen handle for dynamically loading OpenGL extension entry points // dlopen handle for dynamically loading OpenGL extension entry points
void* framework; void* framework;
// TLS key for per-thread current context/window
pthread_key_t current;
} _GLFWlibraryNSGL; } _GLFWlibraryNSGL;

66
src/posix_tls.c Normal file
View File

@ -0,0 +1,66 @@
//========================================================================
// GLFW 3.1 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
int _glfwInitTLS(void)
{
if (pthread_key_create(&_glfw.posix_tls.context, NULL) != 0)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"POSIX: Failed to create context TLS");
return GL_FALSE;
}
return GL_TRUE;
}
void _glfwTerminateTLS(void)
{
pthread_key_delete(_glfw.posix_tls.context);
}
void _glfwSetCurrentContext(_GLFWwindow* context)
{
pthread_setspecific(_glfw.posix_tls.context, context);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return pthread_getspecific(_glfw.posix_tls.context);
}

55
src/posix_tls.h Normal file
View File

@ -0,0 +1,55 @@
//========================================================================
// GLFW 3.1 POSIX - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef _posix_tls_h_
#define _posix_tls_h_
#include <pthread.h>
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsPOSIX posix_tls
//========================================================================
// GLFW platform specific types
//========================================================================
typedef struct _GLFWtlsPOSIX
{
pthread_key_t context;
} _GLFWtlsPOSIX;
//========================================================================
// Prototypes for platform specific internal functions
//========================================================================
int _glfwInitTLS(void);
void _glfwTerminateTLS(void);
void _glfwSetCurrentContext(_GLFWwindow* context);
#endif // _posix_tls_h_

View File

@ -306,6 +306,9 @@ static GLboolean choosePixelFormat(_GLFWwindow* window,
// //
int _glfwInitContextAPI(void) int _glfwInitContextAPI(void)
{ {
if (!_glfwInitTLS())
return GL_FALSE;
_glfw.wgl.opengl32.instance = LoadLibraryW(L"opengl32.dll"); _glfw.wgl.opengl32.instance = LoadLibraryW(L"opengl32.dll");
if (!_glfw.wgl.opengl32.instance) if (!_glfw.wgl.opengl32.instance)
{ {
@ -313,16 +316,6 @@ int _glfwInitContextAPI(void)
return GL_FALSE; return GL_FALSE;
} }
_glfw.wgl.current = TlsAlloc();
if (_glfw.wgl.current == TLS_OUT_OF_INDEXES)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"WGL: Failed to allocate TLS index");
return GL_FALSE;
}
_glfw.wgl.hasTLS = GL_TRUE;
return GL_TRUE; return GL_TRUE;
} }
@ -330,11 +323,10 @@ int _glfwInitContextAPI(void)
// //
void _glfwTerminateContextAPI(void) void _glfwTerminateContextAPI(void)
{ {
if (_glfw.wgl.hasTLS)
TlsFree(_glfw.wgl.current);
if (_glfw.wgl.opengl32.instance) if (_glfw.wgl.opengl32.instance)
FreeLibrary(_glfw.wgl.opengl32.instance); FreeLibrary(_glfw.wgl.opengl32.instance);
_glfwTerminateTLS();
} }
#define setWGLattrib(attribName, attribValue) \ #define setWGLattrib(attribName, attribValue) \
@ -588,12 +580,7 @@ void _glfwPlatformMakeContextCurrent(_GLFWwindow* window)
else else
wglMakeCurrent(NULL, NULL); wglMakeCurrent(NULL, NULL);
TlsSetValue(_glfw.wgl.current, window); _glfwSetCurrentContext(window);
}
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return TlsGetValue(_glfw.wgl.current);
} }
void _glfwPlatformSwapBuffers(_GLFWwindow* window) void _glfwPlatformSwapBuffers(_GLFWwindow* window)

View File

@ -33,7 +33,6 @@
// extensions and not all operating systems come with an up-to-date version // extensions and not all operating systems come with an up-to-date version
#include "../deps/GL/wglext.h" #include "../deps/GL/wglext.h"
#define _GLFW_PLATFORM_FBCONFIG int wgl #define _GLFW_PLATFORM_FBCONFIG int wgl
#define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl #define _GLFW_PLATFORM_CONTEXT_STATE _GLFWcontextWGL wgl
#define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryWGL wgl #define _GLFW_PLATFORM_LIBRARY_OPENGL_STATE _GLFWlibraryWGL wgl
@ -74,9 +73,6 @@ typedef struct _GLFWcontextWGL
//------------------------------------------------------------------------ //------------------------------------------------------------------------
typedef struct _GLFWlibraryWGL typedef struct _GLFWlibraryWGL
{ {
GLboolean hasTLS;
DWORD current;
// opengl32.dll // opengl32.dll
struct { struct {
HINSTANCE instance; HINSTANCE instance;

View File

@ -151,6 +151,8 @@ typedef HRESULT (WINAPI * DWMISCOMPOSITIONENABLED_T)(BOOL*);
#define _GLFW_RECREATION_IMPOSSIBLE 2 #define _GLFW_RECREATION_IMPOSSIBLE 2
#include "win32_tls.h"
#if defined(_GLFW_WGL) #if defined(_GLFW_WGL)
#include "wgl_platform.h" #include "wgl_platform.h"
#elif defined(_GLFW_EGL) #elif defined(_GLFW_EGL)

69
src/win32_tls.c Normal file
View File

@ -0,0 +1,69 @@
//========================================================================
// GLFW 3.1 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#include "internal.h"
//////////////////////////////////////////////////////////////////////////
////// GLFW internal API //////
//////////////////////////////////////////////////////////////////////////
int _glfwInitTLS(void)
{
_glfw.win32_tls.context = TlsAlloc();
if (_glfw.win32_tls.context == TLS_OUT_OF_INDEXES)
{
_glfwInputError(GLFW_PLATFORM_ERROR,
"Win32: Failed to allocate TLS index");
return GL_FALSE;
}
_glfw.win32_tls.allocated = GL_TRUE;
return GL_TRUE;
}
void _glfwTerminateTLS(void)
{
if (_glfw.win32_tls.allocated)
TlsFree(_glfw.win32_tls.context);
}
void _glfwSetCurrentContext(_GLFWwindow* context)
{
TlsSetValue(_glfw.win32_tls.context, context);
}
//////////////////////////////////////////////////////////////////////////
////// GLFW platform API //////
//////////////////////////////////////////////////////////////////////////
_GLFWwindow* _glfwPlatformGetCurrentContext(void)
{
return TlsGetValue(_glfw.win32_tls.context);
}

54
src/win32_tls.h Normal file
View File

@ -0,0 +1,54 @@
//========================================================================
// GLFW 3.1 Win32 - www.glfw.org
//------------------------------------------------------------------------
// Copyright (c) 2002-2006 Marcus Geelnard
// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
//
// This software is provided 'as-is', without any express or implied
// warranty. In no event will the authors be held liable for any damages
// arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software
// in a product, an acknowledgment in the product documentation would
// be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
//========================================================================
#ifndef _win32_tls_h_
#define _win32_tls_h_
#define _GLFW_PLATFORM_TLS_STATE _GLFWtlsWin32 win32_tls
//========================================================================
// GLFW platform specific types
//========================================================================
typedef struct _GLFWtlsWin32
{
GLboolean allocated;
DWORD context;
} _GLFWtlsWin32;
//========================================================================
// Prototypes for platform specific internal functions
//========================================================================
int _glfwInitTLS(void);
void _glfwTerminateTLS(void);
void _glfwSetCurrentContext(_GLFWwindow* context);
#endif // _win32_tls_h_

View File

@ -48,6 +48,8 @@
// The Xkb extension provides improved keyboard support // The Xkb extension provides improved keyboard support
#include <X11/XKBlib.h> #include <X11/XKBlib.h>
#include "posix_tls.h"
#if defined(_GLFW_GLX) #if defined(_GLFW_GLX)
#define _GLFW_X11_CONTEXT_VISUAL window->glx.visual #define _GLFW_X11_CONTEXT_VISUAL window->glx.visual
#include "glx_platform.h" #include "glx_platform.h"