wgl: mutex-protect the shared stw_icd struct
This commit is contained in:
parent
a88e2544ee
commit
ebb864da9e
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue