From 115d4881839d5b2c42fdefb449b21668b4fc5b91 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 7 Sep 2012 22:04:33 +0200 Subject: [PATCH] winex11: Add helper functions to retrieve drawable information for a window or DC. --- dlls/winex11.drv/opengl.c | 175 ++++++++++++++++++-------------------- 1 file changed, 81 insertions(+), 94 deletions(-) diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index eb9cd7f291..9c1f6e5803 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1119,6 +1119,21 @@ static inline void sync_context(struct wgl_context *context) LeaveCriticalSection( &context_section ); } +static struct gl_drawable *get_gl_drawable( HWND hwnd, HDC hdc ) +{ + struct gl_drawable *gl; + + EnterCriticalSection( &context_section ); + if (hwnd && !XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl )) return gl; + if (hdc && !XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl )) return gl; + LeaveCriticalSection( &context_section ); + return NULL; +} + +static void release_gl_drawable( struct gl_drawable *gl ) +{ + if (gl) LeaveCriticalSection( &context_section ); +} static GLXContext create_glxcontext(Display *display, struct wgl_context *context, GLXContext shareList) { @@ -1305,9 +1320,7 @@ void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_r changes.width = min( max( 1, client_rect->right - client_rect->left ), 65535 ); changes.height = min( max( 1, client_rect->bottom - client_rect->top ), 65535 ); - EnterCriticalSection( &context_section ); - - if (XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl )) goto done; + if (!(gl = get_gl_drawable( hwnd, 0 ))) return; if (changes.width != gl->rect.right - gl->rect.left) mask |= CWWidth; if (changes.height != gl->rect.bottom - gl->rect.top) mask |= CWHeight; @@ -1349,7 +1362,7 @@ void sync_gl_drawable( HWND hwnd, const RECT *visible_rect, const RECT *client_r } SetRect( &gl->rect, changes.x, changes.y, changes.x + changes.width, changes.y + changes.height ); done: - LeaveCriticalSection( &context_section ); + release_gl_drawable( gl ); } /*********************************************************************** @@ -1508,20 +1521,17 @@ static int glxdrv_wglDescribePixelFormat( HDC hdc, int iPixelFormat, */ static int glxdrv_wglGetPixelFormat( HDC hdc ) { - HWND hwnd = WindowFromDC( hdc ); struct gl_drawable *gl; int ret = 0; - EnterCriticalSection( &context_section ); - if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ) || - !XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl )) + if ((gl = get_gl_drawable( WindowFromDC( hdc ), hdc ))) + { ret = gl->format - pixel_formats + 1; - LeaveCriticalSection( &context_section ); - - /* Offscreen formats can't be used with traditional WGL calls. - * As has been verified on Windows GetPixelFormat doesn't fail but returns iPixelFormat=1. */ - if (ret && !is_onscreen_pixel_format( ret )) ret = 1; - + /* Offscreen formats can't be used with traditional WGL calls. + * As has been verified on Windows GetPixelFormat doesn't fail but returns iPixelFormat=1. */ + if (!is_onscreen_pixel_format( ret )) ret = 1; + release_gl_drawable( gl ); + } TRACE( "%p -> %d\n", hdc, ret ); return ret; } @@ -1532,7 +1542,7 @@ static int glxdrv_wglGetPixelFormat( HDC hdc ) static BOOL glxdrv_wglSetPixelFormat( HDC hdc, int iPixelFormat, const PIXELFORMATDESCRIPTOR *ppfd ) { const struct wgl_pixel_format *fmt; - int value, prev = 0; + int value; struct gl_drawable *gl; HWND hwnd = WindowFromDC( hdc ); @@ -1558,12 +1568,12 @@ static BOOL glxdrv_wglSetPixelFormat( HDC hdc, int iPixelFormat, const PIXELFORM return FALSE; } - EnterCriticalSection( &context_section ); - if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl )) - prev = gl->format - pixel_formats + 1; - LeaveCriticalSection( &context_section ); - - if (prev) return prev == iPixelFormat; /* cannot change it if already set */ + if ((gl = get_gl_drawable( hwnd, hdc ))) + { + int prev = gl->format - pixel_formats + 1; + release_gl_drawable( gl ); + return prev == iPixelFormat; /* cannot change it if already set */ + } if(!SendMessageW(hwnd, WM_X11DRV_SET_WIN_FORMAT, fmt->fmt_id, 0)) { ERR("Couldn't set format of the window, returning failure\n"); @@ -1609,24 +1619,22 @@ static struct wgl_context *glxdrv_wglCreateContext( HDC hdc ) { struct wgl_context *ret = NULL; struct gl_drawable *gl; - HWND hwnd = WindowFromDC( hdc ); - EnterCriticalSection( &context_section ); + if (!(gl = get_gl_drawable( WindowFromDC( hdc ), hdc ))) + { + SetLastError( ERROR_INVALID_PIXEL_FORMAT ); + return NULL; + } - if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ) || - !XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl )) + if ((ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)))) { - if (!(ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)))) goto done; ret->hdc = hdc; ret->fmt = gl->format; ret->vis = pglXGetVisualFromFBConfig(gdi_display, gl->format->fbconfig); ret->ctx = create_glxcontext(gdi_display, ret, NULL); list_add_head( &context_list, &ret->entry ); } - else SetLastError( ERROR_INVALID_PIXEL_FORMAT ); - -done: - LeaveCriticalSection( &context_section ); + release_gl_drawable( gl ); TRACE( "%p -> %p\n", hdc, ret ); return ret; } @@ -1662,7 +1670,6 @@ static PROC glxdrv_wglGetProcAddress(LPCSTR lpszProc) static BOOL glxdrv_wglMakeCurrent(HDC hdc, struct wgl_context *ctx) { BOOL ret = FALSE; - HWND hwnd; struct gl_drawable *gl; TRACE("(%p,%p)\n", hdc, ctx); @@ -1674,11 +1681,7 @@ static BOOL glxdrv_wglMakeCurrent(HDC hdc, struct wgl_context *ctx) return TRUE; } - hwnd = WindowFromDC( hdc ); - EnterCriticalSection( &context_section ); - - if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ) || - !XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl )) + if ((gl = get_gl_drawable( WindowFromDC( hdc ), hdc ))) { if (ctx->fmt != gl->format) { @@ -1707,7 +1710,7 @@ static BOOL glxdrv_wglMakeCurrent(HDC hdc, struct wgl_context *ctx) SetLastError( ERROR_INVALID_HANDLE ); done: - LeaveCriticalSection( &context_section ); + release_gl_drawable( gl ); TRACE( "%p,%p returning %d\n", hdc, ctx, ret ); return ret; } @@ -1718,8 +1721,7 @@ done: static BOOL X11DRV_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct wgl_context *ctx ) { BOOL ret = FALSE; - HWND draw_hwnd, read_hwnd; - struct gl_drawable *draw_gl, *read_gl; + struct gl_drawable *draw_gl, *read_gl = NULL; TRACE("(%p,%p,%p)\n", draw_hdc, read_hdc, ctx); @@ -1732,17 +1734,9 @@ static BOOL X11DRV_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct if (!pglXMakeContextCurrent) return FALSE; - draw_hwnd = WindowFromDC( draw_hdc ); - read_hwnd = WindowFromDC( read_hdc ); - EnterCriticalSection( &context_section ); - - if (!XFindContext( gdi_display, (XID)draw_hwnd, gl_hwnd_context, (char **)&draw_gl ) || - !XFindContext( gdi_display, (XID)draw_hdc, gl_pbuffer_context, (char **)&draw_gl )) + if ((draw_gl = get_gl_drawable( WindowFromDC( draw_hdc ), draw_hdc ))) { - if (XFindContext( gdi_display, (XID)read_hwnd, gl_hwnd_context, (char **)&read_gl ) && - XFindContext( gdi_display, (XID)read_hdc, gl_pbuffer_context, (char **)&read_gl )) - read_gl = NULL; - + read_gl = get_gl_drawable( WindowFromDC( read_hdc ), read_hdc ); ret = pglXMakeContextCurrent(gdi_display, draw_gl->drawable, read_gl ? read_gl->drawable : 0, ctx->ctx); if (ret) @@ -1758,7 +1752,8 @@ static BOOL X11DRV_wglMakeContextCurrentARB( HDC draw_hdc, HDC read_hdc, struct } SetLastError( ERROR_INVALID_HANDLE ); done: - LeaveCriticalSection( &context_section ); + release_gl_drawable( read_gl ); + release_gl_drawable( draw_gl ); TRACE( "%p,%p,%p returning %d\n", draw_hdc, read_hdc, ctx, ret ); return ret; } @@ -1866,16 +1861,17 @@ static struct wgl_context *X11DRV_wglCreateContextAttribsARB( HDC hdc, struct wg { struct wgl_context *ret = NULL; struct gl_drawable *gl; - HWND hwnd = WindowFromDC( hdc ); TRACE("(%p %p %p)\n", hdc, hShareContext, attribList); - EnterCriticalSection( &context_section ); + if (!(gl = get_gl_drawable( WindowFromDC( hdc ), hdc ))) + { + SetLastError( ERROR_INVALID_PIXEL_FORMAT ); + return NULL; + } - if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ) || - !XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl )) + if ((ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)))) { - if (!(ret = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ret)))) goto done; ret->hdc = hdc; ret->fmt = gl->format; ret->vis = NULL; /* glXCreateContextAttribsARB requires a fbconfig instead of a visual */ @@ -1920,20 +1916,17 @@ static struct wgl_context *X11DRV_wglCreateContextAttribsARB( HDC hdc, struct wg X11DRV_expect_error(gdi_display, GLXErrorHandler, NULL); ret->ctx = create_glxcontext(gdi_display, ret, NULL); XSync(gdi_display, False); - if (!X11DRV_check_error() && ret->ctx) + if (X11DRV_check_error() || !ret->ctx) { - list_add_head( &context_list, &ret->entry ); - goto done; + /* In the future we should convert the GLX error to a win32 one here if needed */ + ERR("Context creation failed\n"); + HeapFree( GetProcessHeap(), 0, ret ); + ret = NULL; } - /* In the future we should convert the GLX error to a win32 one here if needed */ - ERR("Context creation failed\n"); - HeapFree( GetProcessHeap(), 0, ret ); - ret = NULL; + else list_add_head( &context_list, &ret->entry ); } - else SetLastError( ERROR_INVALID_PIXEL_FORMAT ); -done: - LeaveCriticalSection( &context_section ); + release_gl_drawable( gl ); TRACE( "%p -> %p\n", hdc, ret ); return ret; } @@ -3030,43 +3023,39 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc ) enum x11drv_escape_codes code = X11DRV_FLUSH_GL_DRAWABLE; struct gl_drawable *gl; struct wgl_context *ctx = NtCurrentTeb()->glContext; - HWND hwnd = WindowFromDC( hdc ); - BOOL ret = FALSE; TRACE("(%p)\n", hdc); - EnterCriticalSection( &context_section ); + if (!(gl = get_gl_drawable( WindowFromDC( hdc ), hdc ))) + { + SetLastError( ERROR_INVALID_HANDLE ); + return FALSE; + } - if (!XFindContext( gdi_display, (XID)hwnd, gl_hwnd_context, (char **)&gl ) || - !XFindContext( gdi_display, (XID)hdc, gl_pbuffer_context, (char **)&gl )) + switch (gl->type) { - switch (gl->type) - { - case DC_GL_PIXMAP_WIN: - if (ctx) sync_context( ctx ); - if (pglXCopySubBufferMESA) { - /* (glX)SwapBuffers has an implicit glFlush effect, however - * GLX_MESA_copy_sub_buffer doesn't. Make sure GL is flushed before - * copying */ - pglFlush(); - pglXCopySubBufferMESA( gdi_display, gl->drawable, 0, 0, - gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top ); - break; - } - /* fall through */ - default: - pglXSwapBuffers(gdi_display, gl->drawable); + case DC_GL_PIXMAP_WIN: + if (ctx) sync_context( ctx ); + if (pglXCopySubBufferMESA) { + /* (glX)SwapBuffers has an implicit glFlush effect, however + * GLX_MESA_copy_sub_buffer doesn't. Make sure GL is flushed before + * copying */ + pglFlush(); + pglXCopySubBufferMESA( gdi_display, gl->drawable, 0, 0, + gl->rect.right - gl->rect.left, gl->rect.bottom - gl->rect.top ); break; } - ret = TRUE; + /* fall through */ + default: + pglXSwapBuffers(gdi_display, gl->drawable); + break; } - else SetLastError( ERROR_INVALID_HANDLE ); - LeaveCriticalSection( &context_section ); + release_gl_drawable( gl ); ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL ); - return ret; + return TRUE; } static BOOL create_glx_dc( PHYSDEV *pdev ) @@ -3134,14 +3123,13 @@ static INT glxdrv_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_d struct gl_drawable *gl; const struct x11drv_escape_set_drawable *data = in_data; - EnterCriticalSection( &context_section ); - if (!XFindContext( gdi_display, (XID)data->hwnd, gl_hwnd_context, (char **)&gl ) || - !XFindContext( gdi_display, (XID)dev->hdc, gl_pbuffer_context, (char **)&gl )) + if ((gl = get_gl_drawable( data->hwnd, dev->hdc ))) { physdev->format = gl->format; physdev->type = gl->type; physdev->drawable = gl->drawable; physdev->pixmap = gl->pixmap; + release_gl_drawable( gl ); } else { @@ -3150,7 +3138,6 @@ static INT glxdrv_ExtEscape( PHYSDEV dev, INT escape, INT in_count, LPCVOID in_d physdev->drawable = 0; physdev->pixmap = 0; } - LeaveCriticalSection( &context_section ); TRACE( "SET_DRAWABLE hdc %p drawable %lx pf %p type %u\n", dev->hdc, physdev->drawable, physdev->format, physdev->type ); } -- 2.32.0.93.g670b81a890