[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 */
/* Do not assume it have the free value MAXDWORD set, any value can be in here */
DWORD OPENGL32_tls = MAXDWORD;
GLPROCESSDATA OPENGL32_processdata;
static BOOL
OPENGL32_ThreadAttach( void )
{
GLTHREADDATA* lpData = NULL;
PROC *dispatchTable = NULL;
TEB *teb = NULL;
@ -41,16 +38,6 @@ OPENGL32_ThreadAttach( void )
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();
/* initialize dispatch table with empty functions */
@ -62,7 +49,8 @@ OPENGL32_ThreadAttach( void )
#undef X
teb->glTable = dispatchTable;
TlsSetValue( OPENGL32_tls, lpData );
/* At first we have no context */
teb->glCurrentRC = NULL;
return TRUE;
}
@ -71,21 +59,10 @@ OPENGL32_ThreadAttach( void )
static void
OPENGL32_ThreadDetach( void )
{
GLTHREADDATA* lpData = NULL;
TEB* teb = NtCurrentTeb();
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 (!HeapFree( GetProcessHeap(), 0, teb->glTable ))
@ -106,10 +83,6 @@ OPENGL32_ProcessAttach( void )
NULL, /* lpSecurityDescriptor */
TRUE /* bInheritHandle */ };
OPENGL32_tls = TlsAlloc();
if (OPENGL32_tls == MAXDWORD)
return FALSE;
memset( &OPENGL32_processdata, 0, sizeof (OPENGL32_processdata) );
/* create driver, glrc & dcdata list mutex */
@ -181,10 +154,6 @@ OPENGL32_ProcessDetach( void )
CloseHandle( OPENGL32_processdata.glrc_mutex );
if (OPENGL32_processdata.dcdata_mutex != NULL)
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 */
} GLPROCESSDATA;
/* TLS data */
typedef struct tagGLTHREADDATA
{
GLRC *glrc; /*!< current GL rendering context */
} GLTHREADDATA;
extern DWORD OPENGL32_tls;
extern GLPROCESSDATA OPENGL32_processdata;
#define OPENGL32_threaddata ((GLTHREADDATA *)TlsGetValue( OPENGL32_tls ))
/* function prototypes */
GLDRIVERDATA *OPENGL32_LoadICD( LPCWSTR driver );

View file

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