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 "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
|
||||||
|
|
Loading…
Reference in New Issue