Mesa (7.10): wgl: Don't hold on to user supplied HDC.

Jose Fonseca jrfonseca at kemper.freedesktop.org
Sun Jun 12 08:25:02 UTC 2011


Module: Mesa
Branch: 7.10
Commit: fc23cc06af90b5945de2c1f5e045b2b93f5ee70b
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=fc23cc06af90b5945de2c1f5e045b2b93f5ee70b

Author: José Fonseca <jfonseca at vmware.com>
Date:   Mon May 23 20:38:41 2011 +0100

wgl: Don't hold on to user supplied HDC.

Certain applications (e.g., Bernina My Label, and the Windows
implementation of Processing language) destroy the device context used when
creating the frame-buffer, causing presents to fail because we were still
referring to the old device context internally.

This change ensures we always use the same HDC passed to the ICD
entry-points when available, or our own HDC when not available (necessary
only when flushing on single buffered visuals).

---

 src/gallium/state_trackers/wgl/stw_framebuffer.c |   30 +++++++++------------
 src/gallium/state_trackers/wgl/stw_st.c          |   11 ++++---
 src/gallium/state_trackers/wgl/stw_st.h          |    4 ++-
 3 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index 7a689f9..f595efe 100644
--- a/src/gallium/state_trackers/wgl/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -92,6 +92,8 @@ stw_framebuffer_destroy_locked(
 
    stw_st_destroy_framebuffer_locked(fb->stfb);
    
+   ReleaseDC(fb->hWnd, fb->hDC);
+
    pipe_mutex_unlock( fb->mutex );
 
    pipe_mutex_destroy( fb->mutex );
@@ -168,6 +170,7 @@ stw_framebuffer_get_size( struct stw_framebuffer *fb )
 
 #if 0
    debug_printf("\n");
+   debug_printf("%s: hwnd = %p\n", __FUNCTION__, fb->hWnd);
    debug_printf("%s: client_position = (%li, %li)\n",
                 __FUNCTION__, client_pos.x, client_pos.y);
    debug_printf("%s: window_rect = (%li, %li) - (%li, %li)\n",
@@ -251,7 +254,11 @@ stw_framebuffer_create(
    if (fb == NULL)
       return NULL;
 
-   fb->hDC = hdc;
+   /* Applications use, create, destroy device contexts, so the hdc passed is.  We create our own DC
+    * because we need one for single buffered visuals.
+    */
+   fb->hDC = GetDC(hWnd);
+
    fb->hWnd = hWnd;
    fb->iPixelFormat = iPixelFormat;
 
@@ -378,24 +385,13 @@ stw_framebuffer_from_hdc_locked(
    HDC hdc )
 {
    HWND hwnd;
-   struct stw_framebuffer *fb;
 
-   /* 
-    * Some applications create and use several HDCs for the same window, so 
-    * looking up the framebuffer by the HDC is not reliable. Use HWND whenever
-    * possible.
-    */ 
    hwnd = WindowFromDC(hdc);
-   if(hwnd)
-      return stw_framebuffer_from_hwnd_locked(hwnd);
-   
-   for (fb = stw_dev->fb_head; fb != NULL; fb = fb->next)
-      if (fb->hDC == hdc) {
-         pipe_mutex_lock(fb->mutex);
-         break;
-      }
+   if (!hwnd) {
+      return NULL;
+   }
 
-   return fb;
+   return stw_framebuffer_from_hwnd_locked(hwnd);
 }
 
 
@@ -607,7 +603,7 @@ DrvSwapBuffers(
 
    stw_flush_current_locked(fb);
 
-   return stw_st_swap_framebuffer_locked(fb->stfb);
+   return stw_st_swap_framebuffer_locked(hdc, fb->stfb);
 }
 
 
diff --git a/src/gallium/state_trackers/wgl/stw_st.c b/src/gallium/state_trackers/wgl/stw_st.c
index b58d916..9174533 100644
--- a/src/gallium/state_trackers/wgl/stw_st.c
+++ b/src/gallium/state_trackers/wgl/stw_st.c
@@ -154,7 +154,8 @@ stw_st_framebuffer_validate(struct st_framebuffer_iface *stfb,
  * Present an attachment of the framebuffer.
  */
 static boolean
-stw_st_framebuffer_present_locked(struct st_framebuffer_iface *stfb,
+stw_st_framebuffer_present_locked(HDC hdc,
+                                  struct st_framebuffer_iface *stfb,
                                   enum st_attachment_type statt)
 {
    struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
@@ -162,7 +163,7 @@ stw_st_framebuffer_present_locked(struct st_framebuffer_iface *stfb,
 
    resource = stwfb->textures[statt];
    if (resource) {
-      stw_framebuffer_present_locked(stwfb->fb->hDC, stwfb->fb, resource);
+      stw_framebuffer_present_locked(hdc, stwfb->fb, resource);
    }
 
    return TRUE;
@@ -176,7 +177,7 @@ stw_st_framebuffer_flush_front(struct st_framebuffer_iface *stfb,
 
    pipe_mutex_lock(stwfb->fb->mutex);
 
-   return stw_st_framebuffer_present_locked(&stwfb->base, statt);
+   return stw_st_framebuffer_present_locked(stwfb->fb->hDC, &stwfb->base, statt);
 }
 
 /**
@@ -220,7 +221,7 @@ stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface *stfb)
  * Swap the buffers of the given framebuffer.
  */
 boolean
-stw_st_swap_framebuffer_locked(struct st_framebuffer_iface *stfb)
+stw_st_swap_framebuffer_locked(HDC hdc, struct st_framebuffer_iface *stfb)
 {
    struct stw_st_framebuffer *stwfb = stw_st_framebuffer(stfb);
    unsigned front = ST_ATTACHMENT_FRONT_LEFT, back = ST_ATTACHMENT_BACK_LEFT;
@@ -245,7 +246,7 @@ stw_st_swap_framebuffer_locked(struct st_framebuffer_iface *stfb)
    stwfb->texture_mask = mask;
 
    front = ST_ATTACHMENT_FRONT_LEFT;
-   return stw_st_framebuffer_present_locked(&stwfb->base, front);
+   return stw_st_framebuffer_present_locked(hdc, &stwfb->base, front);
 }
 
 /**
diff --git a/src/gallium/state_trackers/wgl/stw_st.h b/src/gallium/state_trackers/wgl/stw_st.h
index 23771d8..945d350 100644
--- a/src/gallium/state_trackers/wgl/stw_st.h
+++ b/src/gallium/state_trackers/wgl/stw_st.h
@@ -28,6 +28,8 @@
 #ifndef STW_ST_H
 #define STW_ST_H
 
+#include <windows.h>
+
 #include "state_tracker/st_api.h"
 
 struct stw_framebuffer;
@@ -42,6 +44,6 @@ void
 stw_st_destroy_framebuffer_locked(struct st_framebuffer_iface *stfb);
 
 boolean
-stw_st_swap_framebuffer_locked(struct st_framebuffer_iface *stfb);
+stw_st_swap_framebuffer_locked(HDC hdc, struct st_framebuffer_iface *stfb);
 
 #endif /* STW_ST_H */




More information about the mesa-commit mailing list