From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/vulkan.c | 29 +++++++++++++---------------- dlls/winemac.drv/vulkan.c | 2 +- dlls/winewayland.drv/vulkan.c | 2 +- dlls/winex11.drv/vulkan.c | 4 ++-- include/wine/vulkan_driver.h | 2 +- 5 files changed, 18 insertions(+), 21 deletions(-)
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index a485cb3ccb8..199dd673c75 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -59,7 +59,7 @@ struct surface struct list entry; VkSurfaceKHR host_surface; void *driver_private; - BOOL is_detached; + HDC offscreen_dc; HWND hwnd; };
@@ -96,9 +96,7 @@ static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance instance, const VkWin
if (!(win = get_win_ptr( toplevel )) || win == WND_DESKTOP || win == WND_OTHER_PROCESS) { - driver_funcs->p_vulkan_surface_detach( surface->hwnd, surface->driver_private ); - surface->is_detached = TRUE; - + driver_funcs->p_vulkan_surface_detach( surface->hwnd, surface->driver_private, &surface->offscreen_dc ); pthread_mutex_lock( &vulkan_mutex ); list_add_tail( &offscreen_surfaces, &surface->entry ); pthread_mutex_unlock( &vulkan_mutex ); @@ -125,6 +123,7 @@ static void win32u_vkDestroySurfaceKHR( VkInstance instance, VkSurfaceKHR handle list_remove( &surface->entry ); pthread_mutex_unlock( &vulkan_mutex );
+ if (surface->offscreen_dc) NtGdiDeleteObjectApp( surface->offscreen_dc ); p_vkDestroySurfaceKHR( instance, surface->host_surface, NULL /* allocator */ ); driver_funcs->p_vulkan_surface_destroy( surface->hwnd, surface->driver_private ); free( surface ); @@ -208,7 +207,7 @@ static void nulldrv_vulkan_surface_attach( HWND hwnd, void *private ) { }
-static void nulldrv_vulkan_surface_detach( HWND hwnd, void *private ) +static void nulldrv_vulkan_surface_detach( HWND hwnd, void *private, HDC *hdc ) { }
@@ -286,9 +285,8 @@ void vulkan_detach_surfaces( struct list *surfaces )
LIST_FOR_EACH_ENTRY( surface, surfaces, struct surface, entry ) { - if (surface->is_detached) continue; - driver_funcs->p_vulkan_surface_detach( surface->hwnd, surface->driver_private ); - surface->is_detached = TRUE; + if (surface->offscreen_dc) continue; + driver_funcs->p_vulkan_surface_detach( surface->hwnd, surface->driver_private, &surface->offscreen_dc ); }
pthread_mutex_lock( &vulkan_mutex ); @@ -360,9 +358,8 @@ void vulkan_set_parent( HWND hwnd, HWND new_parent, HWND old_parent ) /* surfaces will be re-attached as needed from surface region updates */ LIST_FOR_EACH_ENTRY( surface, &surfaces, struct surface, entry ) { - if (surface->is_detached) continue; - driver_funcs->p_vulkan_surface_detach( surface->hwnd, surface->driver_private ); - surface->is_detached = TRUE; + if (surface->offscreen_dc) continue; + driver_funcs->p_vulkan_surface_detach( surface->hwnd, surface->driver_private, &surface->offscreen_dc ); }
append_window_surfaces( new_toplevel, &surfaces ); @@ -384,17 +381,17 @@ void vulkan_set_region( HWND toplevel, HRGN region ) NtUserMapWindowPoints( surface->hwnd, toplevel, (POINT *)&client_rect, 2 ); is_clipped = NtGdiRectInRegion( region, &client_rect );
- if (is_clipped && !surface->is_detached) + if (is_clipped && !surface->offscreen_dc) { TRACE( "surface %p is now clipped\n", surface->hwnd ); - driver_funcs->p_vulkan_surface_detach( surface->hwnd, surface->driver_private ); - surface->is_detached = TRUE; + driver_funcs->p_vulkan_surface_detach( surface->hwnd, surface->driver_private, &surface->offscreen_dc ); } - else if (!is_clipped && surface->is_detached) + else if (!is_clipped && surface->offscreen_dc) { TRACE( "surface %p is now unclipped\n", surface->hwnd ); driver_funcs->p_vulkan_surface_attach( surface->hwnd, surface->driver_private ); - surface->is_detached = FALSE; + NtGdiDeleteObjectApp( surface->offscreen_dc ); + surface->offscreen_dc = NULL; } }
diff --git a/dlls/winemac.drv/vulkan.c b/dlls/winemac.drv/vulkan.c index 9b033a84d57..736d0d397d5 100644 --- a/dlls/winemac.drv/vulkan.c +++ b/dlls/winemac.drv/vulkan.c @@ -182,7 +182,7 @@ static void macdrv_vulkan_surface_attach(HWND hwnd, void *private) { }
-static void macdrv_vulkan_surface_detach(HWND hwnd, void *private) +static void macdrv_vulkan_surface_detach(HWND hwnd, void *private, HDC *hdc) { }
diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index cd63981bf0d..175d8cfa49a 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -136,7 +136,7 @@ static void wayland_vulkan_surface_attach(HWND hwnd, void *private) { }
-static void wayland_vulkan_surface_detach(HWND hwnd, void *private) +static void wayland_vulkan_surface_detach(HWND hwnd, void *private, HDC *hdc) { }
diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index b979da1085e..cf5c44012c8 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -123,12 +123,12 @@ static void X11DRV_vulkan_surface_attach( HWND hwnd, void *private ) } }
-static void X11DRV_vulkan_surface_detach( HWND hwnd, void *private ) +static void X11DRV_vulkan_surface_detach( HWND hwnd, void *private, HDC *hdc ) { Window client_window = (Window)private; struct x11drv_win_data *data;
- TRACE( "%p %p\n", hwnd, private ); + TRACE( "%p %p %p\n", hwnd, private, hdc );
if ((data = get_win_data( hwnd ))) { diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index 180cff0e09b..74cdcd8987f 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -47,7 +47,7 @@ struct vulkan_driver_funcs VkResult (*p_vulkan_surface_create)(HWND, VkInstance, VkSurfaceKHR *, void **); void (*p_vulkan_surface_destroy)(HWND, void *); void (*p_vulkan_surface_attach)(HWND, void *); - void (*p_vulkan_surface_detach)(HWND, void *); + void (*p_vulkan_surface_detach)(HWND, void *, HDC *); void (*p_vulkan_surface_presented)(HWND, VkResult);
VkBool32 (*p_vkGetPhysicalDeviceWin32PresentationSupportKHR)(VkPhysicalDevice, uint32_t);