[PATCH 0/1] MR10106: win32u: Only link client surfaces after they are fully created.
I believe this should fix the winmm:mci occasional failure. The issue comes from the client surface being added to the surface list while it's not yet fully created and more precisely before its X11 client window has been created yet. This can happen in a rendering thread, and the window itself might be moved, resized or more specifically reparented from its owner thread at the same time. This causes all of the window client surfaces to be updated, which causes an XComposite redirect request to be sent without the X11 window yet associated with the surface. Later, when another XComposite unredirect request is sent with the X11 client window this time, it triggers an X11 error as the window has never been redirected. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10106
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/opengl.c | 6 +++++- dlls/win32u/vulkan.c | 1 + dlls/win32u/win32u_private.h | 1 + dlls/win32u/window.c | 16 ++++++++++++---- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 4a1e40f6f0d..8733b6cd564 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -1417,7 +1417,11 @@ static struct opengl_drawable *get_window_unused_drawable( HWND hwnd, int format * window, each drawing to the same back/front buffers. We cannot do that because host * OpenGL usually doesn't allow multiple contexts to use the same surface at the same time. */ - if (!drawable) driver_funcs->p_surface_create( hwnd, format, &drawable ); + if (!drawable) + { + driver_funcs->p_surface_create( hwnd, format, &drawable ); + if (drawable && drawable->client) add_window_client_surface( hwnd, drawable->client ); + } TRACE( "hwnd %p, drawable %s\n", hwnd, debugstr_opengl_drawable( drawable ) ); return drawable; diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index 73168d4eb28..13981410e94 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -1540,6 +1540,7 @@ static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance client_instance, cons free( surface ); return res; } + add_window_client_surface( surface->hwnd, surface->client ); set_window_pixel_format( surface->hwnd, -1, TRUE ); vulkan_object_init( &surface->obj.obj, host_surface ); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index 1024fb71c26..0e963dbf057 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -312,6 +312,7 @@ extern HWND get_shell_window(void); extern HWND get_progman_window(void); extern HWND get_taskman_window(void); extern BOOL is_client_surface_window( struct client_surface *surface, HWND hwnd ); +extern void add_window_client_surface( HWND hwnd, struct client_surface *surface ); extern HICON get_window_icon_info( HWND hwnd, UINT type, HICON icon, ICONINFO *ret ); extern void init_startup_info(void); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 4bceb90fcd2..84aaec6dbc2 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -326,10 +326,7 @@ void *client_surface_create( UINT size, const struct client_surface_funcs *funcs surface->funcs = funcs; surface->ref = 1; surface->hwnd = hwnd; - - pthread_mutex_lock( &surfaces_lock ); - list_add_tail( &client_surfaces, &surface->entry ); - pthread_mutex_unlock( &surfaces_lock ); + list_init( &surface->entry ); TRACE( "created %s\n", debugstr_client_surface( surface ) ); return surface; @@ -383,6 +380,17 @@ void client_surface_update( struct client_surface *surface ) pthread_mutex_unlock( &surfaces_lock ); } +void add_window_client_surface( HWND hwnd, struct client_surface *surface ) +{ + pthread_mutex_lock( &surfaces_lock ); + + surface->hwnd = hwnd; + list_add_tail( &client_surfaces, &surface->entry ); + surface->funcs->update( surface ); + + pthread_mutex_unlock( &surfaces_lock ); +} + BOOL is_client_surface_window( struct client_surface *surface, HWND hwnd ) { BOOL ret; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10106
participants (2)
-
Rémi Bernon -
Rémi Bernon (@rbernon)