Updating the GL drawables on/offscreen dynamically, similarly to how we do it for Vulkan, and in order to ultimately converge and factor both GL and VK client surfaces.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 84 +++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 12 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index c277e57af53..348661fae29 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -208,7 +208,6 @@ enum dc_gl_type { DC_GL_NONE, /* no GL support (pixel format not set yet) */ DC_GL_WINDOW, /* normal top-level window */ - DC_GL_CHILD_WIN, /* child window using XComposite */ DC_GL_PIXMAP_WIN, /* child window using intermediate pixmap */ DC_GL_PBUFFER /* pseudo memory DC using a PBuffer */ }; @@ -225,6 +224,7 @@ struct gl_drawable Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */ const struct glx_pixel_format *format; /* pixel format for the drawable */ int swap_interval; + BOOL offscreen; HDC hdc_src; HDC hdc_dst; }; @@ -875,7 +875,6 @@ static void release_gl_drawable( struct gl_drawable *gl ) switch (gl->type) { case DC_GL_WINDOW: - case DC_GL_CHILD_WIN: TRACE( "destroying %lx drawable %lx\n", gl->window, gl->drawable ); pglXDestroyWindow( gdi_display, gl->drawable ); destroy_client_window( gl->hwnd, gl->window ); @@ -1062,7 +1061,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct glx_pixel #ifdef SONAME_LIBXCOMPOSITE else if(usexcomposite) { - gl->type = DC_GL_CHILD_WIN; + gl->type = DC_GL_WINDOW; gl->colormap = XCreateColormap( gdi_display, get_dummy_parent(), visual->visual, (visual->class == PseudoColor || visual->class == GrayScale || visual->class == DirectColor) ? AllocAll : AllocNone ); @@ -1073,6 +1072,7 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct glx_pixel
gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL ); pXCompositeRedirectWindow( gdi_display, gl->window, CompositeRedirectManual ); + gl->offscreen = TRUE;
if ((data = get_win_data( hwnd ))) { @@ -1166,7 +1166,6 @@ static void update_gl_drawable_size( struct gl_drawable *gl ) switch (gl->type) { case DC_GL_WINDOW: - case DC_GL_CHILD_WIN: gl->rect = rect; XConfigureWindow( gdi_display, gl->window, CWWidth | CWHeight, &changes ); set_dc_drawable( gl->hdc_src, gl->window, &gl->rect, IncludeInferiors ); @@ -1180,22 +1179,83 @@ static void update_gl_drawable_size( struct gl_drawable *gl ) } }
+static void update_gl_drawable_offscreen( struct gl_drawable *gl ) +{ + BOOL offscreen = needs_offscreen_rendering( gl->hwnd, FALSE ); + struct x11drv_win_data *data; + + if (gl->type != DC_GL_WINDOW) return; + + if (offscreen == gl->offscreen) + { + if (!offscreen && (data = get_win_data( gl->hwnd ))) + { + attach_client_window( data, gl->window ); + release_win_data( data ); + } + return; + } + gl->offscreen = offscreen; + + TRACE( "Moving hwnd %p client %lx drawable %lx %sscreen\n", gl->hwnd, gl->window, gl->drawable, offscreen ? "off" : "on" ); + + if (!gl->offscreen) + { +#ifdef SONAME_LIBXCOMPOSITE + if (usexcomposite) pXCompositeUnredirectWindow( gdi_display, gl->window, CompositeRedirectManual ); +#endif + if (gl->hdc_dst) + { + NtGdiDeleteObjectApp( gl->hdc_dst ); + gl->hdc_dst = NULL; + } + if (gl->hdc_src) + { + NtGdiDeleteObjectApp( gl->hdc_src ); + gl->hdc_src = NULL; + } + } + else + { + static const WCHAR displayW[] = {'D','I','S','P','L','A','Y'}; + UNICODE_STRING device_str = RTL_CONSTANT_STRING(displayW); + gl->hdc_dst = NtGdiOpenDCW( &device_str, NULL, NULL, 0, TRUE, NULL, NULL, NULL ); + gl->hdc_src = NtGdiOpenDCW( &device_str, NULL, NULL, 0, TRUE, NULL, NULL, NULL ); + set_dc_drawable( gl->hdc_src, gl->window, &gl->rect, IncludeInferiors ); +#ifdef SONAME_LIBXCOMPOSITE + if (usexcomposite) pXCompositeRedirectWindow( gdi_display, gl->window, CompositeRedirectManual ); +#endif + } + + if ((data = get_win_data( gl->hwnd ))) + { + if (gl->offscreen) detach_client_window( data, gl->window ); + else attach_client_window( data, gl->window ); + release_win_data( data ); + } +} + /*********************************************************************** * sync_gl_drawable */ void sync_gl_drawable( HWND hwnd, BOOL known_child ) { struct gl_drawable *old, *new; - BOOL is_offscreen;
if (!(old = get_gl_drawable( hwnd, 0 ))) return;
+ if (usexcomposite) + { + update_gl_drawable_size( old ); + update_gl_drawable_offscreen( old ); + release_gl_drawable( old ); + return; + } + switch (old->type) { case DC_GL_WINDOW: - case DC_GL_CHILD_WIN: - is_offscreen = old->type == DC_GL_CHILD_WIN; - if (is_offscreen == needs_offscreen_rendering( hwnd, known_child )) + if (!needs_offscreen_rendering( hwnd, known_child )) { update_gl_drawable_size( old ); break; @@ -1222,6 +1282,8 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent ) { struct gl_drawable *old, *new;
+ if (usexcomposite) return sync_gl_drawable( hwnd, FALSE ); + if (!(old = get_gl_drawable( hwnd, 0 ))) return;
TRACE( "setting drawable %lx parent %p\n", old->drawable, parent ); @@ -1230,7 +1292,6 @@ void set_gl_drawable_parent( HWND hwnd, HWND parent ) { case DC_GL_WINDOW: break; - case DC_GL_CHILD_WIN: case DC_GL_PIXMAP_WIN: if (parent == NtUserGetDesktopWindow()) break; /* fall through */ @@ -1559,7 +1620,7 @@ static void present_gl_drawable( HWND hwnd, HDC hdc, struct gl_drawable *gl, BOO switch (gl->type) { case DC_GL_PIXMAP_WIN: drawable = gl->pixmap; break; - case DC_GL_CHILD_WIN: drawable = gl->window; break; + case DC_GL_WINDOW: drawable = gl->offscreen ? gl->window : 0; break; default: drawable = 0; break; } if (!drawable) return; @@ -1932,9 +1993,8 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval pglXSwapBuffers(gdi_display, gl->drawable); break; case DC_GL_WINDOW: - case DC_GL_CHILD_WIN: if (ctx) sync_context( ctx ); - if (gl->type == DC_GL_CHILD_WIN) drawable = gl->window; + if (gl->offscreen) drawable = gl->window; /* fall through */ default: if (ctx && drawable && pglXSwapBuffersMscOML)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 348661fae29..581a9bdb1cc 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1240,18 +1240,31 @@ static void update_gl_drawable_offscreen( struct gl_drawable *gl ) */ void sync_gl_drawable( HWND hwnd, BOOL known_child ) { - struct gl_drawable *old, *new; - - if (!(old = get_gl_drawable( hwnd, 0 ))) return; + struct gl_drawable *old, *new, *gl;
if (usexcomposite) { - update_gl_drawable_size( old ); - update_gl_drawable_offscreen( old ); - release_gl_drawable( old ); - return; + struct x11drv_context *context; + + pthread_mutex_lock( &context_mutex ); + LIST_FOR_EACH_ENTRY( context, &context_list, struct x11drv_context, entry ) + { + if ((gl = context->drawables[0]) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) + { + update_gl_drawable_size( gl ); + update_gl_drawable_offscreen( gl ); + } + if ((gl = context->drawables[1]) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) + { + update_gl_drawable_size( gl ); + update_gl_drawable_offscreen( gl ); + } + } + pthread_mutex_unlock( &context_mutex ); }
+ if (!(old = get_gl_drawable( hwnd, 0 ))) return; + switch (old->type) { case DC_GL_WINDOW:
From: Rémi Bernon rbernon@codeweavers.com
Similarly to how we do it on Vulkan side. --- dlls/winex11.drv/opengl.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 581a9bdb1cc..ed3f47b4eac 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -1677,6 +1677,11 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva
if (flush) flush();
+ pthread_mutex_lock( &context_mutex ); + update_gl_drawable_size( gl ); + update_gl_drawable_offscreen( gl ); + pthread_mutex_unlock( &context_mutex ); + present_gl_drawable( hwnd, ctx->hdc, gl, TRUE, flush != funcs->p_glFinish ); release_gl_drawable( gl ); return TRUE; @@ -2023,8 +2028,12 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval if (ctx && drawable && pglXWaitForSbcOML) pglXWaitForSbcOML( gdi_display, gl->drawable, target_sbc, &ust, &msc, &sbc );
- present_gl_drawable( hwnd, ctx ? ctx->hdc : hdc, gl, !pglXWaitForSbcOML, FALSE ); + pthread_mutex_lock( &context_mutex ); update_gl_drawable_size( gl ); + update_gl_drawable_offscreen( gl ); + pthread_mutex_unlock( &context_mutex ); + + present_gl_drawable( hwnd, ctx ? ctx->hdc : hdc, gl, !pglXWaitForSbcOML, FALSE ); release_gl_drawable( gl ); return TRUE; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/init.c | 4 +- dlls/winex11.drv/opengl.c | 329 ++++++-------------------------------- dlls/winex11.drv/vulkan.c | 2 +- dlls/winex11.drv/window.c | 15 +- dlls/winex11.drv/x11drv.h | 6 +- 5 files changed, 54 insertions(+), 302 deletions(-)
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 4d5d7a45b06..125b3583a1b 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -217,11 +217,11 @@ static BOOL needs_client_window_clipping( HWND hwnd ) return ret > 0; }
-BOOL needs_offscreen_rendering( HWND hwnd, BOOL known_child ) +BOOL needs_offscreen_rendering( HWND hwnd ) { if (NtUserGetDpiForWindow( hwnd ) != NtUserGetWinMonitorDpi( hwnd, MDT_RAW_DPI )) return TRUE; /* needs DPI scaling */ if (NtUserGetAncestor( hwnd, GA_PARENT ) != NtUserGetDesktopWindow()) return TRUE; /* child window, needs compositing */ - if (NtUserGetWindowRelative( hwnd, GW_CHILD ) || known_child) return needs_client_window_clipping( hwnd ); /* window has children, needs compositing */ + if (NtUserGetWindowRelative( hwnd, GW_CHILD )) return needs_client_window_clipping( hwnd ); /* window has children, needs compositing */ return FALSE; }
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index ed3f47b4eac..33d2c5faa7d 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -200,7 +200,6 @@ struct x11drv_context const struct glx_pixel_format *fmt; GLXContext ctx; struct gl_drawable *drawables[2]; - struct gl_drawable *new_drawables[2]; struct list entry; };
@@ -208,7 +207,6 @@ enum dc_gl_type { DC_GL_NONE, /* no GL support (pixel format not set yet) */ DC_GL_WINDOW, /* normal top-level window */ - DC_GL_PIXMAP_WIN, /* child window using intermediate pixmap */ DC_GL_PBUFFER /* pseudo memory DC using a PBuffer */ };
@@ -880,11 +878,6 @@ static void release_gl_drawable( struct gl_drawable *gl ) destroy_client_window( gl->hwnd, gl->window ); XFreeColormap( gdi_display, gl->colormap ); break; - case DC_GL_PIXMAP_WIN: - TRACE( "destroying pixmap %lx drawable %lx\n", gl->pixmap, gl->drawable ); - pglXDestroyPixmap( gdi_display, gl->drawable ); - XFreePixmap( gdi_display, gl->pixmap ); - break; case DC_GL_PBUFFER: TRACE( "destroying pbuffer drawable %lx\n", gl->drawable ); pglXDestroyPbuffer( gdi_display, gl->drawable ); @@ -897,62 +890,6 @@ static void release_gl_drawable( struct gl_drawable *gl ) free( gl ); }
-/* Mark any allocated context using the glx drawable 'old' to use 'new' */ -static void mark_drawable_dirty( struct gl_drawable *old, struct gl_drawable *new ) -{ - struct x11drv_context *ctx; - - pthread_mutex_lock( &context_mutex ); - LIST_FOR_EACH_ENTRY( ctx, &context_list, struct x11drv_context, entry ) - { - if (old == ctx->drawables[0] || old == ctx->new_drawables[0]) - { - release_gl_drawable( ctx->new_drawables[0] ); - ctx->new_drawables[0] = grab_gl_drawable( new ); - } - if (old == ctx->drawables[1] || old == ctx->new_drawables[1]) - { - release_gl_drawable( ctx->new_drawables[1] ); - ctx->new_drawables[1] = grab_gl_drawable( new ); - } - } - pthread_mutex_unlock( &context_mutex ); -} - -/* Given the current context, make sure its drawable is sync'd */ -static inline void sync_context(struct x11drv_context *context) -{ - BOOL refresh = FALSE; - struct gl_drawable *old[2] = { NULL }; - - pthread_mutex_lock( &context_mutex ); - if (context->new_drawables[0]) - { - old[0] = context->drawables[0]; - context->drawables[0] = context->new_drawables[0]; - context->new_drawables[0] = NULL; - refresh = TRUE; - } - if (context->new_drawables[1]) - { - old[1] = context->drawables[1]; - context->drawables[1] = context->new_drawables[1]; - context->new_drawables[1] = NULL; - refresh = TRUE; - } - if (refresh) - { - if (glxRequireVersion(3)) - pglXMakeContextCurrent(gdi_display, context->drawables[0]->drawable, - context->drawables[1]->drawable, context->ctx); - else - pglXMakeCurrent(gdi_display, context->drawables[0]->drawable, context->ctx); - release_gl_drawable( old[0] ); - release_gl_drawable( old[1] ); - } - pthread_mutex_unlock( &context_mutex ); -} - static BOOL set_swap_interval( struct gl_drawable *gl, int interval ) { BOOL ret = TRUE; @@ -1025,18 +962,13 @@ static GLXContext create_glxcontext(Display *display, struct x11drv_context *con /*********************************************************************** * create_gl_drawable */ -static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct glx_pixel_format *format, BOOL known_child ) +static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct glx_pixel_format *format ) { - static const WCHAR displayW[] = {'D','I','S','P','L','A','Y'}; - UNICODE_STRING device_str = RTL_CONSTANT_STRING(displayW); struct gl_drawable *gl, *prev; XVisualInfo *visual = format->visual; RECT rect; - int width, height;
NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) ); - width = min( max( 1, rect.right ), 65535 ); - height = min( max( 1, rect.bottom ), 65535 );
if (!(gl = calloc( 1, sizeof(*gl) ))) return NULL;
@@ -1047,67 +979,13 @@ static struct gl_drawable *create_gl_drawable( HWND hwnd, const struct glx_pixel gl->hwnd = hwnd; gl->rect = rect;
- if (!needs_offscreen_rendering( hwnd, known_child )) - { - gl->type = DC_GL_WINDOW; - gl->colormap = XCreateColormap( gdi_display, get_dummy_parent(), visual->visual, - (visual->class == PseudoColor || visual->class == GrayScale || - visual->class == DirectColor) ? AllocAll : AllocNone ); - gl->window = create_client_window( hwnd, visual, gl->colormap ); - if (gl->window) - gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL ); - TRACE( "%p created client %lx drawable %lx\n", hwnd, gl->window, gl->drawable ); - } -#ifdef SONAME_LIBXCOMPOSITE - else if(usexcomposite) - { - gl->type = DC_GL_WINDOW; - gl->colormap = XCreateColormap( gdi_display, get_dummy_parent(), visual->visual, - (visual->class == PseudoColor || visual->class == GrayScale || - visual->class == DirectColor) ? AllocAll : AllocNone ); - gl->window = create_client_window( hwnd, visual, gl->colormap ); - if (gl->window) - { - struct x11drv_win_data *data; - - gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL ); - pXCompositeRedirectWindow( gdi_display, gl->window, CompositeRedirectManual ); - gl->offscreen = TRUE; - - if ((data = get_win_data( hwnd ))) - { - detach_client_window( data, gl->window ); - release_win_data( data ); - } - - gl->hdc_dst = NtGdiOpenDCW( &device_str, NULL, NULL, 0, TRUE, NULL, NULL, NULL ); - gl->hdc_src = NtGdiOpenDCW( &device_str, NULL, NULL, 0, TRUE, NULL, NULL, NULL ); - set_dc_drawable( gl->hdc_src, gl->window, &gl->rect, IncludeInferiors ); - } - - TRACE( "%p created child %lx drawable %lx\n", hwnd, gl->window, gl->drawable ); - } -#endif - else - { - static unsigned int once; - - if (!once++) - ERR_(winediag)("XComposite is not available, using GLXPixmap hack.\n"); - WARN("XComposite is not available, using GLXPixmap hack.\n"); - - gl->type = DC_GL_PIXMAP_WIN; - gl->pixmap = XCreatePixmap( gdi_display, root_window, width, height, visual->depth ); - if (gl->pixmap) - { - gl->drawable = pglXCreatePixmap( gdi_display, gl->format->fbconfig, gl->pixmap, NULL ); - if (!gl->drawable) XFreePixmap( gdi_display, gl->pixmap ); - - gl->hdc_dst = NtGdiOpenDCW( &device_str, NULL, NULL, 0, TRUE, NULL, NULL, NULL ); - gl->hdc_src = NtGdiOpenDCW( &device_str, NULL, NULL, 0, TRUE, NULL, NULL, NULL ); - set_dc_drawable( gl->hdc_src, gl->pixmap, &gl->rect, IncludeInferiors ); - } - } + gl->type = DC_GL_WINDOW; + gl->colormap = XCreateColormap( gdi_display, get_dummy_parent(), visual->visual, + (visual->class == PseudoColor || visual->class == GrayScale || + visual->class == DirectColor) ? AllocAll : AllocNone ); + gl->window = create_client_window( hwnd, visual, gl->colormap ); + if (gl->window) gl->drawable = pglXCreateWindow( gdi_display, gl->format->fbconfig, gl->window, NULL ); + TRACE( "%p created client %lx drawable %lx\n", hwnd, gl->window, gl->drawable );
if (!gl->drawable) { @@ -1140,7 +1018,7 @@ static BOOL x11drv_set_pixel_format( HWND hwnd, int old_format, int new_format, return FALSE; }
- if (!(gl = create_gl_drawable( hwnd, fmt, FALSE ))) return FALSE; + if (!(gl = create_gl_drawable( hwnd, fmt ))) return FALSE;
TRACE( "created GL drawable %lx for win %p %s\n", gl->drawable, hwnd, debugstr_fbconfig( fmt->fbconfig )); @@ -1153,39 +1031,23 @@ static BOOL x11drv_set_pixel_format( HWND hwnd, int old_format, int new_format,
static void update_gl_drawable_size( struct gl_drawable *gl ) { - struct gl_drawable *new_gl; XWindowChanges changes; RECT rect;
NtUserGetClientRect( gl->hwnd, &rect, NtUserGetDpiForWindow( gl->hwnd ) ); - if (EqualRect( &rect, &gl->rect )) return; + if (EqualRect( &gl->rect, &rect )) return;
changes.width = min( max( 1, rect.right ), 65535 ); changes.height = min( max( 1, rect.bottom ), 65535 ); - - switch (gl->type) - { - case DC_GL_WINDOW: - gl->rect = rect; - XConfigureWindow( gdi_display, gl->window, CWWidth | CWHeight, &changes ); - set_dc_drawable( gl->hdc_src, gl->window, &gl->rect, IncludeInferiors ); - break; - case DC_GL_PIXMAP_WIN: - new_gl = create_gl_drawable( gl->hwnd, gl->format, TRUE ); - mark_drawable_dirty( gl, new_gl ); - release_gl_drawable( new_gl ); - default: - break; - } + XConfigureWindow( gdi_display, gl->window, CWWidth | CWHeight, &changes ); + gl->rect = rect; }
static void update_gl_drawable_offscreen( struct gl_drawable *gl ) { - BOOL offscreen = needs_offscreen_rendering( gl->hwnd, FALSE ); + BOOL offscreen = needs_offscreen_rendering( gl->hwnd ); struct x11drv_win_data *data;
- if (gl->type != DC_GL_WINDOW) return; - if (offscreen == gl->offscreen) { if (!offscreen && (data = get_win_data( gl->hwnd ))) @@ -1238,87 +1100,26 @@ static void update_gl_drawable_offscreen( struct gl_drawable *gl ) /*********************************************************************** * sync_gl_drawable */ -void sync_gl_drawable( HWND hwnd, BOOL known_child ) +void sync_gl_drawable( HWND hwnd ) { - struct gl_drawable *old, *new, *gl; + struct x11drv_context *context; + struct gl_drawable *gl;
- if (usexcomposite) + pthread_mutex_lock( &context_mutex ); + LIST_FOR_EACH_ENTRY( context, &context_list, struct x11drv_context, entry ) { - struct x11drv_context *context; - - pthread_mutex_lock( &context_mutex ); - LIST_FOR_EACH_ENTRY( context, &context_list, struct x11drv_context, entry ) + if ((gl = context->drawables[0]) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) { - if ((gl = context->drawables[0]) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) - { - update_gl_drawable_size( gl ); - update_gl_drawable_offscreen( gl ); - } - if ((gl = context->drawables[1]) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) - { - update_gl_drawable_size( gl ); - update_gl_drawable_offscreen( gl ); - } + update_gl_drawable_size( gl ); + update_gl_drawable_offscreen( gl ); } - pthread_mutex_unlock( &context_mutex ); - } - - if (!(old = get_gl_drawable( hwnd, 0 ))) return; - - switch (old->type) - { - case DC_GL_WINDOW: - if (!needs_offscreen_rendering( hwnd, known_child )) + if ((gl = context->drawables[1]) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) { - update_gl_drawable_size( old ); - break; + update_gl_drawable_size( gl ); + update_gl_drawable_offscreen( gl ); } - /* fall through */ - case DC_GL_PIXMAP_WIN: - if (!(new = create_gl_drawable( hwnd, old->format, known_child ))) break; - mark_drawable_dirty( old, new ); - XFlush( gdi_display ); - TRACE( "Recreated GL drawable %lx to replace %lx\n", new->drawable, old->drawable ); - release_gl_drawable( new ); - break; - default: - break; } - release_gl_drawable( old ); -} - - -/*********************************************************************** - * set_gl_drawable_parent - */ -void set_gl_drawable_parent( HWND hwnd, HWND parent ) -{ - struct gl_drawable *old, *new; - - if (usexcomposite) return sync_gl_drawable( hwnd, FALSE ); - - if (!(old = get_gl_drawable( hwnd, 0 ))) return; - - TRACE( "setting drawable %lx parent %p\n", old->drawable, parent ); - - switch (old->type) - { - case DC_GL_WINDOW: - break; - case DC_GL_PIXMAP_WIN: - if (parent == NtUserGetDesktopWindow()) break; - /* fall through */ - default: - release_gl_drawable( old ); - return; - } - - if ((new = create_gl_drawable( hwnd, old->format, FALSE ))) - { - mark_drawable_dirty( old, new ); - release_gl_drawable( new ); - } - release_gl_drawable( old ); + pthread_mutex_unlock( &context_mutex ); }
@@ -1552,8 +1353,6 @@ static BOOL x11drv_context_destroy(void *private) if (ctx->ctx) pglXDestroyContext( gdi_display, ctx->ctx ); release_gl_drawable( ctx->drawables[0] ); release_gl_drawable( ctx->drawables[1] ); - release_gl_drawable( ctx->new_drawables[0] ); - release_gl_drawable( ctx->new_drawables[1] ); free( ctx ); return TRUE; } @@ -1568,17 +1367,14 @@ static void *x11drv_get_proc_address( const char *name ) static void set_context_drawables( struct x11drv_context *ctx, struct gl_drawable *draw, struct gl_drawable *read ) { - struct gl_drawable *prev[4]; + struct gl_drawable *prev[2]; int i;
prev[0] = ctx->drawables[0]; prev[1] = ctx->drawables[1]; - prev[2] = ctx->new_drawables[0]; - prev[3] = ctx->new_drawables[1]; ctx->drawables[0] = grab_gl_drawable( draw ); ctx->drawables[1] = read ? grab_gl_drawable( read ) : NULL; - ctx->new_drawables[0] = ctx->new_drawables[1] = NULL; - for (i = 0; i < 4; i++) release_gl_drawable( prev[i] ); + for (i = 0; i < 2; i++) release_gl_drawable( prev[i] ); }
static BOOL x11drv_context_make_current( HDC draw_hdc, HDC read_hdc, void *private ) @@ -1625,18 +1421,12 @@ static void present_gl_drawable( HWND hwnd, HDC hdc, struct gl_drawable *gl, BOO { HWND toplevel = NtUserGetAncestor( hwnd, GA_ROOT ); struct x11drv_win_data *data; - Drawable window, drawable; + Drawable window; RECT rect_dst, rect; HRGN region;
- if (!gl) return; - switch (gl->type) - { - case DC_GL_PIXMAP_WIN: drawable = gl->pixmap; break; - case DC_GL_WINDOW: drawable = gl->offscreen ? gl->window : 0; break; - default: drawable = 0; break; - } - if (!drawable) return; + if (!gl->offscreen) return; + window = get_dc_drawable( hdc, &rect ); region = get_dc_monitor_region( hwnd, hdc );
@@ -1669,7 +1459,11 @@ static BOOL x11drv_context_flush( void *private, HWND hwnd, HDC hdc, int interva struct x11drv_context *ctx = private;
if (!(gl = get_gl_drawable( hwnd, 0 ))) return FALSE; - sync_context( ctx ); + if (gl->type != DC_GL_WINDOW) + { + release_gl_drawable( gl ); + return FALSE; + }
pthread_mutex_lock( &context_mutex ); set_swap_interval( gl, interval ); @@ -1974,7 +1768,6 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval struct gl_drawable *gl; struct x11drv_context *ctx = private; INT64 ust, msc, sbc, target_sbc = 0; - Drawable drawable = 0;
TRACE("(%p)\n", hdc);
@@ -1983,50 +1776,24 @@ static BOOL x11drv_swap_buffers( void *private, HWND hwnd, HDC hdc, int interval RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); return FALSE; } + if (gl->type != DC_GL_WINDOW) + { + release_gl_drawable( gl ); + return FALSE; + }
pthread_mutex_lock( &context_mutex ); set_swap_interval( gl, interval ); pthread_mutex_unlock( &context_mutex );
- switch (gl->type) + if (!ctx || !gl->offscreen) pglXSwapBuffers( gdi_display, gl->drawable ); + else { - case DC_GL_PIXMAP_WIN: - if (ctx) sync_context( ctx ); - drawable = gl->pixmap; - if (ctx && pglXCopySubBufferMESA) { - /* (glX)SwapBuffers has an implicit glFlush effect, however - * GLX_MESA_copy_sub_buffer doesn't. Make sure GL is flushed before - * copying */ - funcs->p_glFlush(); - pglXCopySubBufferMESA( gdi_display, gl->drawable, 0, 0, - gl->rect.right, gl->rect.bottom ); - break; - } - if (ctx && pglXSwapBuffersMscOML) - { - funcs->p_glFlush(); - target_sbc = pglXSwapBuffersMscOML( gdi_display, gl->drawable, 0, 0, 0 ); - break; - } - pglXSwapBuffers(gdi_display, gl->drawable); - break; - case DC_GL_WINDOW: - if (ctx) sync_context( ctx ); - if (gl->offscreen) drawable = gl->window; - /* fall through */ - default: - if (ctx && drawable && pglXSwapBuffersMscOML) - { - funcs->p_glFlush(); - target_sbc = pglXSwapBuffersMscOML( gdi_display, gl->drawable, 0, 0, 0 ); - break; - } - pglXSwapBuffers(gdi_display, gl->drawable); - break; - } + funcs->p_glFlush();
- if (ctx && drawable && pglXWaitForSbcOML) - pglXWaitForSbcOML( gdi_display, gl->drawable, target_sbc, &ust, &msc, &sbc ); + if (pglXSwapBuffersMscOML) target_sbc = pglXSwapBuffersMscOML( gdi_display, gl->drawable, 0, 0, 0 ); + if (pglXWaitForSbcOML) pglXWaitForSbcOML( gdi_display, gl->drawable, target_sbc, &ust, &msc, &sbc ); + }
pthread_mutex_lock( &context_mutex ); update_gl_drawable_size( gl ); @@ -2070,10 +1837,6 @@ void sync_gl_drawable( HWND hwnd, BOOL known_child ) { }
-void set_gl_drawable_parent( HWND hwnd, HWND parent ) -{ -} - void destroy_gl_drawable( HWND hwnd ) { } diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index f4442803788..364274b3903 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -158,7 +158,7 @@ static void vulkan_surface_update_size( HWND hwnd, struct x11drv_vulkan_surface
static void vulkan_surface_update_offscreen( HWND hwnd, struct x11drv_vulkan_surface *surface ) { - BOOL offscreen = needs_offscreen_rendering( hwnd, FALSE ); + BOOL offscreen = needs_offscreen_rendering( hwnd ); struct x11drv_win_data *data;
if (offscreen == surface->offscreen) diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index beb93d66251..726478ff040 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2760,11 +2760,7 @@ static struct x11drv_win_data *X11DRV_create_win_data( HWND hwnd, const struct w if (parent != NtUserGetDesktopWindow() && !NtUserGetAncestor( parent, GA_PARENT )) return NULL;
if (NtUserGetWindowThread( 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 ); + sync_gl_drawable( parent );
display = thread_init_display(); init_clip_window(); /* make sure the clip window is initialized in this thread */ @@ -3080,12 +3076,7 @@ void X11DRV_SetParent( HWND hwnd, HWND parent, HWND old_parent ) } done: release_win_data( data ); - 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 ); + sync_gl_drawable( parent );
fetch_icon_data( hwnd, 0, 0 ); } @@ -3173,7 +3164,7 @@ void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UIN struct window_rects old_rects; BOOL was_fullscreen, activate = !(swp_flags & SWP_NOACTIVATE);
- sync_gl_drawable( hwnd, FALSE ); + sync_gl_drawable( hwnd );
if (!(data = get_win_data( hwnd ))) return; if (is_window_managed( hwnd, swp_flags, fullscreen )) window_set_managed( data, TRUE ); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 388ab771452..421d394de20 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -355,7 +355,7 @@ struct x11drv_escape_get_drawable RECT dc_rect; /* DC rectangle relative to drawable */ };
-extern BOOL needs_offscreen_rendering( HWND hwnd, BOOL known_child ); +extern BOOL needs_offscreen_rendering( HWND hwnd ); extern void set_dc_drawable( HDC hdc, Drawable drawable, const RECT *rect, int mode ); extern Drawable get_dc_drawable( HDC hdc, RECT *rect ); extern HRGN get_dc_monitor_region( HWND hwnd, HDC hdc ); @@ -681,10 +681,8 @@ extern void set_window_parent( struct x11drv_win_data *data, Window parent ); extern Window X11DRV_get_whole_window( HWND hwnd ); extern Window get_dummy_parent(void);
-extern void sync_gl_drawable( HWND hwnd, BOOL known_child ); -extern void set_gl_drawable_parent( HWND hwnd, HWND parent ); +extern void sync_gl_drawable( HWND hwnd ); extern void destroy_gl_drawable( HWND hwnd ); -extern void destroy_vk_surface( HWND hwnd );
extern BOOL window_is_reparenting( HWND hwnd ); extern BOOL window_should_take_focus( HWND hwnd, Time time );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 33d2c5faa7d..495dfda41f8 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -199,7 +199,8 @@ struct x11drv_context HDC hdc; const struct glx_pixel_format *fmt; GLXContext ctx; - struct gl_drawable *drawables[2]; + struct gl_drawable *draw; + struct gl_drawable *read; struct list entry; };
@@ -868,7 +869,6 @@ static struct gl_drawable *grab_gl_drawable( struct gl_drawable *gl )
static void release_gl_drawable( struct gl_drawable *gl ) { - if (!gl) return; if (InterlockedDecrement( &gl->ref )) return; switch (gl->type) { @@ -1108,12 +1108,12 @@ void sync_gl_drawable( HWND hwnd ) pthread_mutex_lock( &context_mutex ); LIST_FOR_EACH_ENTRY( context, &context_list, struct x11drv_context, entry ) { - if ((gl = context->drawables[0]) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) + if ((gl = context->draw) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) { update_gl_drawable_size( gl ); update_gl_drawable_offscreen( gl ); } - if ((gl = context->drawables[1]) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) + if ((gl = context->read) && gl->type == DC_GL_WINDOW && gl->hwnd == hwnd) { update_gl_drawable_size( gl ); update_gl_drawable_offscreen( gl ); @@ -1351,8 +1351,8 @@ static BOOL x11drv_context_destroy(void *private) pthread_mutex_unlock( &context_mutex );
if (ctx->ctx) pglXDestroyContext( gdi_display, ctx->ctx ); - release_gl_drawable( ctx->drawables[0] ); - release_gl_drawable( ctx->drawables[1] ); + if (ctx->draw) release_gl_drawable( ctx->draw ); + if (ctx->read) release_gl_drawable( ctx->read ); free( ctx ); return TRUE; } @@ -1367,14 +1367,14 @@ static void *x11drv_get_proc_address( const char *name ) static void set_context_drawables( struct x11drv_context *ctx, struct gl_drawable *draw, struct gl_drawable *read ) { - struct gl_drawable *prev[2]; - int i; - - prev[0] = ctx->drawables[0]; - prev[1] = ctx->drawables[1]; - ctx->drawables[0] = grab_gl_drawable( draw ); - ctx->drawables[1] = read ? grab_gl_drawable( read ) : NULL; - for (i = 0; i < 2; i++) release_gl_drawable( prev[i] ); + struct gl_drawable *old_draw, *old_read; + + old_draw = ctx->draw; + old_read = ctx->read; + ctx->draw = grab_gl_drawable( draw ); + ctx->read = read ? grab_gl_drawable( read ) : NULL; + if (old_draw) release_gl_drawable( old_draw ); + if (old_read) release_gl_drawable( old_read ); }
static BOOL x11drv_context_make_current( HDC draw_hdc, HDC read_hdc, void *private ) @@ -1411,8 +1411,8 @@ static BOOL x11drv_context_make_current( HDC draw_hdc, HDC read_hdc, void *priva } RtlSetLastWin32Error( ERROR_INVALID_HANDLE ); done: - release_gl_drawable( read_gl ); - release_gl_drawable( draw_gl ); + if (read_gl) release_gl_drawable( read_gl ); + if (draw_gl) release_gl_drawable( draw_gl ); TRACE( "%p,%p,%p returning %d\n", draw_hdc, read_hdc, ctx, ret ); return ret; }