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).
This commit is contained in:
José Fonseca 2011-05-23 20:38:41 +01:00 committed by José Fonseca
parent 195e15559e
commit fc23cc06af
3 changed files with 22 additions and 23 deletions

View 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);
}

View 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);
}
/**

View 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 */