diff options
-rw-r--r-- | src/gallium/state_trackers/wgl/icd/stw_icd.c | 213 |
1 files changed, 138 insertions, 75 deletions
diff --git a/src/gallium/state_trackers/wgl/icd/stw_icd.c b/src/gallium/state_trackers/wgl/icd/stw_icd.c index 8fa9f4e667f..e4f3c669e20 100644 --- a/src/gallium/state_trackers/wgl/icd/stw_icd.c +++ b/src/gallium/state_trackers/wgl/icd/stw_icd.c @@ -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,11 +42,14 @@ struct stw_icd { + pipe_mutex mutex; + + GLCLTPROCTABLE cpt; + boolean cpt_initialized; + struct { struct stw_context *ctx; } ctx_array[DRV_CONTEXT_MAX]; - - DHGLRC ctx_current; }; @@ -62,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; } @@ -72,27 +78,33 @@ 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; - if(!stw_icd) + if (icd == NULL) return NULL; - return stw_icd->ctx_array[dhglrc - 1].ctx; + return icd->ctx_array[dhglrc - 1].ctx; } BOOL APIENTRY @@ -101,14 +113,22 @@ DrvCopyContext( DHGLRC dhrcDest, UINT fuMask ) { - struct stw_context *src = lookup_context( dhrcSource ); - struct stw_context *dst = lookup_context( dhrcDest ); + BOOL ret = FALSE; + + 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) - return FALSE; + if (src == NULL || dst == NULL) + goto done; + + ret = stw_copy_context( src, dst, fuMask ); + } +done: + pipe_mutex_unlock( stw_icd->mutex ); - return stw_copy_context( src, dst, fuMask ); + return ret; } DHGLRC APIENTRY @@ -116,23 +136,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; - -found_slot: - stw_icd->ctx_array[i].ctx = stw_create_context( hdc, iLayerPlane ); - if (stw_icd->ctx_array[i].ctx == NULL) - return 0; +done: + pipe_mutex_unlock( stw_icd->mutex ); - return (DHGLRC) i + 1; + return handle; } DHGLRC APIENTRY @@ -146,20 +177,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 @@ -233,23 +271,29 @@ BOOL APIENTRY DrvReleaseContext( DHGLRC dhglrc ) { - struct stw_context *ctx; + BOOL ret = FALSE; - if (dhglrc != stw_icd->ctx_current) - goto fail; + pipe_mutex_lock( stw_icd->mutex ); + { + struct stw_context *ctx; - ctx = lookup_context( dhglrc ); - if (ctx == NULL) - 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; - if (stw_make_current( NULL, NULL ) == FALSE) - goto fail; + if (stw_make_current( NULL, NULL ) == FALSE) + goto done; - stw_icd->ctx_current = 0; - return TRUE; + ret = TRUE; + } +done: + pipe_mutex_unlock( stw_icd->mutex ); -fail: - return FALSE; + return ret; } void APIENTRY @@ -262,31 +306,15 @@ DrvSetCallbackProcs( return; } -#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( %p, %u, %p )\n", __FUNCTION__, hdc, dhglrc, pfnSetProcTable ); - ctx = lookup_context( dhglrc ); - if (ctx == NULL) - return NULL; - - if (!stw_make_current( hdc, ctx )) - return NULL; +static void init_proc_table( GLCLTPROCTABLE *cpt ) +{ + GLDISPATCHTABLE *disp = &cpt->glDispatchTable; - memset( &cpt, 0, sizeof( cpt ) ); - cpt.cEntries = OPENGL_VERSION_110_ENTRIES; + memset( cpt, 0, sizeof *cpt ); + cpt->cEntries = OPENGL_VERSION_110_ENTRIES; +#define GPA_GL( NAME ) disp->NAME = gl##NAME GPA_GL( NewList ); GPA_GL( EndList ); GPA_GL( CallList ); @@ -623,8 +651,43 @@ DrvSetContext( GPA_GL( TexSubImage2D ); GPA_GL( PopClientAttrib ); GPA_GL( PushClientAttrib ); +} + +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 &cpt; + return result; } int APIENTRY |