diff options
Diffstat (limited to 'src/gallium/state_trackers')
| -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 8fa9f4e667..e4f3c669e2 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; -    -   for (i = 0; i < DRV_CONTEXT_MAX; i++) { -      if (stw_icd->ctx_array[i].ctx == NULL) -         goto found_slot; -   } +   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; +      } -   /* No slot available, fail: -    */ -   return 0; +      /* No slot available, fail: +       */ +      if (i == DRV_CONTEXT_MAX) +         goto done; -found_slot: -   stw_icd->ctx_array[i].ctx = stw_create_context( hdc, iLayerPlane ); -   if (stw_icd->ctx_array[i].ctx == NULL) -      return 0; +      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: +   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; +static void init_proc_table( GLCLTPROCTABLE *cpt ) +{  +   GLDISPATCHTABLE *disp = &cpt->glDispatchTable; -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; - -   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 | 
