[OPENGL32]

* Use the TEB instead of TLS to store the thread curent context

svn path=/trunk/; revision=56872
This commit is contained in:
Jérôme Gardou 2012-07-12 11:39:23 +00:00
parent d9203fde02
commit 66340bca60
3 changed files with 19 additions and 64 deletions

View file

@ -20,15 +20,12 @@ static DWORD OPENGL32_RegGetDriverInfo( LPCWSTR driver, GLDRIVERDATA *icd );
/* global vars */ /* global vars */
/* Do not assume it have the free value MAXDWORD set, any value can be in here */
DWORD OPENGL32_tls = MAXDWORD;
GLPROCESSDATA OPENGL32_processdata; GLPROCESSDATA OPENGL32_processdata;
static BOOL static BOOL
OPENGL32_ThreadAttach( void ) OPENGL32_ThreadAttach( void )
{ {
GLTHREADDATA* lpData = NULL;
PROC *dispatchTable = NULL; PROC *dispatchTable = NULL;
TEB *teb = NULL; TEB *teb = NULL;
@ -41,16 +38,6 @@ OPENGL32_ThreadAttach( void )
return FALSE; return FALSE;
} }
lpData = (GLTHREADDATA*)HeapAlloc( GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY,
sizeof (GLTHREADDATA) );
if (lpData == NULL)
{
DBGPRINT( "Error: Couldn't allocate GLTHREADDATA" );
HeapFree( GetProcessHeap(), 0, dispatchTable );
return FALSE;
}
teb = NtCurrentTeb(); teb = NtCurrentTeb();
/* initialize dispatch table with empty functions */ /* initialize dispatch table with empty functions */
@ -62,7 +49,8 @@ OPENGL32_ThreadAttach( void )
#undef X #undef X
teb->glTable = dispatchTable; teb->glTable = dispatchTable;
TlsSetValue( OPENGL32_tls, lpData ); /* At first we have no context */
teb->glCurrentRC = NULL;
return TRUE; return TRUE;
} }
@ -71,21 +59,10 @@ OPENGL32_ThreadAttach( void )
static void static void
OPENGL32_ThreadDetach( void ) OPENGL32_ThreadDetach( void )
{ {
GLTHREADDATA* lpData = NULL;
TEB* teb = NtCurrentTeb(); TEB* teb = NtCurrentTeb();
rosglMakeCurrent( NULL, NULL ); rosglMakeCurrent( NULL, NULL );
lpData = (GLTHREADDATA*)TlsGetValue( OPENGL32_tls );
if (lpData != NULL)
{
if (!HeapFree( GetProcessHeap(), 0, lpData ))
DBGPRINT( "Warning: HeapFree() on GLTHREADDATA failed (%d)",
GetLastError() );
lpData = NULL;
}
TlsSetValue( OPENGL32_tls, NULL );
if (teb->glTable != NULL) if (teb->glTable != NULL)
{ {
if (!HeapFree( GetProcessHeap(), 0, teb->glTable )) if (!HeapFree( GetProcessHeap(), 0, teb->glTable ))
@ -106,10 +83,6 @@ OPENGL32_ProcessAttach( void )
NULL, /* lpSecurityDescriptor */ NULL, /* lpSecurityDescriptor */
TRUE /* bInheritHandle */ }; TRUE /* bInheritHandle */ };
OPENGL32_tls = TlsAlloc();
if (OPENGL32_tls == MAXDWORD)
return FALSE;
memset( &OPENGL32_processdata, 0, sizeof (OPENGL32_processdata) ); memset( &OPENGL32_processdata, 0, sizeof (OPENGL32_processdata) );
/* create driver, glrc & dcdata list mutex */ /* create driver, glrc & dcdata list mutex */
@ -181,10 +154,6 @@ OPENGL32_ProcessDetach( void )
CloseHandle( OPENGL32_processdata.glrc_mutex ); CloseHandle( OPENGL32_processdata.glrc_mutex );
if (OPENGL32_processdata.dcdata_mutex != NULL) if (OPENGL32_processdata.dcdata_mutex != NULL)
CloseHandle( OPENGL32_processdata.dcdata_mutex ); CloseHandle( OPENGL32_processdata.dcdata_mutex );
/* free TLS */
if (OPENGL32_tls != MAXDWORD)
TlsFree(OPENGL32_tls);
} }

View file

@ -177,15 +177,7 @@ typedef struct tagGLPROCESSDATA
HANDLE dcdata_mutex; /*!< Mutex to protect glrc list */ HANDLE dcdata_mutex; /*!< Mutex to protect glrc list */
} GLPROCESSDATA; } GLPROCESSDATA;
/* TLS data */
typedef struct tagGLTHREADDATA
{
GLRC *glrc; /*!< current GL rendering context */
} GLTHREADDATA;
extern DWORD OPENGL32_tls;
extern GLPROCESSDATA OPENGL32_processdata; extern GLPROCESSDATA OPENGL32_processdata;
#define OPENGL32_threaddata ((GLTHREADDATA *)TlsGetValue( OPENGL32_tls ))
/* function prototypes */ /* function prototypes */
GLDRIVERDATA *OPENGL32_LoadICD( LPCWSTR driver ); GLDRIVERDATA *OPENGL32_LoadICD( LPCWSTR driver );

View file

