winex11: Pass the source drawable to the FLUSH_GL_DRAWABLE escape.

This commit is contained in:
Alexandre Julliard 2012-10-02 21:50:54 +02:00
parent ea15163973
commit d8de77f01e
2 changed files with 66 additions and 31 deletions

View File

@ -1107,7 +1107,6 @@ static void mark_drawable_dirty(Drawable old, Drawable new)
/* Given the current context, make sure its drawable is sync'd */ /* Given the current context, make sure its drawable is sync'd */
static inline void sync_context(struct wgl_context *context) static inline void sync_context(struct wgl_context *context)
{ {
EnterCriticalSection( &context_section );
if (context->refresh_drawables) { if (context->refresh_drawables) {
if (glxRequireVersion(3)) if (glxRequireVersion(3))
pglXMakeContextCurrent(gdi_display, context->drawables[0], pglXMakeContextCurrent(gdi_display, context->drawables[0],
@ -1116,7 +1115,6 @@ static inline void sync_context(struct wgl_context *context)
pglXMakeCurrent(gdi_display, context->drawables[0], context->ctx); pglXMakeCurrent(gdi_display, context->drawables[0], context->ctx);
context->refresh_drawables = FALSE; context->refresh_drawables = FALSE;
} }
LeaveCriticalSection( &context_section );
} }
static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc ) static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc )
@ -1818,21 +1816,14 @@ static BOOL glxdrv_wglShareLists(struct wgl_context *org, struct wgl_context *de
return FALSE; return FALSE;
} }
static void flush_gl_drawable( struct glx_physdev *physdev ) static void flush_gl_drawable( struct glx_physdev *physdev, Drawable src )
{ {
RECT rect; RECT rect;
int w = physdev->x11dev->dc_rect.right - physdev->x11dev->dc_rect.left; int w = physdev->x11dev->dc_rect.right - physdev->x11dev->dc_rect.left;
int h = physdev->x11dev->dc_rect.bottom - physdev->x11dev->dc_rect.top; int h = physdev->x11dev->dc_rect.bottom - physdev->x11dev->dc_rect.top;
Drawable src = physdev->drawable;
if (w <= 0 || h <= 0) return; if (w <= 0 || h <= 0) return;
switch (physdev->type)
{
case DC_GL_PIXMAP_WIN:
src = physdev->pixmap;
/* fall through */
case DC_GL_CHILD_WIN:
/* The GL drawable may be lagged behind if we don't flush first, so /* The GL drawable may be lagged behind if we don't flush first, so
* flush the display make sure we copy up-to-date data */ * flush the display make sure we copy up-to-date data */
XFlush(gdi_display); XFlush(gdi_display);
@ -1841,30 +1832,57 @@ static void flush_gl_drawable( struct glx_physdev *physdev )
physdev->x11dev->dc_rect.left, physdev->x11dev->dc_rect.top); physdev->x11dev->dc_rect.left, physdev->x11dev->dc_rect.top);
SetRect( &rect, 0, 0, w, h ); SetRect( &rect, 0, 0, w, h );
add_device_bounds( physdev->x11dev, &rect ); add_device_bounds( physdev->x11dev, &rect );
default:
break;
}
} }
static void wglFinish(void) static void wglFinish(void)
{ {
struct x11drv_escape_flush_gl_drawable escape;
struct gl_drawable *gl;
struct wgl_context *ctx = NtCurrentTeb()->glContext; struct wgl_context *ctx = NtCurrentTeb()->glContext;
enum x11drv_escape_codes code = X11DRV_FLUSH_GL_DRAWABLE;
escape.code = X11DRV_FLUSH_GL_DRAWABLE;
escape.gl_drawable = 0;
if ((gl = get_gl_drawable( WindowFromDC( ctx->hdc ), 0 )))
{
switch (gl->type)
{
case DC_GL_PIXMAP_WIN: escape.gl_drawable = gl->pixmap; break;
case DC_GL_CHILD_WIN: escape.gl_drawable = gl->drawable; break;
default: break;
}
sync_context(ctx); sync_context(ctx);
release_gl_drawable( gl );
}
pglFinish(); pglFinish();
ExtEscape( ctx->hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL ); if (escape.gl_drawable) ExtEscape( ctx->hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
} }
static void wglFlush(void) static void wglFlush(void)
{ {
struct x11drv_escape_flush_gl_drawable escape;
struct gl_drawable *gl;
struct wgl_context *ctx = NtCurrentTeb()->glContext; struct wgl_context *ctx = NtCurrentTeb()->glContext;
enum x11drv_escape_codes code = X11DRV_FLUSH_GL_DRAWABLE;
escape.code = X11DRV_FLUSH_GL_DRAWABLE;
escape.gl_drawable = 0;
if ((gl = get_gl_drawable( WindowFromDC( ctx->hdc ), 0 )))
{
switch (gl->type)
{
case DC_GL_PIXMAP_WIN: escape.gl_drawable = gl->pixmap; break;
case DC_GL_CHILD_WIN: escape.gl_drawable = gl->drawable; break;
default: break;
}
sync_context(ctx); sync_context(ctx);
release_gl_drawable( gl );
}
pglFlush(); pglFlush();
ExtEscape( ctx->hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL ); if (escape.gl_drawable) ExtEscape( ctx->hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
} }
/*********************************************************************** /***********************************************************************
@ -3034,12 +3052,15 @@ static void X11DRV_WineGL_LoadExtensions(void)
*/ */
static BOOL glxdrv_wglSwapBuffers( HDC hdc ) static BOOL glxdrv_wglSwapBuffers( HDC hdc )
{ {
enum x11drv_escape_codes code = X11DRV_FLUSH_GL_DRAWABLE; struct x11drv_escape_flush_gl_drawable escape;
struct gl_drawable *gl; struct gl_drawable *gl;
struct wgl_context *ctx = NtCurrentTeb()->glContext; struct wgl_context *ctx = NtCurrentTeb()->glContext;
TRACE("(%p)\n", hdc); TRACE("(%p)\n", hdc);
escape.code = X11DRV_FLUSH_GL_DRAWABLE;
escape.gl_drawable = 0;
if (!(gl = get_gl_drawable( WindowFromDC( hdc ), hdc ))) if (!(gl = get_gl_drawable( WindowFromDC( hdc ), hdc )))
{ {
SetLastError( ERROR_INVALID_HANDLE ); SetLastError( ERROR_INVALID_HANDLE );
@ -3050,6 +3071,7 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
{ {
case DC_GL_PIXMAP_WIN: case DC_GL_PIXMAP_WIN:
if (ctx) sync_context( ctx ); if (ctx) sync_context( ctx );
escape.gl_drawable = gl->pixmap;
if (pglXCopySubBufferMESA) { if (pglXCopySubBufferMESA) {
/* (glX)SwapBuffers has an implicit glFlush effect, however /* (glX)SwapBuffers has an implicit glFlush effect, however
* GLX_MESA_copy_sub_buffer doesn't. Make sure GL is flushed before * GLX_MESA_copy_sub_buffer doesn't. Make sure GL is flushed before
@ -3059,6 +3081,10 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top ); gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top );
break; break;
} }
pglXSwapBuffers(gdi_display, gl->drawable);
break;
case DC_GL_CHILD_WIN:
escape.gl_drawable = gl->drawable;
/* fall through */ /* fall through */
default: default:
pglXSwapBuffers(gdi_display, gl->drawable); pglXSwapBuffers(gdi_display, gl->drawable);
@ -3067,8 +3093,7 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
release_gl_drawable( gl ); release_gl_drawable( gl );
ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL ); if (escape.gl_drawable) ExtEscape( ctx->hdc, X11DRV_ESCAPE, sizeof(escape), (LPSTR)&escape, 0, NULL );
return TRUE; return TRUE;
} }
@ -3165,7 +3190,11 @@ static INT glxdrv_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_d
} }
break; break;
case X11DRV_FLUSH_GL_DRAWABLE: case X11DRV_FLUSH_GL_DRAWABLE:
flush_gl_drawable( physdev ); if (in_count >= sizeof(struct x11drv_escape_flush_gl_drawable))
{
const struct x11drv_escape_flush_gl_drawable *data = in_data;
flush_gl_drawable( physdev, data->gl_drawable );
}
return TRUE; return TRUE;
default: default:
break; break;

View File

@ -291,6 +291,12 @@ struct x11drv_escape_get_drawable
int pixel_format; /* internal GL pixel format */ int pixel_format; /* internal GL pixel format */
}; };
struct x11drv_escape_flush_gl_drawable
{
enum x11drv_escape_codes code; /* escape code (X11DRV_FLUSH_GL_DRAWABLE) */
Drawable gl_drawable; /* GL drawable */
};
/************************************************************************** /**************************************************************************
* X11 USER driver * X11 USER driver
*/ */