From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/opengl.c | 13 +-- dlls/winewayland.drv/vulkan.c | 70 +---------------- dlls/winewayland.drv/wayland_surface.c | 105 ++++++++++++++++--------- dlls/winewayland.drv/waylanddrv.h | 5 +- dlls/winewayland.drv/window.c | 8 +- 5 files changed, 79 insertions(+), 122 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index bf7be9daccc..db510d2df97 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -65,13 +65,8 @@ static void wayland_drawable_destroy(struct opengl_drawable *base) if (gl->wl_egl_window) wl_egl_window_destroy(gl->wl_egl_window); if (gl->client) { - HWND hwnd = wl_surface_get_user_data(gl->client->wl_surface); - struct wayland_win_data *data = wayland_win_data_get(hwnd); - - if (wayland_client_surface_release(gl->client) && data) - data->client_surface = NULL; - - if (data) wayland_win_data_release(data); + gl->client->client.funcs->detach( &gl->client->client ); + client_surface_release( &gl->client->client ); } }
@@ -170,11 +165,9 @@ static void wayland_drawable_flush(struct opengl_drawable *base, UINT flags)
static BOOL wayland_drawable_swap(struct opengl_drawable *base) { - HWND hwnd = base->hwnd, toplevel = NtUserGetAncestor(hwnd, GA_ROOT); struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base);
- ensure_window_surface_contents(toplevel); - set_client_surface(hwnd, gl->client); + client_surface_present(&gl->client->client, NULL); funcs->p_eglSwapBuffers(egl->display, gl->base.surface);
return TRUE; diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index ac42bf9e14d..c6aa9342c09 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -39,17 +39,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan);
#ifdef SONAME_LIBVULKAN
-struct wayland_vulkan_surface -{ - struct client_surface client; - struct wayland_client_surface *wayland_client; -}; - -static struct wayland_vulkan_surface *impl_from_client_surface(struct client_surface *client) -{ - return CONTAINING_RECORD(client, struct wayland_vulkan_surface, client); -} - #define VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR 1000006000
typedef struct VkWaylandSurfaceCreateInfoKHR @@ -64,7 +53,6 @@ typedef struct VkWaylandSurfaceCreateInfoKHR static VkResult (*pvkCreateWaylandSurfaceKHR)(VkInstance, const VkWaylandSurfaceCreateInfoKHR *, const VkAllocationCallbacks *, VkSurfaceKHR *); static VkBool32 (*pvkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalDevice, uint32_t, struct wl_display *);
-static const struct client_surface_funcs wayland_vulkan_surface_funcs; static const struct vulkan_driver_funcs wayland_vulkan_driver_funcs;
static VkResult wayland_vulkan_surface_create(HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *handle, @@ -72,23 +60,16 @@ static VkResult wayland_vulkan_surface_create(HWND hwnd, const struct vulkan_ins { VkResult res; VkWaylandSurfaceCreateInfoKHR create_info_host; - struct wayland_vulkan_surface *surface; + struct wayland_client_surface *surface;
TRACE("%p %p %p %p\n", hwnd, instance, handle, client);
- if (!(surface = client_surface_create(sizeof(*surface), &wayland_vulkan_surface_funcs, hwnd))) return VK_ERROR_OUT_OF_HOST_MEMORY; - if (!(surface->wayland_client = wayland_client_surface_create(hwnd))) - { - ERR("Failed to create client handle for hwnd=%p\n", hwnd); - client_surface_release(&surface->client); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - + if (!(surface = wayland_client_surface_create(hwnd))) return VK_ERROR_OUT_OF_HOST_MEMORY; create_info_host.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; create_info_host.pNext = NULL; create_info_host.flags = 0; /* reserved */ create_info_host.display = process_wayland.wl_display; - create_info_host.surface = surface->wayland_client->wl_surface; + create_info_host.surface = surface->wl_surface;
res = pvkCreateWaylandSurfaceKHR(instance->host.instance, &create_info_host, NULL /* allocator */, @@ -100,48 +81,13 @@ static VkResult wayland_vulkan_surface_create(HWND hwnd, const struct vulkan_ins return res; }
- set_client_surface(hwnd, surface->wayland_client); + set_client_surface(hwnd, surface); *client = &surface->client;
TRACE("Created surface=0x%s, client=%p\n", wine_dbgstr_longlong(*handle), *client); return VK_SUCCESS; }
-static void wayland_vulkan_surface_destroy(struct client_surface *client) -{ - struct wayland_vulkan_surface *surface = impl_from_client_surface(client); - - TRACE("%s\n", debugstr_client_surface(client)); - - if (surface->wayland_client) wayland_client_surface_release(surface->wayland_client); -} - -static void wayland_vulkan_surface_detach(struct client_surface *client) -{ - struct wayland_vulkan_surface *surface = impl_from_client_surface(client); - struct wayland_win_data *data; - - if ((data = wayland_win_data_get(client->hwnd))) - { - if (data->client_surface == surface->wayland_client) - data->client_surface = NULL; - wayland_client_surface_detach(surface->wayland_client); - wayland_win_data_release(data); - } -} - -static void wayland_vulkan_surface_update(struct client_surface *client) -{ -} - -static void wayland_vulkan_surface_present(struct client_surface *client, HDC hdc) -{ - struct wayland_vulkan_surface *surface = impl_from_client_surface(client); - HWND hwnd = client->hwnd, toplevel = NtUserGetAncestor(hwnd, GA_ROOT); - ensure_window_surface_contents(toplevel); - set_client_surface(hwnd, surface->wayland_client); -} - static VkBool32 wayland_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev, uint32_t index) { @@ -156,14 +102,6 @@ static const char *wayland_get_host_surface_extension(void) return "VK_KHR_wayland_surface"; }
-static const struct client_surface_funcs wayland_vulkan_surface_funcs = -{ - .destroy = wayland_vulkan_surface_destroy, - .detach = wayland_vulkan_surface_detach, - .update = wayland_vulkan_surface_update, - .present = wayland_vulkan_surface_present, -}; - static const struct vulkan_driver_funcs wayland_vulkan_driver_funcs = { .p_vulkan_surface_create = wayland_vulkan_surface_create, diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 15a5786ec69..7da7c4212f6 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -984,37 +984,64 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface, *window_y = round(surface_y * surface->window.scale); }
-/********************************************************************** - * wayland_client_surface_release - */ -BOOL wayland_client_surface_release(struct wayland_client_surface *client) +static struct wayland_client_surface *impl_from_client_surface(struct client_surface *client) { - if (InterlockedDecrement(&client->ref)) return FALSE; + return CONTAINING_RECORD(client, struct wayland_client_surface, client); +}
- if (client->wp_viewport) - wp_viewport_destroy(client->wp_viewport); - if (client->wl_subsurface) - wl_subsurface_destroy(client->wl_subsurface); - if (client->wl_surface) - wl_surface_destroy(client->wl_surface); +static void wayland_client_surface_destroy(struct client_surface *client) +{ + struct wayland_client_surface *surface = impl_from_client_surface(client);
- free(client); + TRACE("%s\n", debugstr_client_surface(client));
- return TRUE; + if (surface->wp_viewport) + wp_viewport_destroy(surface->wp_viewport); + if (surface->wl_subsurface) + wl_subsurface_destroy(surface->wl_subsurface); + if (surface->wl_surface) + wl_surface_destroy(surface->wl_surface); +} + +static void wayland_client_surface_detach(struct client_surface *client) +{ + struct wayland_client_surface *surface = impl_from_client_surface(client); + struct wayland_win_data *data; + + if ((data = wayland_win_data_get(client->hwnd))) + { + if (data->client_surface == surface) data->client_surface = NULL; + wayland_client_surface_attach(surface, NULL); + wayland_win_data_release(data); + } }
+static void wayland_client_surface_update(struct client_surface *client) +{ +} + +static void wayland_client_surface_present(struct client_surface *client, HDC hdc) +{ + struct wayland_client_surface *surface = impl_from_client_surface(client); + HWND hwnd = client->hwnd, toplevel = NtUserGetAncestor(hwnd, GA_ROOT); + ensure_window_surface_contents(toplevel); + set_client_surface(hwnd, surface); +} + +static const struct client_surface_funcs wayland_client_surface_funcs = +{ + .destroy = wayland_client_surface_destroy, + .detach = wayland_client_surface_detach, + .update = wayland_client_surface_update, + .present = wayland_client_surface_present, +}; + struct wayland_client_surface *wayland_client_surface_create(HWND hwnd) { struct wayland_client_surface *client; struct wl_region *empty_region;
- if (!(client = calloc(1, sizeof(*client)))) - { - ERR("Failed to allocate space for client surface\n"); - return NULL; - } - client->ref = 1; - client->hwnd = hwnd; + if (!(client = client_surface_create(sizeof(*client), &wayland_client_surface_funcs, hwnd))) return NULL;
client->wl_surface = wl_compositor_create_surface(process_wayland.wl_compositor); @@ -1047,25 +1074,38 @@ struct wayland_client_surface *wayland_client_surface_create(HWND hwnd) return client;
err: - wayland_client_surface_release(client); + client_surface_release(&client->client); return NULL; }
void wayland_client_surface_attach(struct wayland_client_surface *client, HWND toplevel) { - struct wayland_win_data *toplevel_data = wayland_win_data_get_nolock(toplevel); + struct wayland_win_data *toplevel_data; struct wayland_surface *surface; + HWND hwnd = client->client.hwnd; RECT client_rect;
- if (!toplevel_data || !(surface = toplevel_data->wayland_surface)) + if (!toplevel) { - wayland_client_surface_detach(client); + if (client->wl_subsurface) + { + wl_subsurface_destroy(client->wl_subsurface); + client->wl_subsurface = NULL; + } + + client->toplevel = 0; + return; + } + + if (!(toplevel_data = wayland_win_data_get_nolock(toplevel)) || !(surface = toplevel_data->wayland_surface)) + { + wayland_client_surface_attach(client, NULL); return; }
if (client->toplevel != toplevel) { - wayland_client_surface_detach(client); + wayland_client_surface_attach(client, NULL);
client->wl_subsurface = wl_subcompositor_get_subsurface(process_wayland.wl_subcompositor, @@ -1082,25 +1122,14 @@ void wayland_client_surface_attach(struct wayland_client_surface *client, HWND t client->toplevel = toplevel; }
- NtUserGetClientRect(client->hwnd, &client_rect, NtUserGetWinMonitorDpi(client->hwnd, MDT_RAW_DPI)); - NtUserMapWindowPoints(client->hwnd, toplevel, (POINT *)&client_rect, 2, NtUserGetWinMonitorDpi(client->hwnd, MDT_RAW_DPI)); + NtUserGetClientRect(hwnd, &client_rect, NtUserGetWinMonitorDpi(hwnd, MDT_RAW_DPI)); + NtUserMapWindowPoints(hwnd, toplevel, (POINT *)&client_rect, 2, NtUserGetWinMonitorDpi(hwnd, MDT_RAW_DPI));
wayland_surface_reconfigure_client(surface, client, &client_rect); /* Commit to apply subsurface positioning. */ wl_surface_commit(surface->wl_surface); }
-void wayland_client_surface_detach(struct wayland_client_surface *client) -{ - if (client->wl_subsurface) - { - wl_subsurface_destroy(client->wl_subsurface); - client->wl_subsurface = NULL; - } - - client->toplevel = 0; -} - static void dummy_buffer_release(void *data, struct wl_buffer *buffer) { struct wayland_shm_buffer *shm_buffer = data; diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 5592ffe9989..cb331df789d 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -239,8 +239,7 @@ struct wayland_window_config
struct wayland_client_surface { - LONG ref; - HWND hwnd; + struct client_surface client; HWND toplevel; struct wl_surface *wl_surface; struct wl_subsurface *wl_subsurface; @@ -330,9 +329,7 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface, double surface_x, double surface_y, int *window_x, int *window_y); struct wayland_client_surface *wayland_client_surface_create(HWND hwnd); -BOOL wayland_client_surface_release(struct wayland_client_surface *client); void wayland_client_surface_attach(struct wayland_client_surface *client, HWND toplevel); -void wayland_client_surface_detach(struct wayland_client_surface *client); void wayland_surface_ensure_contents(struct wayland_surface *surface); void wayland_surface_set_title(struct wayland_surface *surface, LPCWSTR title); void wayland_surface_set_icon(struct wayland_surface *surface, UINT type, ICONINFO *ii); diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index c84c35153c1..1beeb43a6e2 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -207,7 +207,7 @@ static BOOL wayland_win_data_create_wayland_surface(struct wayland_win_data *dat /* we can temporarily clear the role of a surface but cannot assign a different one after it's set */ if ((surface = data->wayland_surface) && role && surface->role && surface->role != role) { - if (client) wayland_client_surface_detach(client); + if (client) wayland_client_surface_attach(client, NULL); wayland_surface_destroy(data->wayland_surface); data->wayland_surface = NULL; } @@ -481,7 +481,7 @@ void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, HWND owner_hint, UIN if (toplevel && NtUserIsWindowVisible(hwnd)) wayland_client_surface_attach(client, toplevel); else - wayland_client_surface_detach(client); + wayland_client_surface_attach(client, NULL); }
if (data->wayland_surface) @@ -821,14 +821,14 @@ void set_client_surface(HWND hwnd, struct wayland_client_surface *new_client) if (new_client != data->client_surface) { if ((old_client = data->client_surface)) - wayland_client_surface_detach(old_client); + wayland_client_surface_attach(old_client, NULL);
if ((data->client_surface = new_client)) { if (toplevel && NtUserIsWindowVisible(hwnd)) wayland_client_surface_attach(new_client, toplevel); else - wayland_client_surface_detach(new_client); + wayland_client_surface_attach(new_client, NULL); } }