@ -871,7 +871,7 @@ HGLRC
APIENTRY APIENTRY
rosglGetCurrentContext() rosglGetCurrentContext()
{ {
return (HGLRC)(OPENGL32_threaddata->glrc); return NtCurrentTeb()->glCurrentRC;
} }
@ -884,11 +884,9 @@ HDC
APIENTRY APIENTRY
rosglGetCurrentDC() rosglGetCurrentDC()
{ {
/* FIXME: is it correct to return NULL when there is no current GLRC or GLRC* glrc = (GLRC*)NtCurrentTeb()->glCurrentRC;
is there another way to find out the wanted HDC? */ if(glrc) return glrc->hdc;
if (OPENGL32_threaddata->glrc == NULL) return NULL;
return NULL;
return (HDC)(OPENGL32_threaddata->glrc->hdc);
} }
@ -918,19 +916,18 @@ APIENTRY
rosglGetProcAddress( LPCSTR proc ) rosglGetProcAddress( LPCSTR proc )
{ {
PROC func; PROC func;
GLDRIVERDATA *icd; GLRC* glrc = (GLRC*)NtCurrentTeb()->glCurrentRC;
/* FIXME we should Flush the gl here */ /* FIXME we should Flush the gl here */
if (OPENGL32_threaddata->glrc == NULL) if (glrc == NULL)
{ {
DBGPRINT( "Error: No current GLRC!" ); DBGPRINT( "Error: No current GLRC!" );
SetLastError( ERROR_INVALID_FUNCTION ); SetLastError( ERROR_INVALID_FUNCTION );
return NULL; return NULL;
} }
icd = OPENGL32_threaddata->glrc->icd; func = glrc->icd->DrvGetProcAddress( proc );
func = icd->DrvGetProcAddress( proc );
if (func != NULL) if (func != NULL)
{ {
DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc ); DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc );
@ -947,19 +944,18 @@ APIENTRY
rosglGetDefaultProcAddress( LPCSTR proc ) rosglGetDefaultProcAddress( LPCSTR proc )
{ {
PROC func; PROC func;
GLDRIVERDATA *icd; GLRC* glrc = (GLRC*)NtCurrentTeb()->glCurrentRC;
/* wglGetDefaultProcAddress does not flush the gl */ /* wglGetDefaultProcAddress does not flush the gl */
if (OPENGL32_threaddata->glrc == NULL) if (glrc == NULL)
{ {
DBGPRINT( "Error: No current GLRC!" ); DBGPRINT( "Error: No current GLRC!" );
SetLastError( ERROR_INVALID_FUNCTION ); SetLastError( ERROR_INVALID_FUNCTION );
return NULL; return NULL;
} }
icd = OPENGL32_threaddata->glrc->icd; func = glrc->icd->DrvGetProcAddress( proc );
func = icd->DrvGetProcAddress( proc );
if (func != NULL) if (func != NULL)
{ {
DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc ); DBGPRINT( "Info: Proc \"%s\" loaded from ICD.", proc );
@ -989,9 +985,6 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
DBGTRACE( "Called!" ); DBGTRACE( "Called!" );
if (OPENGL32_threaddata == NULL)
return FALSE;
/* Is t a new context ? */ /* Is t a new context ? */
if (glrc != NULL) if (glrc != NULL)
{ {
@ -1020,9 +1013,9 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
} }
/* Unset previous one */ /* Unset previous one */
if (OPENGL32_threaddata->glrc != NULL) if (NtCurrentTeb()->glCurrentRC != NULL)
{ {
GLRC *oldglrc = OPENGL32_threaddata->glrc; GLRC *oldglrc = (GLRC*)NtCurrentTeb()->glCurrentRC;
oldglrc->is_current = FALSE; oldglrc->is_current = FALSE;
oldglrc->thread_id = 0; oldglrc->thread_id = 0;
oldglrc->hdc = NULL; oldglrc->hdc = NULL;
@ -1039,6 +1032,7 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
if (icdTable == NULL) if (icdTable == NULL)
{ {
DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() ); DBGPRINT( "Error: DrvSetContext failed (%d)\n", GetLastError() );
NtCurrentTeb()->glCurrentRC = NULL;
return FALSE; return FALSE;
} }
DBGPRINT( "Info: DrvSetContext succeeded!" ); DBGPRINT( "Info: DrvSetContext succeeded!" );
@ -1048,17 +1042,17 @@ rosglMakeCurrent( HDC hdc, HGLRC hglrc )
glrc->is_current = TRUE; glrc->is_current = TRUE;
glrc->thread_id = GetCurrentThreadId(); glrc->thread_id = GetCurrentThreadId();
glrc->hdc = hdc; glrc->hdc = hdc;
OPENGL32_threaddata->glrc = glrc; NtCurrentTeb()->glCurrentRC = (HGLRC)glrc;
} }
else if(OPENGL32_threaddata->glrc) else if(NtCurrentTeb()->glCurrentRC)
{ {
/* This is a call to unset the context */ /* This is a call to unset the context */
GLRC *oldglrc = OPENGL32_threaddata->glrc; GLRC *oldglrc = (GLRC*)NtCurrentTeb()->glCurrentRC;
oldglrc->is_current = FALSE; oldglrc->is_current = FALSE;
oldglrc->thread_id = 0; oldglrc->thread_id = 0;
oldglrc->hdc = NULL; oldglrc->hdc = NULL;
oldglrc->icd->DrvReleaseContext(oldglrc->hglrc); oldglrc->icd->DrvReleaseContext(oldglrc->hglrc);
OPENGL32_threaddata->glrc = NULL; NtCurrentTeb()->glCurrentRC = NULL;
} }
else else
{ {