wgl: Don't hold on to user supplied HDC.
authorJosé Fonseca <jfonseca@vmware.com>
Mon, 23 May 2011 19:38:41 +0000 (20:38 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Tue, 24 May 2011 12:12:39 +0000 (13:12 +0100)
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
src/gallium/state_trackers/wgl/stw_st.c
src/gallium/state_trackers/wgl/stw_st.h

index 7a689f9977d2c8e4d3d762945809e188d7bc6a4d..f595efe03f49f57ef505ee3e42e7bc8ebf5c6739 100644 (file)
@@ -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);
 }
 
 
index b58d91673b7867dfe483e961cd2a1508122c8494..9174533fc06d8ba7943c6322086618ee3431e9bd 100644 (file)
@@ -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);
 }
 
 /**
index 23771d8bef606870b6b472a3e465719db466023e..945d3508b48905574b61f7be237fb7760054f0cd 100644 (file)
@@ -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 */