winex11.drv: Recreate gl_drawable for top-level windows as non-top level when clipping for child windows is required.

Prevent creating a gl_drawable for a window as type DC_GL_WINDOW if
there are known children of the window, since DC_GL_WINDOW does not
support clipping.

Recreate a gl_drawable that was previously create as type DC_GL_WINDOW
when a child is encountered.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=15232
Signed-off-by: Micah N Gorrell <mgorrell@codeweavers.com>
Signed-off-by: Ken Thomases <ken@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Micah N Gorrell 2019-04-10 13:04:18 -06:00 committed by Alexandre Julliard
parent 04ccd995b1
commit 0cb79db12a
3 changed files with 25 additions and 10 deletions

View File

@ -1328,7 +1328,7 @@ static GLXContext create_glxcontext(Display *display, struct wgl_context *contex
/*********************************************************************** /***********************************************************************
* create_gl_drawable * create_gl_drawable
*/ */
static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct wgl_pixel_format *format ) static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct wgl_pixel_format *format, BOOL known_child )
{ {
struct gl_drawable *gl, *prev; struct gl_drawable *gl, *prev;
XVisualInfo *visual = format->visual; XVisualInfo *visual = format->visual;
@ -1349,7 +1349,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct wgl_pixel
gl->format = format; gl->format = format;
gl->ref = 1; gl->ref = 1;
if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) /* top-level window */ if (!known_child && !GetWindow( hwnd, GW_CHILD ) && GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) /* childless top-level window */
{ {
gl->type = DC_GL_WINDOW; gl->type = DC_GL_WINDOW;
gl->window = create_client_window( hwnd, visual ); gl->window = create_client_window( hwnd, visual );
@ -1412,7 +1412,7 @@ static BOOL set_win_format( HWND hwnd, const struct wgl_pixel_format *format )
if (!format->visual) return FALSE; if (!format->visual) return FALSE;
if (!(gl = create_gl_drawable( hwnd, format ))) return FALSE; if (!(gl = create_gl_drawable( hwnd, format, FALSE ))) return FALSE;
TRACE( "created GL drawable %lx for win %p %s\n", TRACE( "created GL drawable %lx for win %p %s\n",
gl->drawable, hwnd, debugstr_fbconfig( format->fbconfig )); gl->drawable, hwnd, debugstr_fbconfig( format->fbconfig ));
@ -1471,7 +1471,7 @@ static BOOL set_pixel_format(HDC hdc, int format, BOOL allow_change)
/*********************************************************************** /***********************************************************************
* sync_gl_drawable * sync_gl_drawable
*/ */
void sync_gl_drawable( HWND hwnd ) void sync_gl_drawable( HWND hwnd, BOOL known_child )
{ {
struct gl_drawable *old, *new; struct gl_drawable *old, *new;
@ -1479,8 +1479,11 @@ void sync_gl_drawable( HWND hwnd )
switch (old->type) switch (old->type)
{ {
case DC_GL_WINDOW:
if (!known_child) break; /* Still a childless top-level window */
/* fall through */
case DC_GL_PIXMAP_WIN: case DC_GL_PIXMAP_WIN:
if (!(new = create_gl_drawable( hwnd, old->format ))) break; if (!(new = create_gl_drawable( hwnd, old->format, known_child ))) break;
mark_drawable_dirty( old, new ); mark_drawable_dirty( old, new );
XFlush( gdi_display ); XFlush( gdi_display );
TRACE( "Recreated GL drawable %lx to replace %lx\n", new->drawable, old->drawable ); TRACE( "Recreated GL drawable %lx to replace %lx\n", new->drawable, old->drawable );
@ -1517,7 +1520,7 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent )
return; return;
} }
if ((new = create_gl_drawable( hwnd, old->format ))) if ((new = create_gl_drawable( hwnd, old->format, FALSE )))
{ {
mark_drawable_dirty( old, new ); mark_drawable_dirty( old, new );
release_gl_drawable( new ); release_gl_drawable( new );
@ -3304,9 +3307,10 @@ static BOOL glxdrv_wglSwapBuffers( HDC hdc )
} }
pglXSwapBuffers(gdi_display, gl->drawable); pglXSwapBuffers(gdi_display, gl->drawable);
break; break;
case DC_GL_WINDOW:
case DC_GL_CHILD_WIN: case DC_GL_CHILD_WIN:
if (ctx) sync_context( ctx ); if (ctx) sync_context( ctx );
escape.gl_drawable = gl->window; if (gl->type == DC_GL_CHILD_WIN) escape.gl_drawable = gl->window;
/* fall through */ /* fall through */
default: default:
if (escape.gl_drawable && pglXSwapBuffersMscOML) if (escape.gl_drawable && pglXSwapBuffersMscOML)
@ -3362,7 +3366,7 @@ struct opengl_funcs *get_glx_driver( UINT version )
return NULL; return NULL;
} }
void sync_gl_drawable( HWND hwnd ) void sync_gl_drawable( HWND hwnd, BOOL known_child )
{ {
} }

View File

@ -1874,6 +1874,11 @@ static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const RECT *wi
if (GetWindowThreadProcessId( hwnd, NULL ) != GetCurrentThreadId()) return NULL; if (GetWindowThreadProcessId( hwnd, NULL ) != GetCurrentThreadId()) return NULL;
/* Recreate the parent gl_drawable now that we know there are child windows
* that will need clipping support.
*/
sync_gl_drawable( parent, TRUE );
display = thread_init_display(); display = thread_init_display();
init_clip_window(); /* make sure the clip window is initialized in this thread */ init_clip_window(); /* make sure the clip window is initialized in this thread */
@ -2206,6 +2211,12 @@ void CDECL X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent )
done: done:
release_win_data( data ); release_win_data( data );
set_gl_drawable_parent( hwnd, parent ); set_gl_drawable_parent( hwnd, parent );
/* Recreate the parent gl_drawable now that we know there are child windows
* that will need clipping support.
*/
sync_gl_drawable( parent, TRUE );
fetch_icon_data( hwnd, 0, 0 ); fetch_icon_data( hwnd, 0, 0 );
} }
@ -2369,7 +2380,7 @@ void CDECL X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags
data->client_rect.bottom - data->client_rect.top != data->client_rect.bottom - data->client_rect.top !=
old_client_rect.bottom - old_client_rect.top)); old_client_rect.bottom - old_client_rect.top));
release_win_data( data ); release_win_data( data );
if (needs_resize) sync_gl_drawable( hwnd ); if (needs_resize) sync_gl_drawable( hwnd, FALSE );
return; return;
} }

View File

@ -583,7 +583,7 @@ extern void release_win_data( struct x11drv_win_data *data ) DECLSPEC_HIDDEN;
extern Window X11DRV_get_whole_window( HWND hwnd ) DECLSPEC_HIDDEN; extern Window X11DRV_get_whole_window( HWND hwnd ) DECLSPEC_HIDDEN;
extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN; extern XIC X11DRV_get_ic( HWND hwnd ) DECLSPEC_HIDDEN;
extern void sync_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN; extern void sync_gl_drawable( HWND hwnd, BOOL known_child ) DECLSPEC_HIDDEN;
extern void set_gl_drawable_parent( HWND hwnd, HWND parent ) DECLSPEC_HIDDEN; extern void set_gl_drawable_parent( HWND hwnd, HWND parent ) DECLSPEC_HIDDEN;
extern void destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN; extern void destroy_gl_drawable( HWND hwnd ) DECLSPEC_HIDDEN;
extern void wine_vk_surface_destroy( HWND hwnd ) DECLSPEC_HIDDEN; extern void wine_vk_surface_destroy( HWND hwnd ) DECLSPEC_HIDDEN;