wgl: mutex-protect the shared stw_icd struct

This commit is contained in:
Keith Whitwell 2009-02-10 18:11:44 +00:00
parent a88e2544ee
commit ebb864da9e
1 changed files with 141 additions and 76 deletions

View File

@ -31,6 +31,7 @@
#include "GL/gl.h" #include "GL/gl.h"
#include "pipe/p_debug.h" #include "pipe/p_debug.h"
#include "pipe/p_thread.h"
#include "shared/stw_public.h" #include "shared/stw_public.h"
#include "icd/stw_icd.h" #include "icd/stw_icd.h"
@ -41,6 +42,11 @@
struct stw_icd struct stw_icd
{ {
pipe_mutex mutex;
GLCLTPROCTABLE cpt;
boolean cpt_initialized;
struct { struct {
struct stw_context *ctx; struct stw_context *ctx;
} ctx_array[DRV_CONTEXT_MAX]; } ctx_array[DRV_CONTEXT_MAX];
@ -60,6 +66,8 @@ stw_icd_init( void )
stw_icd = &stw_icd_storage; stw_icd = &stw_icd_storage;
memset(stw_icd, 0, sizeof *stw_icd); memset(stw_icd, 0, sizeof *stw_icd);
pipe_mutex_init( stw_icd->mutex );
return TRUE; return TRUE;
} }
@ -70,24 +78,30 @@ stw_icd_cleanup(void)
if(!stw_icd) if(!stw_icd)
return; return;
pipe_mutex_lock( stw_icd->mutex );
{
/* Ensure all contexts are destroyed */
for (i = 0; i < DRV_CONTEXT_MAX; i++)
if (stw_icd->ctx_array[i].ctx)
stw_delete_context( stw_icd->ctx_array[i].ctx );
}
pipe_mutex_unlock( stw_icd->mutex );
/* Ensure all contexts are destroyed */ pipe_mutex_init( stw_icd->mutex );
for (i = 0; i < DRV_CONTEXT_MAX; i++)
if (stw_icd->ctx_array[i].ctx)
stw_delete_context( stw_icd->ctx_array[i].ctx );
stw_icd = NULL; stw_icd = NULL;
} }
static struct stw_context * static struct stw_context *
lookup_context( DHGLRC dhglrc ) lookup_context( struct stw_icd *icd,
DHGLRC dhglrc )
{ {
if (dhglrc == 0 || if (dhglrc == 0 ||
dhglrc >= DRV_CONTEXT_MAX) dhglrc >= DRV_CONTEXT_MAX)
return NULL; return NULL;
return stw_icd->ctx_array[dhglrc - 1].ctx; return icd->ctx_array[dhglrc - 1].ctx;
} }
BOOL APIENTRY BOOL APIENTRY
@ -96,14 +110,22 @@ DrvCopyContext(
DHGLRC dhrcDest, DHGLRC dhrcDest,
UINT fuMask ) UINT fuMask )
{ {
struct stw_context *src = lookup_context( dhrcSource ); BOOL ret = FALSE;
struct stw_context *dst = lookup_context( dhrcDest );
if (src == NULL ||
dst == NULL)
return FALSE;
return stw_copy_context( src, dst, fuMask ); pipe_mutex_lock( stw_icd->mutex );
{
struct stw_context *src = lookup_context( stw_icd, dhrcSource );
struct stw_context *dst = lookup_context( stw_icd, dhrcDest );
if (src == NULL || dst == NULL)
goto done;
ret = stw_copy_context( src, dst, fuMask );
}
done:
pipe_mutex_unlock( stw_icd->mutex );
return ret;
} }
DHGLRC APIENTRY DHGLRC APIENTRY
@ -111,23 +133,34 @@ DrvCreateLayerContext(
HDC hdc, HDC hdc,
INT iLayerPlane ) INT iLayerPlane )
{ {
DWORD i; DHGLRC handle = 0;;
pipe_mutex_lock( stw_icd->mutex );
{
int i;
for (i = 0; i < DRV_CONTEXT_MAX; i++) {
if (stw_icd->ctx_array[i].ctx == NULL)
break;
}
for (i = 0; i < DRV_CONTEXT_MAX; i++) { /* No slot available, fail:
if (stw_icd->ctx_array[i].ctx == NULL) */
goto found_slot; if (i == DRV_CONTEXT_MAX)
goto done;
stw_icd->ctx_array[i].ctx = stw_create_context( hdc, iLayerPlane );
if (stw_icd->ctx_array[i].ctx == NULL)
goto done;
/* success:
*/
handle = (DHGLRC) i + 1;
} }
done:
/* No slot available, fail: pipe_mutex_unlock( stw_icd->mutex );
*/
return 0;
found_slot: return handle;
stw_icd->ctx_array[i].ctx = stw_create_context( hdc, iLayerPlane );
if (stw_icd->ctx_array[i].ctx == NULL)
return 0;
return (DHGLRC) i + 1;
} }
DHGLRC APIENTRY DHGLRC APIENTRY
@ -141,20 +174,27 @@ BOOL APIENTRY
DrvDeleteContext( DrvDeleteContext(
DHGLRC dhglrc ) DHGLRC dhglrc )
{ {
struct stw_context *ctx; BOOL ret = FALSE;
ctx = lookup_context( dhglrc ); pipe_mutex_lock( stw_icd->mutex );
if (ctx == NULL) {
goto fail; struct stw_context *ctx;
if (stw_delete_context( ctx ) == FALSE) ctx = lookup_context( stw_icd, dhglrc );
goto fail; if (ctx == NULL)
goto done;
if (stw_delete_context( ctx ) == FALSE)
goto done;
stw_icd->ctx_array[dhglrc - 1].ctx = NULL;
ret = TRUE;
stw_icd->ctx_array[dhglrc - 1].ctx = NULL; }
return TRUE; done:
pipe_mutex_unlock( stw_icd->mutex );
fail: return ret;
return FALSE;
} }
BOOL APIENTRY BOOL APIENTRY
@ -228,23 +268,29 @@ BOOL APIENTRY
DrvReleaseContext( DrvReleaseContext(
DHGLRC dhglrc ) DHGLRC dhglrc )
{ {
struct stw_context *ctx; BOOL ret = FALSE;
/* XXX: The expectation is that ctx is the same context which is pipe_mutex_lock( stw_icd->mutex );
* current for this thread. We should check that and return False {
* if not the case. struct stw_context *ctx;
*/
ctx = lookup_context( dhglrc );
if (ctx == NULL)
goto fail;
if (stw_make_current( NULL, NULL ) == FALSE) /* XXX: The expectation is that ctx is the same context which is
goto fail; * current for this thread. We should check that and return False
* if not the case.
*/
ctx = lookup_context( stw_icd, dhglrc );
if (ctx == NULL)
goto done;
return TRUE; if (stw_make_current( NULL, NULL ) == FALSE)
goto done;
fail: ret = TRUE;
return FALSE; }
done:
pipe_mutex_unlock( stw_icd->mutex );
return ret;
} }
void APIENTRY void APIENTRY
@ -257,31 +303,15 @@ DrvSetCallbackProcs(
return; return;
} }
static void init_proc_table( GLCLTPROCTABLE *cpt )
{
GLDISPATCHTABLE *disp = &cpt->glDispatchTable;
memset( cpt, 0, sizeof *cpt );
cpt->cEntries = OPENGL_VERSION_110_ENTRIES;
#define GPA_GL( NAME ) disp->NAME = gl##NAME #define GPA_GL( NAME ) disp->NAME = gl##NAME
static GLCLTPROCTABLE cpt;
PGLCLTPROCTABLE APIENTRY
DrvSetContext(
HDC hdc,
DHGLRC dhglrc,
PFN_SETPROCTABLE pfnSetProcTable )
{
struct stw_context *ctx;
GLDISPATCHTABLE *disp = &cpt.glDispatchTable;
debug_printf( "%s( 0x%p, %u, 0x%p )\n", __FUNCTION__, hdc, dhglrc, pfnSetProcTable );
ctx = lookup_context( dhglrc );
if (ctx == NULL)
return NULL;
if (!stw_make_current( hdc, ctx ))
return NULL;
memset( &cpt, 0, sizeof( cpt ) );
cpt.cEntries = OPENGL_VERSION_110_ENTRIES;
GPA_GL( NewList ); GPA_GL( NewList );
GPA_GL( EndList ); GPA_GL( EndList );
GPA_GL( CallList ); GPA_GL( CallList );
@ -618,8 +648,43 @@ DrvSetContext(
GPA_GL( TexSubImage2D ); GPA_GL( TexSubImage2D );
GPA_GL( PopClientAttrib ); GPA_GL( PopClientAttrib );
GPA_GL( PushClientAttrib ); GPA_GL( PushClientAttrib );
}
return &cpt; PGLCLTPROCTABLE APIENTRY
DrvSetContext(
HDC hdc,
DHGLRC dhglrc,
PFN_SETPROCTABLE pfnSetProcTable )
{
PGLCLTPROCTABLE result = NULL;
pipe_mutex_lock( stw_icd->mutex );
{
struct stw_context *ctx;
debug_printf( "%s( 0x%p, %u, 0x%p )\n",
__FUNCTION__, hdc, dhglrc, pfnSetProcTable );
/* Although WGL allows different dispatch entrypoints per
*/
if (!stw_icd->cpt_initialized) {
init_proc_table( &stw_icd->cpt );
stw_icd->cpt_initialized = TRUE;
}
ctx = lookup_context( stw_icd, dhglrc );
if (ctx == NULL)
goto done;
if (!stw_make_current( hdc, ctx ))
goto done;
result = &stw_icd->cpt;
}
done:
pipe_mutex_unlock( stw_icd->mutex );
return result;
} }
int APIENTRY int APIENTRY