Finally allowing win32u to manage client surfaces for GL/VK directly.
-- v2: win32u: Replace opengl drawables tracking with client surfaces. winex11: Create client surfaces for opengl drawables. winex11: Move client surface code out of vulkan ifdef. winewayland: Merge the vulkan client surface with wayland_client_surface. winewayland: Clear the current client surface on vulkan detach.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/vulkan.c | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 473612ae5b6..ac42bf9e14d 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -67,17 +67,6 @@ static VkBool32 (*pvkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalD static const struct client_surface_funcs wayland_vulkan_surface_funcs; static const struct vulkan_driver_funcs wayland_vulkan_driver_funcs;
-static void wine_vk_surface_destroy(struct wayland_client_surface *client) -{ - HWND hwnd = wl_surface_get_user_data(client->wl_surface); - struct wayland_win_data *data = wayland_win_data_get(hwnd); - - if (wayland_client_surface_release(client) && data) - data->client_surface = NULL; - - if (data) wayland_win_data_release(data); -} - static VkResult wayland_vulkan_surface_create(HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *handle, struct client_surface **client) { @@ -124,11 +113,21 @@ static void wayland_vulkan_surface_destroy(struct client_surface *client)
TRACE("%s\n", debugstr_client_surface(client));
- if (surface->wayland_client) wine_vk_surface_destroy(surface->wayland_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)
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); } }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/init.c | 187 ++++++++++++++++++++++++++++++++++++++ dlls/winex11.drv/vulkan.c | 186 +------------------------------------ dlls/winex11.drv/x11drv.h | 1 + 3 files changed, 191 insertions(+), 183 deletions(-)
diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 125b3583a1b..4806bd835a3 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -31,6 +31,7 @@ #include "winbase.h" #include "winreg.h" #include "x11drv.h" +#include "xcomposite.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(x11drv); @@ -255,6 +256,192 @@ HRGN get_dc_monitor_region( HWND hwnd, HDC hdc ) return 0; }
+static const struct client_surface_funcs x11drv_client_surface_funcs; + +struct x11drv_client_surface +{ + struct client_surface client; + Window window; + RECT rect; + + HDC hdc_src; + HDC hdc_dst; +}; + +static struct x11drv_client_surface *impl_from_client_surface( struct client_surface *client ) +{ + return CONTAINING_RECORD( client, struct x11drv_client_surface, client ); +} + +static void x11drv_client_surface_destroy( struct client_surface *client ) +{ + struct x11drv_client_surface *surface = impl_from_client_surface( client ); + HWND hwnd = client->hwnd; + + TRACE( "%s\n", debugstr_client_surface( client ) ); + + if (surface->window) destroy_client_window( hwnd, surface->window ); + if (surface->hdc_dst) NtGdiDeleteObjectApp( surface->hdc_dst ); + if (surface->hdc_src) NtGdiDeleteObjectApp( surface->hdc_src ); +} + +static void x11drv_client_surface_detach( struct client_surface *client ) +{ + struct x11drv_client_surface *surface = impl_from_client_surface( client ); + Window client_window = surface->window; + struct x11drv_win_data *data; + HWND hwnd = client->hwnd; + + TRACE( "%s\n", debugstr_client_surface( client ) ); + + if ((data = get_win_data( hwnd ))) + { + detach_client_window( data, client_window ); + release_win_data( data ); + } +} + +static void client_surface_update_size( HWND hwnd, struct x11drv_client_surface *surface ) +{ + XWindowChanges changes; + RECT rect; + + NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) ); + if (EqualRect( &surface->rect, &rect )) return; + + changes.width = min( max( 1, rect.right ), 65535 ); + changes.height = min( max( 1, rect.bottom ), 65535 ); + XConfigureWindow( gdi_display, surface->window, CWWidth | CWHeight, &changes ); + surface->rect = rect; +} + +static void client_surface_update_offscreen( HWND hwnd, struct x11drv_client_surface *surface ) +{ + BOOL offscreen = needs_offscreen_rendering( hwnd ); + struct x11drv_win_data *data; + + if (InterlockedExchange(&surface->client.offscreen, offscreen) == offscreen) + { + if (!offscreen && (data = get_win_data( hwnd ))) + { + attach_client_window( data, surface->window ); + release_win_data( data ); + } + return; + } + + if (!offscreen) + { +#ifdef SONAME_LIBXCOMPOSITE + if (usexcomposite) pXCompositeUnredirectWindow( gdi_display, surface->window, CompositeRedirectManual ); +#endif + if (surface->hdc_dst) + { + NtGdiDeleteObjectApp( surface->hdc_dst ); + surface->hdc_dst = NULL; + } + if (surface->hdc_src) + { + NtGdiDeleteObjectApp( surface->hdc_src ); + surface->hdc_src = NULL; + } + } + else + { + static const WCHAR displayW[] = {'D','I','S','P','L','A','Y'}; + UNICODE_STRING device_str = RTL_CONSTANT_STRING(displayW); + surface->hdc_dst = NtGdiOpenDCW( &device_str, NULL, NULL, 0, TRUE, NULL, NULL, NULL ); + surface->hdc_src = NtGdiOpenDCW( &device_str, NULL, NULL, 0, TRUE, NULL, NULL, NULL ); + set_dc_drawable( surface->hdc_src, surface->window, &surface->rect, IncludeInferiors ); +#ifdef SONAME_LIBXCOMPOSITE + if (usexcomposite) pXCompositeRedirectWindow( gdi_display, surface->window, CompositeRedirectManual ); +#endif + } + + if ((data = get_win_data( hwnd ))) + { + if (offscreen) detach_client_window( data, surface->window ); + else attach_client_window( data, surface->window ); + release_win_data( data ); + } +} + +static void x11drv_client_surface_update( struct client_surface *client ) +{ + struct x11drv_client_surface *surface = impl_from_client_surface( client ); + HWND hwnd = client->hwnd; + + TRACE( "%s\n", debugstr_client_surface( client ) ); + + client_surface_update_size( hwnd, surface ); + client_surface_update_offscreen( hwnd, surface ); +} + +static void X11DRV_client_surface_present( struct client_surface *client, HDC hdc ) +{ + struct x11drv_client_surface *surface = impl_from_client_surface( client ); + HWND hwnd = client->hwnd, toplevel = NtUserGetAncestor( hwnd, GA_ROOT ); + struct x11drv_win_data *data; + RECT rect_dst, rect; + Drawable window; + HRGN region; + + client_surface_update_size( hwnd, surface ); + client_surface_update_offscreen( hwnd, surface ); + + if (!hdc) return; + window = X11DRV_get_whole_window( toplevel ); + region = get_dc_monitor_region( hwnd, hdc ); + + NtUserGetClientRect( hwnd, &rect_dst, NtUserGetWinMonitorDpi( hwnd, MDT_RAW_DPI ) ); + NtUserMapWindowPoints( hwnd, toplevel, (POINT *)&rect_dst, 2, NtUserGetWinMonitorDpi( hwnd, MDT_RAW_DPI ) ); + + if ((data = get_win_data( toplevel ))) + { + OffsetRect( &rect_dst, data->rects.client.left - data->rects.visible.left, + data->rects.client.top - data->rects.visible.top ); + release_win_data( data ); + } + + if (get_dc_drawable( surface->hdc_dst, &rect ) != window || !EqualRect( &rect, &rect_dst )) + set_dc_drawable( surface->hdc_dst, window, &rect_dst, IncludeInferiors ); + if (region) NtGdiExtSelectClipRgn( surface->hdc_dst, region, RGN_COPY ); + + NtGdiStretchBlt( surface->hdc_dst, 0, 0, rect_dst.right - rect_dst.left, rect_dst.bottom - rect_dst.top, + surface->hdc_src, 0, 0, surface->rect.right, surface->rect.bottom, SRCCOPY, 0 ); + + if (region) NtGdiDeleteObjectApp( region ); +} + +static const struct client_surface_funcs x11drv_client_surface_funcs = +{ + .destroy = x11drv_client_surface_destroy, + .detach = x11drv_client_surface_detach, + .update = x11drv_client_surface_update, + .present = X11DRV_client_surface_present, +}; + +Window x11drv_client_surface_create( HWND hwnd, struct client_surface **client ) +{ + struct x11drv_client_surface *surface; + + if (!(surface = client_surface_create( sizeof(*surface), &x11drv_client_surface_funcs, hwnd ))) + { + ERR("Failed to allocate vulkan surface for hwnd=%p\n", hwnd); + return None; + } + if (!(surface->window = create_client_window( hwnd, &default_visual, default_colormap ))) + { + ERR("Failed to allocate client window for hwnd=%p\n", hwnd); + client_surface_release( &surface->client ); + return None; + } + NtUserGetClientRect( hwnd, &surface->rect, NtUserGetDpiForWindow( hwnd ) ); + + *client = &surface->client; + return surface->window; +} + /********************************************************************** * ExtEscape (X11DRV.@) */ diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index ee72e5ed69a..407df86169e 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -61,22 +61,6 @@ static VkResult (*pvkCreateXlibSurfaceKHR)(VkInstance, const VkXlibSurfaceCreate static VkBool32 (*pvkGetPhysicalDeviceXlibPresentationSupportKHR)(VkPhysicalDevice, uint32_t, Display *, VisualID);
static const struct vulkan_driver_funcs x11drv_vulkan_driver_funcs; -static const struct client_surface_funcs x11drv_vulkan_surface_funcs; - -struct x11drv_vulkan_surface -{ - struct client_surface client; - Window window; - RECT rect; - - HDC hdc_src; - HDC hdc_dst; -}; - -static struct x11drv_vulkan_surface *impl_from_client_surface( struct client_surface *client ) -{ - return CONTAINING_RECORD( client, struct x11drv_vulkan_surface, client ); -}
static VkResult X11DRV_vulkan_surface_create( HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *handle, struct client_surface **client ) @@ -86,177 +70,21 @@ static VkResult X11DRV_vulkan_surface_create( HWND hwnd, const struct vulkan_ins .sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, .dpy = gdi_display, }; - struct x11drv_vulkan_surface *surface;
TRACE( "%p %p %p %p\n", hwnd, instance, handle, client );
- if (!(surface = client_surface_create( sizeof(*surface), &x11drv_vulkan_surface_funcs, hwnd ))) - { - ERR("Failed to allocate vulkan surface for hwnd=%p\n", hwnd); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - if (!(surface->window = create_client_window( hwnd, &default_visual, default_colormap ))) - { - ERR("Failed to allocate client window for hwnd=%p\n", hwnd); - client_surface_release( &surface->client ); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - NtUserGetClientRect( hwnd, &surface->rect, NtUserGetDpiForWindow( hwnd ) ); - - info.window = surface->window; + if (!(info.window = x11drv_client_surface_create( hwnd, client ))) return VK_ERROR_OUT_OF_HOST_MEMORY; if (pvkCreateXlibSurfaceKHR( instance->host.instance, &info, NULL /* allocator */, handle )) { ERR("Failed to create Xlib surface\n"); - client_surface_release( &surface->client ); + client_surface_release( *client ); return VK_ERROR_OUT_OF_HOST_MEMORY; }
- *client = &surface->client; - - TRACE( "Created surface 0x%s, client %p\n", wine_dbgstr_longlong( *handle ), *client ); + TRACE( "Created surface 0x%s, client %s\n", wine_dbgstr_longlong( *handle ), debugstr_client_surface( *client ) ); return VK_SUCCESS; }
-static void x11drv_vulkan_surface_destroy( struct client_surface *client ) -{ - struct x11drv_vulkan_surface *surface = impl_from_client_surface( client ); - HWND hwnd = client->hwnd; - - TRACE( "%s\n", debugstr_client_surface( client ) ); - - if (surface->window) destroy_client_window( hwnd, surface->window ); - if (surface->hdc_dst) NtGdiDeleteObjectApp( surface->hdc_dst ); - if (surface->hdc_src) NtGdiDeleteObjectApp( surface->hdc_src ); -} - -static void x11drv_vulkan_surface_detach( struct client_surface *client ) -{ - struct x11drv_vulkan_surface *surface = impl_from_client_surface( client ); - Window client_window = surface->window; - struct x11drv_win_data *data; - HWND hwnd = client->hwnd; - - TRACE( "%s\n", debugstr_client_surface( client ) ); - - if ((data = get_win_data( hwnd ))) - { - detach_client_window( data, client_window ); - release_win_data( data ); - } -} - -static void vulkan_surface_update_size( HWND hwnd, struct x11drv_vulkan_surface *surface ) -{ - XWindowChanges changes; - RECT rect; - - NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) ); - if (EqualRect( &surface->rect, &rect )) return; - - changes.width = min( max( 1, rect.right ), 65535 ); - changes.height = min( max( 1, rect.bottom ), 65535 ); - XConfigureWindow( gdi_display, surface->window, CWWidth | CWHeight, &changes ); - surface->rect = rect; -} - -static void vulkan_surface_update_offscreen( HWND hwnd, struct x11drv_vulkan_surface *surface ) -{ - BOOL offscreen = needs_offscreen_rendering( hwnd ); - struct x11drv_win_data *data; - - if (InterlockedExchange(&surface->client.offscreen, offscreen) == offscreen) - { - if (!offscreen && (data = get_win_data( hwnd ))) - { - attach_client_window( data, surface->window ); - release_win_data( data ); - } - return; - } - - if (!offscreen) - { -#ifdef SONAME_LIBXCOMPOSITE - if (usexcomposite) pXCompositeUnredirectWindow( gdi_display, surface->window, CompositeRedirectManual ); -#endif - if (surface->hdc_dst) - { - NtGdiDeleteObjectApp( surface->hdc_dst ); - surface->hdc_dst = NULL; - } - if (surface->hdc_src) - { - NtGdiDeleteObjectApp( surface->hdc_src ); - surface->hdc_src = NULL; - } - } - else - { - static const WCHAR displayW[] = {'D','I','S','P','L','A','Y'}; - UNICODE_STRING device_str = RTL_CONSTANT_STRING(displayW); - surface->hdc_dst = NtGdiOpenDCW( &device_str, NULL, NULL, 0, TRUE, NULL, NULL, NULL ); - surface->hdc_src = NtGdiOpenDCW( &device_str, NULL, NULL, 0, TRUE, NULL, NULL, NULL ); - set_dc_drawable( surface->hdc_src, surface->window, &surface->rect, IncludeInferiors ); -#ifdef SONAME_LIBXCOMPOSITE - if (usexcomposite) pXCompositeRedirectWindow( gdi_display, surface->window, CompositeRedirectManual ); -#endif - } - - if ((data = get_win_data( hwnd ))) - { - if (offscreen) detach_client_window( data, surface->window ); - else attach_client_window( data, surface->window ); - release_win_data( data ); - } -} - -static void x11drv_vulkan_surface_update( struct client_surface *client ) -{ - struct x11drv_vulkan_surface *surface = impl_from_client_surface( client ); - HWND hwnd = client->hwnd; - - TRACE( "%s\n", debugstr_client_surface( client ) ); - - vulkan_surface_update_size( hwnd, surface ); - vulkan_surface_update_offscreen( hwnd, surface ); -} - -static void X11DRV_vulkan_surface_present( struct client_surface *client, HDC hdc ) -{ - struct x11drv_vulkan_surface *surface = impl_from_client_surface( client ); - HWND hwnd = client->hwnd, toplevel = NtUserGetAncestor( hwnd, GA_ROOT ); - struct x11drv_win_data *data; - RECT rect_dst, rect; - Drawable window; - HRGN region; - - vulkan_surface_update_size( hwnd, surface ); - vulkan_surface_update_offscreen( hwnd, surface ); - - if (!hdc) return; - window = X11DRV_get_whole_window( toplevel ); - region = get_dc_monitor_region( hwnd, hdc ); - - NtUserGetClientRect( hwnd, &rect_dst, NtUserGetWinMonitorDpi( hwnd, MDT_RAW_DPI ) ); - NtUserMapWindowPoints( hwnd, toplevel, (POINT *)&rect_dst, 2, NtUserGetWinMonitorDpi( hwnd, MDT_RAW_DPI ) ); - - if ((data = get_win_data( toplevel ))) - { - OffsetRect( &rect_dst, data->rects.client.left - data->rects.visible.left, - data->rects.client.top - data->rects.visible.top ); - release_win_data( data ); - } - - if (get_dc_drawable( surface->hdc_dst, &rect ) != window || !EqualRect( &rect, &rect_dst )) - set_dc_drawable( surface->hdc_dst, window, &rect_dst, IncludeInferiors ); - if (region) NtGdiExtSelectClipRgn( surface->hdc_dst, region, RGN_COPY ); - - NtGdiStretchBlt( surface->hdc_dst, 0, 0, rect_dst.right - rect_dst.left, rect_dst.bottom - rect_dst.top, - surface->hdc_src, 0, 0, surface->rect.right, surface->rect.bottom, SRCCOPY, 0 ); - - if (region) NtGdiDeleteObjectApp( region ); -} - static VkBool32 X11DRV_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev, uint32_t index) { @@ -271,14 +99,6 @@ static const char *X11DRV_get_host_surface_extension(void) return "VK_KHR_xlib_surface"; }
-static const struct client_surface_funcs x11drv_vulkan_surface_funcs = -{ - .destroy = x11drv_vulkan_surface_destroy, - .detach = x11drv_vulkan_surface_detach, - .update = x11drv_vulkan_surface_update, - .present = X11DRV_vulkan_surface_present, -}; - static const struct vulkan_driver_funcs x11drv_vulkan_driver_funcs = { .p_vulkan_surface_create = X11DRV_vulkan_surface_create, diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index dfca33dcc97..1b24ad918f9 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -359,6 +359,7 @@ 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 ); +extern Window x11drv_client_surface_create( HWND hwnd, struct client_surface **client );
/************************************************************************** * X11 USER driver
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/opengl.c | 185 +++++++++----------------------------- 1 file changed, 44 insertions(+), 141 deletions(-)
diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index f841a45651c..7e9e253a373 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -197,9 +197,9 @@ struct glx_pixel_format struct gl_drawable { struct opengl_drawable base; + struct client_surface *client; RECT rect; /* current size of the GL drawable */ GLXDrawable drawable; /* drawable for rendering with GL */ - Window window; /* window if drawable is a GLXWindow */ Colormap colormap; /* colormap for the client window */ Pixmap pixmap; /* base pixmap if drawable is a GLXPixmap */ BOOL offscreen; @@ -489,6 +489,7 @@ static BOOL x11drv_egl_surface_create( HWND hwnd, HDC hdc, int format, struct op { struct opengl_drawable *previous; struct gl_drawable *gl; + Window window; RECT rect;
if ((previous = *drawable) && previous->format == format) return TRUE; @@ -498,16 +499,21 @@ static BOOL x11drv_egl_surface_create( HWND hwnd, HDC hdc, int format, struct op gl->rect = rect; gl->hdc = hdc;
- gl->window = create_client_window( hwnd, &default_visual, default_colormap ); + if (!(window = x11drv_client_surface_create(hwnd, &gl->client))) + { + opengl_drawable_release( &gl->base ); + return FALSE; + } + gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(format), - (void *)gl->window, NULL ); + (void *)window, NULL ); if (!gl->base.surface) { opengl_drawable_release( &gl->base ); return FALSE; }
- TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), gl->window ); + TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), window ); XFlush( gdi_display );
if (previous) opengl_drawable_release( previous ); @@ -868,10 +874,10 @@ static void x11drv_surface_destroy( struct opengl_drawable *base ) TRACE( "drawable %s\n", debugstr_opengl_drawable( base ) );
if (gl->drawable) pglXDestroyWindow( gdi_display, gl->drawable ); - if (gl->window) destroy_client_window( gl->base.hwnd, gl->window ); if (gl->colormap) XFreeColormap( gdi_display, gl->colormap ); if (gl->hdc_src) NtGdiDeleteObjectApp( gl->hdc_src ); if (gl->hdc_dst) NtGdiDeleteObjectApp( gl->hdc_dst ); + if (gl->client) client_surface_release( gl->client ); }
static BOOL set_swap_interval( struct gl_drawable *gl, int interval ) @@ -930,6 +936,7 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); struct opengl_drawable *previous; struct gl_drawable *gl; + Window window; RECT rect;
if ((previous = *drawable) && previous->format == format) return TRUE; @@ -939,19 +946,22 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl gl->rect = rect; gl->hdc = hdc;
+ if (!(window = x11drv_client_surface_create(hwnd, &gl->client))) + { + opengl_drawable_release( &gl->base ); + return FALSE; + } + gl->colormap = XCreateColormap( gdi_display, get_dummy_parent(), fmt->visual->visual, (fmt->visual->class == PseudoColor || fmt->visual->class == GrayScale || fmt->visual->class == DirectColor) ? AllocAll : AllocNone ); - gl->window = create_client_window( hwnd, fmt->visual, gl->colormap ); - if (gl->window) gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, gl->window, NULL ); - - if (!gl->drawable) + if (!(gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, window, NULL ))) { opengl_drawable_release( &gl->base ); return FALSE; }
- TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), gl->window ); + TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), window ); XFlush( gdi_display );
if (previous) opengl_drawable_release( previous ); @@ -959,83 +969,11 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl return TRUE; }
-static void update_gl_drawable_size( struct gl_drawable *gl ) -{ - XWindowChanges changes; - RECT rect = {0}; - - NtUserGetClientRect( gl->base.hwnd, &rect, NtUserGetDpiForWindow( gl->base.hwnd ) ); - if (EqualRect( &gl->rect, &rect )) return; - - changes.width = min( max( 1, rect.right ), 65535 ); - changes.height = min( max( 1, rect.bottom ), 65535 ); - 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->base.hwnd ); - struct x11drv_win_data *data; - - if (offscreen == gl->offscreen) - { - if (!offscreen && (data = get_win_data( gl->base.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->base.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->base.hwnd ))) - { - if (gl->offscreen) detach_client_window( data, gl->window ); - else attach_client_window( data, gl->window ); - release_win_data( data ); - } -} - static void x11drv_surface_update( struct opengl_drawable *base ) { - struct gl_drawable *gl = impl_from_opengl_drawable( base ); - - update_gl_drawable_size( gl ); - update_gl_drawable_offscreen( gl ); + TRACE( "%s\n", debugstr_opengl_drawable( base ) ); }
- static void x11drv_surface_detach( struct opengl_drawable *base ) { TRACE( "%s\n", debugstr_opengl_drawable( base ) ); @@ -1259,42 +1197,6 @@ static BOOL x11drv_make_current( struct opengl_drawable *draw_base, struct openg return ret; }
-static void present_gl_drawable( struct gl_drawable *gl, BOOL flush, BOOL gl_finish ) -{ - HWND hwnd = gl->base.hwnd, toplevel = NtUserGetAncestor( hwnd, GA_ROOT ); - struct x11drv_win_data *data; - Drawable window; - RECT rect_dst, rect; - HRGN region; - - if (!gl->offscreen) return; - - window = get_dc_drawable( gl->hdc, &rect ); - region = get_dc_monitor_region( hwnd, gl->hdc ); - - if (gl_finish) funcs->p_glFinish(); - if (flush) XFlush( gdi_display ); - - NtUserGetClientRect( hwnd, &rect_dst, NtUserGetWinMonitorDpi( hwnd, MDT_RAW_DPI ) ); - NtUserMapWindowPoints( hwnd, toplevel, (POINT *)&rect_dst, 2, NtUserGetWinMonitorDpi( hwnd, MDT_RAW_DPI ) ); - - if ((data = get_win_data( toplevel ))) - { - OffsetRect( &rect_dst, data->rects.client.left - data->rects.visible.left, - data->rects.client.top - data->rects.visible.top ); - release_win_data( data ); - } - - if (get_dc_drawable( gl->hdc_dst, &rect ) != window || !EqualRect( &rect, &rect_dst )) - set_dc_drawable( gl->hdc_dst, window, &rect_dst, IncludeInferiors ); - if (region) NtGdiExtSelectClipRgn( gl->hdc_dst, region, RGN_COPY ); - - NtGdiStretchBlt( gl->hdc_dst, 0, 0, rect_dst.right - rect_dst.left, rect_dst.bottom - rect_dst.top, - gl->hdc_src, 0, 0, gl->rect.right, gl->rect.bottom, SRCCOPY, 0 ); - - if (region) NtGdiDeleteObjectApp( region ); -} - static void x11drv_surface_flush( struct opengl_drawable *base, UINT flags ) { struct gl_drawable *gl = impl_from_opengl_drawable( base ); @@ -1303,10 +1205,12 @@ static void x11drv_surface_flush( struct opengl_drawable *base, UINT flags )
if (flags & GL_FLUSH_INTERVAL) set_swap_interval( gl, base->interval );
- update_gl_drawable_size( gl ); - update_gl_drawable_offscreen( gl ); - - present_gl_drawable( gl, TRUE, !(flags & GL_FLUSH_FINISHED) ); + if (InterlockedCompareExchange( &gl->client->offscreen, 0, 0 )) + { + if (!(flags & GL_FLUSH_FINISHED)) funcs->p_glFinish(); + XFlush( gdi_display ); + client_surface_present( gl->client, gl->hdc ); + } }
/*********************************************************************** @@ -1568,10 +1472,12 @@ static BOOL x11drv_surface_swap( struct opengl_drawable *base ) if (pglXWaitForSbcOML) pglXWaitForSbcOML( gdi_display, gl->drawable, target_sbc, &ust, &msc, &sbc ); }
- update_gl_drawable_size( gl ); - update_gl_drawable_offscreen( gl ); + if (InterlockedCompareExchange( &gl->client->offscreen, 0, 0 )) + { + if (!pglXWaitForSbcOML) XFlush( gdi_display ); + client_surface_present( gl->client, gl->hdc ); + }
- present_gl_drawable( gl, !pglXWaitForSbcOML, FALSE ); return TRUE; }
@@ -1579,9 +1485,9 @@ static void x11drv_egl_surface_destroy( struct opengl_drawable *base ) { struct gl_drawable *gl = impl_from_opengl_drawable( base );
- TRACE( "drawable %s\n", debugstr_opengl_drawable( base ) ); + TRACE( "%s\n", debugstr_opengl_drawable( base ) );
- destroy_client_window( gl->base.hwnd, gl->window ); + if (gl->client) client_surface_release( gl->client ); }
static void x11drv_egl_surface_detach( struct opengl_drawable *base ) @@ -1591,12 +1497,7 @@ static void x11drv_egl_surface_detach( struct opengl_drawable *base )
static void x11drv_egl_surface_update( struct opengl_drawable *base ) { - struct gl_drawable *gl = impl_from_opengl_drawable( base ); - TRACE( "%s\n", debugstr_opengl_drawable( base ) ); - - update_gl_drawable_size( gl ); - update_gl_drawable_offscreen( gl ); }
static void x11drv_egl_surface_flush( struct opengl_drawable *base, UINT flags ) @@ -1606,13 +1507,13 @@ static void x11drv_egl_surface_flush( struct opengl_drawable *base, UINT flags ) TRACE( "%s\n", debugstr_opengl_drawable( base ) );
if (flags & GL_FLUSH_INTERVAL) funcs->p_eglSwapInterval( egl->display, abs( base->interval ) ); - if (flags & GL_FLUSH_UPDATED) + + if (InterlockedCompareExchange( &gl->client->offscreen, 0, 0 )) { - update_gl_drawable_size( gl ); - update_gl_drawable_offscreen( gl ); + if (!(flags & GL_FLUSH_FINISHED)) funcs->p_glFinish(); + XFlush( gdi_display ); + client_surface_present( gl->client, gl->hdc ); } - - present_gl_drawable( gl, TRUE, !(flags & GL_FLUSH_FINISHED) ); }
static BOOL x11drv_egl_surface_swap( struct opengl_drawable *base ) @@ -1623,10 +1524,12 @@ static BOOL x11drv_egl_surface_swap( struct opengl_drawable *base )
funcs->p_eglSwapBuffers( egl->display, gl->base.surface );
- update_gl_drawable_size( gl ); - update_gl_drawable_offscreen( gl ); + if (InterlockedCompareExchange( &gl->client->offscreen, 0, 0 )) + { + XFlush( gdi_display ); + client_surface_present( gl->client, gl->hdc ); + }
- present_gl_drawable( gl, TRUE, FALSE ); return TRUE; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/ntuser_private.h | 4 -- dlls/win32u/opengl.c | 76 +++------------------------------ dlls/win32u/window.c | 3 -- dlls/wineandroid.drv/opengl.c | 45 ++++++++++++++------ dlls/winemac.drv/opengl.c | 78 +++++++++++++++++++++------------- dlls/winewayland.drv/opengl.c | 35 +++++---------- dlls/winex11.drv/opengl.c | 80 ++++++++++------------------------- include/wine/opengl_driver.h | 21 +++------ 8 files changed, 126 insertions(+), 216 deletions(-)
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h index f87cc191d18..27a723b4c2f 100644 --- a/dlls/win32u/ntuser_private.h +++ b/dlls/win32u/ntuser_private.h @@ -221,10 +221,6 @@ extern PFN_vkGetInstanceProcAddr p_vkGetInstanceProcAddr;
extern BOOL vulkan_init(void);
-/* opengl.c */ -extern void update_opengl_drawables( HWND hwnd ); -extern void detach_opengl_drawables( HWND hwnd ); - /* window.c */ HANDLE alloc_user_handle( void *ptr, unsigned short type ); void *free_user_handle( HANDLE handle, unsigned short type ); diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 6ed8ac1010e..f27143f3357 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -163,54 +163,7 @@ static void register_extension( char *list, size_t size, const char *name ) } }
-static pthread_mutex_t drawables_lock = PTHREAD_MUTEX_INITIALIZER; -static struct list drawables = LIST_INIT( drawables ); - -void detach_opengl_drawables( HWND hwnd ) -{ - struct list detached = LIST_INIT( detached ); - struct opengl_drawable *drawable, *next; - - pthread_mutex_lock( &drawables_lock ); - - LIST_FOR_EACH_ENTRY_SAFE( drawable, next, &drawables, struct opengl_drawable, entry ) - { - if (drawable->hwnd != hwnd) continue; - - list_remove( &drawable->entry ); - list_add_tail( &detached, &drawable->entry ); - opengl_drawable_add_ref( drawable ); - - drawable->funcs->detach( drawable ); - drawable->hwnd = NULL; - } - - pthread_mutex_unlock( &drawables_lock ); - - LIST_FOR_EACH_ENTRY_SAFE( drawable, next, &detached, struct opengl_drawable, entry ) - { - list_remove( &drawable->entry ); - opengl_drawable_release( drawable ); - } -} - -void update_opengl_drawables( HWND hwnd ) -{ - struct opengl_drawable *drawable, *next; - - pthread_mutex_lock( &drawables_lock ); - - LIST_FOR_EACH_ENTRY_SAFE( drawable, next, &drawables, struct opengl_drawable, entry ) - { - if (drawable->hwnd != hwnd) continue; - drawable->funcs->update( drawable ); - InterlockedExchange( &drawable->updated, 1 ); - } - - pthread_mutex_unlock( &drawables_lock ); -} - -void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, HWND hwnd ) +void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, struct client_surface *client ) { struct opengl_drawable *drawable;
@@ -220,15 +173,7 @@ void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *fun
drawable->format = format; drawable->interval = INT_MIN; - drawable->hwnd = hwnd; - - if (!hwnd) list_init( &drawable->entry ); /* pbuffer, keep it unlinked */ - else - { - pthread_mutex_lock( &drawables_lock ); - list_add_tail( &drawables, &drawable->entry ); - pthread_mutex_unlock( &drawables_lock ); - } + if ((drawable->client = client)) client_surface_add_ref( client );
TRACE( "created %s\n", debugstr_opengl_drawable( drawable ) ); return drawable; @@ -250,25 +195,18 @@ void opengl_drawable_release( struct opengl_drawable *drawable ) const struct opengl_funcs *funcs = &display_funcs; const struct egl_platform *egl = &display_egl;
- pthread_mutex_lock( &drawables_lock ); - if (drawable->hwnd) - { - drawable->funcs->detach( drawable ); - list_remove( &drawable->entry ); - } - pthread_mutex_unlock( &drawables_lock ); - drawable->funcs->destroy( drawable ); if (drawable->surface) funcs->p_eglDestroySurface( egl->display, drawable->surface ); + if (drawable->client) client_surface_release( drawable->client ); free( drawable ); } }
static void opengl_drawable_flush( struct opengl_drawable *drawable, int interval, UINT flags ) { - if (!drawable->hwnd) return; + if (!drawable->client) return;
- if (InterlockedCompareExchange( &drawable->updated, 0, 1 )) flags |= GL_FLUSH_UPDATED; + if (InterlockedCompareExchange( &drawable->client->updated, 0, 1 )) flags |= GL_FLUSH_UPDATED; if (interval != drawable->interval) { drawable->interval = interval; @@ -553,7 +491,7 @@ static BOOL egldrv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex } *attrib++ = EGL_NONE;
- if (!(gl = opengl_drawable_create( sizeof(*gl), &egldrv_pbuffer_funcs, format, 0 ))) return FALSE; + if (!(gl = opengl_drawable_create( sizeof(*gl), &egldrv_pbuffer_funcs, format, NULL ))) return FALSE; if (!(gl->surface = funcs->p_eglCreatePbufferSurface( egl->display, egl_config_for_format( egl, gl->format ), attribs ))) { opengl_drawable_release( gl ); @@ -1749,7 +1687,7 @@ static BOOL win32u_wglSwapBuffers( HDC hdc )
if (!(draw = get_dc_opengl_drawable( draw_hdc, FALSE ))) return FALSE; opengl_drawable_flush( draw, interval, 0 ); - if (!draw->hwnd) ret = FALSE; /* pbuffer, nothing to do */ + if (!draw->client) ret = FALSE; /* pbuffer, nothing to do */ else ret = draw->funcs->swap( draw ); opengl_drawable_release( draw );
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 47cded6ec4e..4a9e817c7e4 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2256,7 +2256,6 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, stru
user_driver->pWindowPosChanged( hwnd, insert_after, owner_hint, swp_flags, is_fullscreen, &monitor_rects, get_driver_window_surface( new_surface, raw_dpi ) ); - update_opengl_drawables( hwnd ); update_client_surfaces( hwnd );
update_children_window_state( hwnd ); @@ -5191,7 +5190,6 @@ LRESULT destroy_window( HWND hwnd ) window_surface_release( surface ); }
- detach_opengl_drawables( hwnd ); detach_client_surfaces( hwnd ); if (win->opengl_drawable) opengl_drawable_release( win->opengl_drawable ); user_driver->pDestroyWindow( hwnd ); @@ -5347,7 +5345,6 @@ void destroy_thread_windows(void) free_list = entry->next; TRACE( "destroying %p\n", entry );
- detach_opengl_drawables( entry->handle ); detach_client_surfaces( entry->handle ); user_driver->pDestroyWindow( entry->handle ); if (entry->opengl_drawable) opengl_drawable_release( entry->opengl_drawable ); diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index e5f660c2be4..25e6751c744 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -48,6 +48,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(android);
static const struct egl_platform *egl; static const struct opengl_funcs *funcs; +static const struct client_surface_funcs android_client_surface_funcs; static const struct opengl_drawable_funcs android_drawable_funcs;
struct gl_drawable @@ -73,9 +74,13 @@ static inline EGLConfig egl_config_for_format(int format) static struct gl_drawable *create_gl_drawable( HWND hwnd, HDC hdc, int format, ANativeWindow *window ) { static const int attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; + struct client_surface *client; struct gl_drawable *gl;
- if (!(gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, hwnd ))) return NULL; + if (!(client = client_surface_create( sizeof(*client), &android_client_surface_funcs, hwnd ))) return NULL; + gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, client ); + client_surface_release( client ); + if (!gl) return NULL;
if (!window) gl->window = create_ioctl_window( hwnd, TRUE, 1.0f ); else gl->window = grab_ioctl_window( window ); @@ -93,16 +98,6 @@ static void android_drawable_destroy( struct opengl_drawable *base ) release_ioctl_window( gl->window ); }
-static void android_drawable_detach( struct opengl_drawable *base ) -{ - TRACE( "%s\n", debugstr_opengl_drawable( base ) ); -} - -static void android_drawable_update( struct opengl_drawable *base ) -{ - TRACE( "%s\n", debugstr_opengl_drawable( base ) ); -} - void update_gl_drawable( HWND hwnd ) { struct gl_drawable *old, *new; @@ -133,7 +128,6 @@ static BOOL android_surface_create( HWND hwnd, HDC hdc, int format, struct openg gl = impl_from_opengl_drawable( *drawable ); funcs->p_eglGetConfigAttrib( egl->display, egl_config_for_format(format), EGL_NATIVE_VISUAL_ID, &pf ); gl->window->perform( gl->window, NATIVE_WINDOW_SET_BUFFERS_FORMAT, pf ); - gl->base.hwnd = hwnd; gl->base.format = format;
TRACE( "Updated drawable %s\n", debugstr_opengl_drawable( *drawable ) ); @@ -191,11 +185,34 @@ static struct opengl_driver_funcs android_driver_funcs = .p_surface_create = android_surface_create, };
+static void android_client_surface_destroy(struct client_surface *client) +{ + TRACE("%s\n", debugstr_client_surface(client)); +} + +static void android_client_surface_detach(struct client_surface *client) +{ +} + +static void android_client_surface_update(struct client_surface *client) +{ +} + +static void android_client_surface_present(struct client_surface *client, HDC hdc) +{ +} + +static const struct client_surface_funcs android_client_surface_funcs = +{ + .destroy = android_client_surface_destroy, + .detach = android_client_surface_detach, + .update = android_client_surface_update, + .present = android_client_surface_present, +}; + static const struct opengl_drawable_funcs android_drawable_funcs = { .destroy = android_drawable_destroy, - .detach = android_drawable_detach, - .update = android_drawable_update, .flush = android_drawable_flush, .swap = android_drawable_swap, }; diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index f48737c1b43..172b0d60226 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -96,6 +96,7 @@ static pthread_mutex_t context_mutex = PTHREAD_MUTEX_INITIALIZER; static void *opengl_handle; static const struct opengl_funcs *funcs; static const struct opengl_driver_funcs macdrv_driver_funcs; +static const struct client_surface_funcs macdrv_client_surface_funcs; static const struct opengl_drawable_funcs macdrv_surface_funcs; static const struct opengl_drawable_funcs macdrv_pbuffer_funcs;
@@ -1470,6 +1471,7 @@ static BOOL create_context(struct macdrv_context *context, CGLContextObj share,
static BOOL macdrv_surface_create(HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable) { + struct client_surface *client; struct macdrv_win_data *data; struct gl_drawable *gl;
@@ -1484,9 +1486,12 @@ static BOOL macdrv_surface_create(HWND hwnd, HDC hdc, int format, struct opengl_ data->pixel_format = format; release_win_data(data);
- if (!(gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, hwnd))) return FALSE; - *drawable = &gl->base; + if (!(client = client_surface_create(sizeof(*client), &macdrv_client_surface_funcs, hwnd))) return FALSE; + gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, client); + client_surface_release(client); + if (!gl) return FALSE;
+ *drawable = &gl->base; return TRUE; }
@@ -1511,21 +1516,6 @@ static void mark_contexts_for_moved_view(macdrv_view view) pthread_mutex_unlock(&context_mutex); }
-static void macdrv_surface_update(struct opengl_drawable *base) -{ - struct macdrv_win_data *data = get_win_data(base->hwnd); - - TRACE("%s\n", debugstr_opengl_drawable(base)); - - if (data->client_cocoa_view && data->pixel_format) - { - TRACE("GL view %p changed position; marking contexts\n", data->client_cocoa_view); - mark_contexts_for_moved_view(data->client_cocoa_view); - } - - release_win_data(data); -} - /********************************************************************** * sync_context_rect */ @@ -2085,11 +2075,6 @@ static void macdrv_glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, make_context_current(context, FALSE); }
-static void macdrv_surface_detach(struct opengl_drawable *base) -{ - TRACE("%s\n", debugstr_opengl_drawable(base)); -} - static void macdrv_surface_flush(struct opengl_drawable *base, UINT flags) { struct macdrv_context *context = NtCurrentTeb()->glReserved2; @@ -2357,7 +2342,7 @@ static BOOL macdrv_pbuffer_create(HDC hdc, int format, BOOL largest, GLenum text texture_format = GL_RGB; }
- if (!(gl = opengl_drawable_create(sizeof(*gl), &macdrv_pbuffer_funcs, format, 0))) return FALSE; + if (!(gl = opengl_drawable_create(sizeof(*gl), &macdrv_pbuffer_funcs, format, NULL))) return FALSE;
err = CGLCreatePBuffer(*width, *height, texture_target, texture_format, max_level, &gl->pbuffer); if (err != kCGLNoError) @@ -2386,7 +2371,6 @@ static BOOL macdrv_make_current(struct opengl_drawable *draw_base, struct opengl struct gl_drawable *draw = impl_from_opengl_drawable(draw_base), *read = impl_from_opengl_drawable(read_base); struct macdrv_context *context = private; struct macdrv_win_data *data; - HWND hwnd;
TRACE("draw %s, read %s, context %p\n", debugstr_opengl_drawable(draw_base), debugstr_opengl_drawable(read_base), private);
@@ -2397,8 +2381,9 @@ static BOOL macdrv_make_current(struct opengl_drawable *draw_base, struct opengl return TRUE; }
- if ((hwnd = draw->base.hwnd)) + if (draw->base.client) { + HWND hwnd = draw->base.client->hwnd; if (!(data = get_win_data(hwnd))) { FIXME("draw DC for window %p of other process: not implemented\n", hwnd); @@ -2424,8 +2409,9 @@ static BOOL macdrv_make_current(struct opengl_drawable *draw_base, struct opengl context->read_pbuffer = NULL; if (read != draw) { - if ((hwnd = read->base.hwnd)) + if (read->base.client) { + HWND hwnd = read->base.client->hwnd; if ((data = get_win_data(hwnd))) { if (data->client_cocoa_view != context->draw_view) @@ -2906,7 +2892,7 @@ static BOOL macdrv_surface_swap(struct opengl_drawable *base) { struct macdrv_context *context = NtCurrentTeb()->glReserved2; struct macdrv_win_data *data; - HWND hwnd = base->hwnd; + HWND hwnd = base->client->hwnd; BOOL match = FALSE;
TRACE("%s context %p/%p/%p\n", debugstr_opengl_drawable(base), context, (context ? context->context : NULL), @@ -2948,11 +2934,45 @@ static const struct opengl_driver_funcs macdrv_driver_funcs = .p_pbuffer_bind = macdrv_pbuffer_bind, };
+static void macdrv_client_surface_destroy(struct client_surface *client) +{ + TRACE("%s\n", debugstr_client_surface(client)); +} + +static void macdrv_client_surface_detach(struct client_surface *client) +{ +} + +static void macdrv_client_surface_update(struct client_surface *client) +{ + struct macdrv_win_data *data = get_win_data(client->hwnd); + + TRACE("%s\n", debugstr_client_surface(client)); + + if (data->client_cocoa_view && data->pixel_format) + { + TRACE("GL view %p changed position; marking contexts\n", data->client_cocoa_view); + mark_contexts_for_moved_view(data->client_cocoa_view); + } + + release_win_data(data); +} + +static void macdrv_client_surface_present(struct client_surface *client, HDC hdc) +{ +} + +static const struct client_surface_funcs macdrv_client_surface_funcs = +{ + .destroy = macdrv_client_surface_destroy, + .detach = macdrv_client_surface_detach, + .update = macdrv_client_surface_update, + .present = macdrv_client_surface_present, +}; + static const struct opengl_drawable_funcs macdrv_surface_funcs = { .destroy = macdrv_surface_destroy, - .detach = macdrv_surface_detach, - .update = macdrv_surface_update, .flush = macdrv_surface_flush, .swap = macdrv_surface_swap, }; diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index db510d2df97..c3ccfc93202 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -49,7 +49,6 @@ static const struct opengl_drawable_funcs wayland_drawable_funcs; struct wayland_gl_drawable { struct opengl_drawable base; - struct wayland_client_surface *client; struct wl_egl_window *wl_egl_window; };
@@ -61,23 +60,7 @@ static struct wayland_gl_drawable *impl_from_opengl_drawable(struct opengl_drawa static void wayland_drawable_destroy(struct opengl_drawable *base) { struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base); - if (gl->wl_egl_window) wl_egl_window_destroy(gl->wl_egl_window); - if (gl->client) - { - gl->client->client.funcs->detach( &gl->client->client ); - client_surface_release( &gl->client->client ); - } -} - -static void wayland_drawable_detach(struct opengl_drawable *base) -{ - TRACE("%s\n", debugstr_opengl_drawable(base)); -} - -static void wayland_drawable_update(struct opengl_drawable *base) -{ - TRACE("%s\n", debugstr_opengl_drawable(base)); }
static EGLConfig egl_config_for_format(int format) @@ -92,7 +75,7 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) int client_width, client_height; RECT client_rect = {0};
- NtUserGetClientRect(gl->base.hwnd, &client_rect, NtUserGetDpiForWindow(gl->base.hwnd)); + NtUserGetClientRect(gl->base.client->hwnd, &client_rect, NtUserGetDpiForWindow(gl->base.client->hwnd)); client_width = client_rect.right - client_rect.left; client_height = client_rect.bottom - client_rect.top; if (client_width == 0 || client_height == 0) client_width = client_height = 1; @@ -103,6 +86,7 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) static BOOL wayland_opengl_surface_create(HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable) { EGLConfig config = egl_config_for_format(format); + struct wayland_client_surface *client; EGLint attribs[4], *attrib = attribs; struct opengl_drawable *previous; struct wayland_gl_drawable *gl; @@ -125,11 +109,14 @@ static BOOL wayland_opengl_surface_create(HWND hwnd, HDC hdc, int format, struct } *attrib++ = EGL_NONE;
- if (!(gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, hwnd))) return FALSE; - if (!(gl->client = wayland_client_surface_create(hwnd))) goto err; - if (!(gl->wl_egl_window = wl_egl_window_create(gl->client->wl_surface, rect.right, rect.bottom))) goto err; + if (!(client = wayland_client_surface_create(hwnd))) return FALSE; + gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, &client->client); + client_surface_release(&client->client); + if (!gl) return FALSE; + + if (!(gl->wl_egl_window = wl_egl_window_create(client->wl_surface, rect.right, rect.bottom))) goto err; if (!(gl->base.surface = funcs->p_eglCreateWindowSurface(egl->display, config, gl->wl_egl_window, attribs))) goto err; - set_client_surface(hwnd, gl->client); + set_client_surface(hwnd, client);
TRACE("Created drawable %s with egl_surface %p\n", debugstr_opengl_drawable(&gl->base), gl->base.surface);
@@ -167,7 +154,7 @@ static BOOL wayland_drawable_swap(struct opengl_drawable *base) { struct wayland_gl_drawable *gl = impl_from_opengl_drawable(base);
- client_surface_present(&gl->client->client, NULL); + client_surface_present(base->client, NULL); funcs->p_eglSwapBuffers(egl->display, gl->base.surface);
return TRUE; @@ -248,8 +235,6 @@ static struct opengl_driver_funcs wayland_driver_funcs = static const struct opengl_drawable_funcs wayland_drawable_funcs = { .destroy = wayland_drawable_destroy, - .detach = wayland_drawable_detach, - .update = wayland_drawable_update, .flush = wayland_drawable_flush, .swap = wayland_drawable_swap, }; diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 7e9e253a373..8d5654d8379 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -197,7 +197,6 @@ struct glx_pixel_format struct gl_drawable { struct opengl_drawable base; - struct client_surface *client; RECT rect; /* current size of the GL drawable */ GLXDrawable drawable; /* drawable for rendering with GL */ Colormap colormap; /* colormap for the client window */ @@ -488,6 +487,7 @@ static inline EGLConfig egl_config_for_format(int format) static BOOL x11drv_egl_surface_create( HWND hwnd, HDC hdc, int format, struct opengl_drawable **drawable ) { struct opengl_drawable *previous; + struct client_surface *client; struct gl_drawable *gl; Window window; RECT rect; @@ -495,19 +495,15 @@ static BOOL x11drv_egl_surface_create( HWND hwnd, HDC hdc, int format, struct op if ((previous = *drawable) && previous->format == format) return TRUE; NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) );
- if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, hwnd ))) return FALSE; + if (!(window = x11drv_client_surface_create( hwnd, &client ))) return FALSE; + gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, client ); + client_surface_release( client ); + if (!gl) return FALSE; gl->rect = rect; gl->hdc = hdc;
- if (!(window = x11drv_client_surface_create(hwnd, &gl->client))) - { - opengl_drawable_release( &gl->base ); - return FALSE; - } - - gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(format), - (void *)window, NULL ); - if (!gl->base.surface) + if (!(gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format(format), + (void *)window, NULL ))) { opengl_drawable_release( &gl->base ); return FALSE; @@ -877,7 +873,6 @@ static void x11drv_surface_destroy( struct opengl_drawable *base ) if (gl->colormap) XFreeColormap( gdi_display, gl->colormap ); if (gl->hdc_src) NtGdiDeleteObjectApp( gl->hdc_src ); if (gl->hdc_dst) NtGdiDeleteObjectApp( gl->hdc_dst ); - if (gl->client) client_surface_release( gl->client ); }
static BOOL set_swap_interval( struct gl_drawable *gl, int interval ) @@ -935,6 +930,7 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl { struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); struct opengl_drawable *previous; + struct client_surface *client; struct gl_drawable *gl; Window window; RECT rect; @@ -942,16 +938,13 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl if ((previous = *drawable) && previous->format == format) return TRUE; NtUserGetClientRect( hwnd, &rect, NtUserGetDpiForWindow( hwnd ) );
- if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, hwnd ))) return FALSE; + if (!(window = x11drv_client_surface_create( hwnd, &client ))) return FALSE; + gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, client ); + client_surface_release( client ); + if (!gl) return FALSE; gl->rect = rect; gl->hdc = hdc;
- if (!(window = x11drv_client_surface_create(hwnd, &gl->client))) - { - opengl_drawable_release( &gl->base ); - return FALSE; - } - gl->colormap = XCreateColormap( gdi_display, get_dummy_parent(), fmt->visual->visual, (fmt->visual->class == PseudoColor || fmt->visual->class == GrayScale || fmt->visual->class == DirectColor) ? AllocAll : AllocNone ); @@ -969,17 +962,6 @@ static BOOL x11drv_surface_create( HWND hwnd, HDC hdc, int format, struct opengl return TRUE; }
-static void x11drv_surface_update( struct opengl_drawable *base ) -{ - TRACE( "%s\n", debugstr_opengl_drawable( base ) ); -} - -static void x11drv_surface_detach( struct opengl_drawable *base ) -{ - TRACE( "%s\n", debugstr_opengl_drawable( base ) ); -} - - static BOOL x11drv_describe_pixel_format( int format, struct wgl_pixel_format *pf ) { int value, drawable_type = 0, render_type = 0; @@ -1205,11 +1187,11 @@ static void x11drv_surface_flush( struct opengl_drawable *base, UINT flags )
if (flags & GL_FLUSH_INTERVAL) set_swap_interval( gl, base->interval );
- if (InterlockedCompareExchange( &gl->client->offscreen, 0, 0 )) + if (InterlockedCompareExchange( &base->client->offscreen, 0, 0 )) { if (!(flags & GL_FLUSH_FINISHED)) funcs->p_glFinish(); XFlush( gdi_display ); - client_surface_present( gl->client, gl->hdc ); + client_surface_present( base->client, gl->hdc ); } }
@@ -1306,7 +1288,7 @@ static BOOL x11drv_pbuffer_create( HDC hdc, int format, BOOL largest, GLenum tex } glx_attribs[count++] = 0;
- if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_pbuffer_funcs, format, 0 ))) return FALSE; + if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_pbuffer_funcs, format, NULL ))) return FALSE;
gl->drawable = pglXCreatePbuffer( gdi_display, fmt->fbconfig, glx_attribs ); TRACE( "new Pbuffer drawable as %p (%lx)\n", gl, gl->drawable ); @@ -1472,10 +1454,10 @@ static BOOL x11drv_surface_swap( struct opengl_drawable *base ) if (pglXWaitForSbcOML) pglXWaitForSbcOML( gdi_display, gl->drawable, target_sbc, &ust, &msc, &sbc ); }
- if (InterlockedCompareExchange( &gl->client->offscreen, 0, 0 )) + if (InterlockedCompareExchange( &base->client->offscreen, 0, 0 )) { if (!pglXWaitForSbcOML) XFlush( gdi_display ); - client_surface_present( gl->client, gl->hdc ); + client_surface_present( base->client, gl->hdc ); }
return TRUE; @@ -1483,21 +1465,7 @@ static BOOL x11drv_surface_swap( struct opengl_drawable *base )
static void x11drv_egl_surface_destroy( struct opengl_drawable *base ) { - struct gl_drawable *gl = impl_from_opengl_drawable( base ); - - TRACE( "%s\n", debugstr_opengl_drawable( base ) ); - - if (gl->client) client_surface_release( gl->client ); -} - -static void x11drv_egl_surface_detach( struct opengl_drawable *base ) -{ - TRACE( "%s\n", debugstr_opengl_drawable( base ) ); -} - -static void x11drv_egl_surface_update( struct opengl_drawable *base ) -{ - TRACE( "%s\n", debugstr_opengl_drawable( base ) ); + TRACE( "drawable %s\n", debugstr_opengl_drawable( base ) ); }
static void x11drv_egl_surface_flush( struct opengl_drawable *base, UINT flags ) @@ -1508,11 +1476,11 @@ static void x11drv_egl_surface_flush( struct opengl_drawable *base, UINT flags )
if (flags & GL_FLUSH_INTERVAL) funcs->p_eglSwapInterval( egl->display, abs( base->interval ) );
- if (InterlockedCompareExchange( &gl->client->offscreen, 0, 0 )) + if (InterlockedCompareExchange( &base->client->offscreen, 0, 0 )) { if (!(flags & GL_FLUSH_FINISHED)) funcs->p_glFinish(); XFlush( gdi_display ); - client_surface_present( gl->client, gl->hdc ); + client_surface_present( base->client, gl->hdc ); } }
@@ -1524,10 +1492,10 @@ static BOOL x11drv_egl_surface_swap( struct opengl_drawable *base )
funcs->p_eglSwapBuffers( egl->display, gl->base.surface );
- if (InterlockedCompareExchange( &gl->client->offscreen, 0, 0 )) + if (InterlockedCompareExchange( &base->client->offscreen, 0, 0 )) { XFlush( gdi_display ); - client_surface_present( gl->client, gl->hdc ); + client_surface_present( base->client, gl->hdc ); }
return TRUE; @@ -1551,8 +1519,6 @@ static struct opengl_driver_funcs x11drv_driver_funcs = static const struct opengl_drawable_funcs x11drv_surface_funcs = { .destroy = x11drv_surface_destroy, - .detach = x11drv_surface_detach, - .update = x11drv_surface_update, .flush = x11drv_surface_flush, .swap = x11drv_surface_swap, }; @@ -1565,8 +1531,6 @@ static const struct opengl_drawable_funcs x11drv_pbuffer_funcs = static const struct opengl_drawable_funcs x11drv_egl_surface_funcs = { .destroy = x11drv_egl_surface_destroy, - .detach = x11drv_egl_surface_detach, - .update = x11drv_egl_surface_update, .flush = x11drv_egl_surface_flush, .swap = x11drv_egl_surface_swap, }; diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index 1e744622dbd..dec9abb0f91 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -136,10 +136,6 @@ struct opengl_drawable; struct opengl_drawable_funcs { void (*destroy)( struct opengl_drawable *iface ); - /* detach the drawable from its window, called from window owner thread */ - void (*detach)( struct opengl_drawable *drawable ); - /* update the drawable to match its window state, called from window owner thread */ - void (*update)( struct opengl_drawable *drawable ); /* flush and update the drawable front buffer, called from render thread */ void (*flush)( struct opengl_drawable *iface, UINT flags ); /* swap and present the drawable buffers, called from render thread */ @@ -154,23 +150,20 @@ struct opengl_drawable_funcs struct opengl_drawable { const struct opengl_drawable_funcs *funcs; - LONG ref; - - int format; /* pixel format of the drawable */ - int interval; /* last set surface swap interval */ - HWND hwnd; /* window the drawable was created for */ - struct list entry; /* entry in win32u managed list */ - LONG updated; /* has been moved / resized / reparented */ - EGLSurface surface; /* surface for EGL based drivers */ + LONG ref; /* reference count */ + struct client_surface *client; /* underlying client surface */ + int format; /* pixel format of the drawable */ + int interval; /* last set surface swap interval */ + EGLSurface surface; /* surface for EGL based drivers */ };
static inline const char *debugstr_opengl_drawable( struct opengl_drawable *drawable ) { if (!drawable) return "(null)"; - return wine_dbg_sprintf( "%p (format %u, hwnd %p)", drawable, drawable->format, drawable->hwnd ); + return wine_dbg_sprintf( "%s/%p (format %u)", debugstr_client_surface( drawable->surface ), drawable, drawable->format ); }
-W32KAPI void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, HWND hwnd ); +W32KAPI void *opengl_drawable_create( UINT size, const struct opengl_drawable_funcs *funcs, int format, struct client_surface *client ); W32KAPI void opengl_drawable_add_ref( struct opengl_drawable *drawable ); W32KAPI void opengl_drawable_release( struct opengl_drawable *drawable );
On Wed Jul 9 05:55:35 2025 +0000, Rémi Bernon wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/8522/diffs?diff_id=191818&start_sha=c45fab0272f1017ca1511f714b43d1eea8c03886#eb7d7a7ef7f5aace0d92d509eb6d01faa73cd029_1047_1045)
Fixed, thanks!
On Wed Jul 9 05:55:35 2025 +0000, Rémi Bernon wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/8522/diffs?diff_id=191818&start_sha=c45fab0272f1017ca1511f714b43d1eea8c03886#eb7d7a7ef7f5aace0d92d509eb6d01faa73cd029_1081_1077)
Done, thanks.
On Wed Jul 9 05:55:35 2025 +0000, Rémi Bernon wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/8522/diffs?diff_id=191818&start_sha=c45fab0272f1017ca1511f714b43d1eea8c03886#7cb9ec68fa2d916cb30c713051e39c8ebdc3165a_332_332)
Removed.
Alexandros Frantzis (@afrantzis) commented about dlls/winex11.drv/init.c:
+static const struct client_surface_funcs x11drv_client_surface_funcs = +{
- .destroy = x11drv_client_surface_destroy,
- .detach = x11drv_client_surface_detach,
- .update = x11drv_client_surface_update,
- .present = X11DRV_client_surface_present,
+};
+Window x11drv_client_surface_create( HWND hwnd, struct client_surface **client ) +{
- struct x11drv_client_surface *surface;
- if (!(surface = client_surface_create( sizeof(*surface), &x11drv_client_surface_funcs, hwnd )))
- {
ERR("Failed to allocate vulkan surface for hwnd=%p\n", hwnd);
Nit: By the end of the series the client surface is also used for OpenGL, so this error could be confusing in the logs.
This merge request was approved by Alexandros Frantzis.
A small nit, but otherwise LGTM.