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 "pipe/p_debug.h"
#include "pipe/p_thread.h"
#include "shared/stw_public.h"
#include "icd/stw_icd.h"
@ -41,6 +42,11 @@
struct stw_icd
{
pipe_mutex mutex;
GLCLTPROCTABLE cpt;
boolean cpt_initialized;
struct {
struct stw_context *ctx;
} ctx_array[DRV_CONTEXT_MAX];
@ -60,6 +66,8 @@ stw_icd_init( void )
stw_icd = &stw_icd_storage;
memset(stw_icd, 0, sizeof *stw_icd);
pipe_mutex_init( stw_icd->mutex );
return TRUE;
}
@ -70,24 +78,30 @@ stw_icd_cleanup(void)
if(!stw_icd)
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 */
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_init( stw_icd->mutex );
stw_icd = NULL;
}
static struct stw_context *
lookup_context( DHGLRC dhglrc )
lookup_context( struct stw_icd *icd,
DHGLRC dhglrc )
{
if (dhglrc == 0 ||
dhglrc >= DRV_CONTEXT_MAX)
return NULL;
return stw_icd->ctx_array[dhglrc - 1].ctx;
return icd->ctx_array[dhglrc - 1].ctx;
}
BOOL APIENTRY
@ -96,14 +110,22 @@ DrvCopyContext(
DHGLRC dhrcDest,
UINT fuMask )
{
struct stw_context *src = lookup_context( dhrcSource );
struct stw_context *dst = lookup_context( dhrcDest );
if (src == NULL ||
dst == NULL)
return FALSE;
BOOL ret = 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
@ -111,23 +133,34 @@ DrvCreateLayerContext(
HDC hdc,
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++) {
if (stw_icd->ctx_array[i].ctx == NULL)
goto found_slot;
/* No slot available, fail:
*/
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;
}
/* No slot available, fail:
*/
return 0;
done:
pipe_mutex_unlock( stw_icd->mutex );
found_slot:
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;
return handle;
}
DHGLRC APIENTRY
@ -141,20 +174,27 @@ BOOL APIENTRY
DrvDeleteContext(
DHGLRC dhglrc )
{
struct stw_context *ctx;
BOOL ret = FALSE;
ctx = lookup_context( dhglrc );
if (ctx == NULL)
goto fail;
pipe_mutex_lock( stw_icd->mutex );
{
struct stw_context *ctx;
if (stw_delete_context( ctx ) == FALSE)
goto fail;
ctx = lookup_context( stw_icd, dhglrc );
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 FALSE;
return ret;
}
BOOL APIENTRY
@ -228,23 +268,29 @@ BOOL APIENTRY
DrvReleaseContext(
DHGLRC dhglrc )
{
struct stw_context *ctx;
BOOL ret = FALSE;
/* XXX: The expectation is that ctx is the same context which is
* current for this thread. We should check that and return False
* if not the case.
*/
ctx = lookup_context( dhglrc );
if (ctx == NULL)
goto fail;
pipe_mutex_lock( stw_icd->mutex );
{
struct stw_context *ctx;
if (stw_make_current( NULL, NULL ) == FALSE)
goto fail;
/* XXX: The expectation is that ctx is the same context which is
* 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:
return FALSE;
ret = TRUE;
}
done:
pipe_mutex_unlock( stw_icd->mutex );
return ret;
}
void APIENTRY
@ -257,31 +303,15 @@ DrvSetCallbackProcs(
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
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( EndList );
GPA_GL( CallList );
@ -618,8 +648,43 @@ DrvSetContext(
GPA_GL( TexSubImage2D );
GPA_GL( PopClientAttrib );
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