Mesa (master): wgl: Protect the framebuffer with a lock.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Fri Apr 10 18:50:42 UTC 2009


Module: Mesa
Branch: master
Commit: 11084d582764a916245ae92437421ac0cacdf335
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=11084d582764a916245ae92437421ac0cacdf335

Author: José Fonseca <jfonseca at vmware.com>
Date:   Fri Apr 10 19:48:59 2009 +0100

wgl: Protect the framebuffer with a lock.

Unfortunately this doesn't catch all the cases, as the mesa state tracker
can still use the framebuffer without giving the wgl state tracker
the chance to lock it.

---

 .../state_trackers/wgl/shared/stw_context.c        |    5 ++-
 .../state_trackers/wgl/shared/stw_framebuffer.c    |   42 +++++++++++++-------
 .../state_trackers/wgl/shared/stw_framebuffer.h    |   16 ++++---
 3 files changed, 41 insertions(+), 22 deletions(-)

diff --git a/src/gallium/state_trackers/wgl/shared/stw_context.c b/src/gallium/state_trackers/wgl/shared/stw_context.c
index 1e3bf10..f3c7af9 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_context.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_context.c
@@ -337,8 +337,11 @@ stw_make_current(
    }
 
    if (ctx && fb) {
+      pipe_mutex_lock( fb->mutex );
       st_make_current( ctx->st, fb->stfb, fb->stfb );
-      stw_framebuffer_resize( fb, width, height );
+      st_resize_framebuffer( fb->stfb, width, height );
+      pipe_mutex_unlock( fb->mutex );
+
       ctx->hdc = hdc;
       ctx->st->pipe->priv = hdc;
    }
diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
index e70e203..4348b8f 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
@@ -45,15 +45,6 @@
 #include "stw_tls.h"
 
 
-void
-stw_framebuffer_resize(
-   struct stw_framebuffer *fb,
-   GLuint width,
-   GLuint height )
-{
-   st_resize_framebuffer( fb->stfb, width, height );
-}
-
 /**
  * @sa http://msdn.microsoft.com/en-us/library/ms644975(VS.85).aspx
  * @sa http://msdn.microsoft.com/en-us/library/ms644960(VS.85).aspx
@@ -86,7 +77,16 @@ stw_call_window_proc(
       if(fb) {
          unsigned width = LOWORD( pParams->lParam );
          unsigned height = HIWORD( pParams->lParam );
-         stw_framebuffer_resize( fb, width, height );
+         
+         /* FIXME: The mesa statetracker makes the assumptions that only
+          * one context is using the framebuffer, and that that context is the 
+          * current one. However neither holds true, as WGL allows more than
+          * one context to be bound to the same drawable, and this function can 
+          * be called from any thread.
+          */
+         pipe_mutex_lock( fb->mutex );
+         st_resize_framebuffer( fb->stfb, width, height );
+         pipe_mutex_unlock( fb->mutex );
       }
    }
 
@@ -125,6 +125,11 @@ stw_framebuffer_create(
    if (fb == NULL)
       return NULL;
 
+   fb->hDC = hdc;
+   fb->hWnd = WindowFromDC( hdc );
+
+   pipe_mutex_init( fb->mutex );
+
    fb->stfb = st_create_framebuffer(
       visual,
       colorFormat,
@@ -133,9 +138,10 @@ stw_framebuffer_create(
       width,
       height,
       (void *) fb );
-
-   fb->hDC = hdc;
-   fb->hWnd = WindowFromDC( hdc );
+   if(!fb->stfb) {
+      FREE(fb);
+      return NULL;
+   }
 
    pipe_mutex_lock( stw_dev->mutex );
    fb->next = stw_dev->fb_head;
@@ -165,6 +171,8 @@ stw_framebuffer_destroy(
 
    st_unreference_framebuffer(fb->stfb);
    
+   pipe_mutex_destroy( fb->mutex );
+   
    FREE( fb );
 }
 
@@ -199,6 +207,8 @@ stw_swap_buffers(
    if (fb == NULL)
       return FALSE;
 
+   pipe_mutex_lock( fb->mutex );
+
    /* If we're swapping the buffer associated with the current context
     * we have to flush any pending rendering commands first.
     */
@@ -206,9 +216,11 @@ stw_swap_buffers(
 
    screen = stw_dev->screen;
    
-   if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_BACK_LEFT, &surface ))
+   if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_BACK_LEFT, &surface )) {
       /* FIXME: this shouldn't happen, but does on glean */
+      pipe_mutex_unlock( fb->mutex );
       return FALSE;
+   }
 
 #ifdef DEBUG
    if(stw_dev->trace_running) {
@@ -219,6 +231,8 @@ stw_swap_buffers(
 
    stw_dev->stw_winsys->flush_frontbuffer( screen, surface, hdc );
    
+   pipe_mutex_unlock( fb->mutex );
+   
    return TRUE;
 }
 
diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h
index 607b7f0..f5b48db 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h
+++ b/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h
@@ -28,8 +28,12 @@
 #ifndef STW_FRAMEBUFFER_H
 #define STW_FRAMEBUFFER_H
 
+#include <windows.h>
+
 #include "main/mtypes.h"
 
+#include "pipe/p_thread.h"
+
 struct stw_pixelformat_info;
 
 /**
@@ -37,9 +41,13 @@ struct stw_pixelformat_info;
  */
 struct stw_framebuffer
 {
-   struct st_framebuffer *stfb;
    HDC hDC;
    HWND hWnd;
+
+   pipe_mutex mutex;
+   struct st_framebuffer *stfb;
+   
+   /** This is protected by stw_device::mutex, not the mutex above */
    struct stw_framebuffer *next;
 };
 
@@ -55,12 +63,6 @@ void
 stw_framebuffer_destroy(
    struct stw_framebuffer *fb );
 
-void
-stw_framebuffer_resize(
-   struct stw_framebuffer *fb,
-   GLuint width,
-   GLuint height );
-
 struct stw_framebuffer *
 stw_framebuffer_from_hdc(
    HDC hdc );




More information about the mesa-commit mailing list