[PATCH v4 0/3] MR11093: win32u: Create client surfaces for GL/VK from win32u.
-- v4: win32u: Create OpenGL client surfaces from win32u. win32u: Create vulkan client surfaces from win32u. win32u: Add a new driver entry to create client surfaces. https://gitlab.winehq.org/wine/wine/-/merge_requests/11093
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/driver.c | 60 +++++++++++++------------- dlls/win32u/opengl.c | 2 +- dlls/win32u/vulkan.c | 2 +- dlls/win32u/win32u_private.h | 1 - dlls/wineandroid.drv/android.h | 1 + dlls/wineandroid.drv/init.c | 1 + dlls/wineandroid.drv/opengl.c | 7 ++- dlls/winemac.drv/gdi.c | 1 + dlls/winemac.drv/macdrv.h | 8 +--- dlls/winemac.drv/opengl.c | 8 ++-- dlls/winemac.drv/vulkan.c | 4 +- dlls/winemac.drv/window.c | 10 ++++- dlls/winewayland.drv/opengl.c | 14 +++--- dlls/winewayland.drv/vulkan.c | 5 ++- dlls/winewayland.drv/wayland_surface.c | 15 ++++--- dlls/winewayland.drv/waylanddrv.h | 4 +- dlls/winewayland.drv/waylanddrv_main.c | 1 + dlls/winex11.drv/init.c | 38 ++++++---------- dlls/winex11.drv/opengl.c | 18 ++++---- dlls/winex11.drv/vulkan.c | 7 ++- dlls/winex11.drv/x11drv.h | 16 ++++++- include/wine/gdi_driver.h | 3 +- 22 files changed, 129 insertions(+), 97 deletions(-) diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index c7a78cd327d..cfe0650648b 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -879,6 +879,35 @@ static BOOL nulldrv_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *swp return FALSE; } +static void nulldrv_surface_destroy( struct client_surface *client ) +{ +} + +static void nulldrv_surface_detach( struct client_surface *client ) +{ +} + +static void nulldrv_surface_update( struct client_surface *client ) +{ +} + +static void nulldrv_surface_present( struct client_surface *client, HDC hdc ) +{ +} + +static const struct client_surface_funcs nulldrv_surface_funcs = +{ + .destroy = nulldrv_surface_destroy, + .detach = nulldrv_surface_detach, + .update = nulldrv_surface_update, + .present = nulldrv_surface_present, +}; + +static struct client_surface *nulldrv_CreateClientSurface( HWND hwnd, int pixel_format ) +{ + return client_surface_create( sizeof(struct client_surface), &nulldrv_surface_funcs, hwnd ); +} + static BOOL nulldrv_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ) { return FALSE; @@ -1302,6 +1331,7 @@ static const struct user_driver_funcs lazy_load_driver = nulldrv_WindowPosChanging, nulldrv_GetWindowStyleMasks, nulldrv_GetWindowStateUpdates, + nulldrv_CreateClientSurface, nulldrv_CreateWindowSurface, nulldrv_MoveWindowBits, nulldrv_WindowPosChanged, @@ -1401,6 +1431,7 @@ void __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT version SET_USER_FUNC(WindowPosChanging); SET_USER_FUNC(GetWindowStyleMasks); SET_USER_FUNC(GetWindowStateUpdates); + SET_USER_FUNC(CreateClientSurface); SET_USER_FUNC(CreateWindowSurface); SET_USER_FUNC(MoveWindowBits); SET_USER_FUNC(WindowPosChanged); @@ -1439,32 +1470,3 @@ INT WINAPI NtGdiExtEscape( HDC hdc, WCHAR *driver, int driver_id, INT escape, IN release_dc_ptr( dc ); return ret; } - -static void nulldrv_surface_destroy( struct client_surface *client ) -{ -} - -static void nulldrv_surface_detach( struct client_surface *client ) -{ -} - -static void nulldrv_surface_update( struct client_surface *client ) -{ -} - -static void nulldrv_surface_present( struct client_surface *client, HDC hdc ) -{ -} - -static const struct client_surface_funcs nulldrv_surface_funcs = -{ - .destroy = nulldrv_surface_destroy, - .detach = nulldrv_surface_detach, - .update = nulldrv_surface_update, - .present = nulldrv_surface_present, -}; - -struct client_surface *nulldrv_client_surface_create( HWND hwnd ) -{ - return client_surface_create( sizeof(struct client_surface), &nulldrv_surface_funcs, hwnd ); -} diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 3d03b41fc24..089452198de 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -664,7 +664,7 @@ static BOOL egldrv_surface_create( HWND hwnd, int format, struct opengl_drawable { struct client_surface *client; - if (!(client = nulldrv_client_surface_create( hwnd ))) return FALSE; + if (!(client = user_driver->pCreateClientSurface( hwnd, format ))) return FALSE; *drawable = framebuffer_surface_create( format, client ); client_surface_release( client ); diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index bf8f6f1daba..c95038ed6a4 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -2930,7 +2930,7 @@ static VkResult nulldrv_vulkan_surface_create( HWND hwnd, const struct vulkan_in VkHeadlessSurfaceCreateInfoEXT create_info = {.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; VkResult res; - if (!(*client = nulldrv_client_surface_create( hwnd ))) return VK_ERROR_OUT_OF_HOST_MEMORY; + if (!(*client = user_driver->pCreateClientSurface( hwnd, 0 ))) return VK_ERROR_OUT_OF_HOST_MEMORY; if ((res = instance->p_vkCreateHeadlessSurfaceEXT( instance->host.instance, &create_info, NULL, surface ))) { client_surface_release(*client); diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index be303ae4d13..620d848488d 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -354,7 +354,6 @@ extern HKEY hkcu_key; /* driver.c */ extern const struct user_driver_funcs *user_driver; -extern struct client_surface *nulldrv_client_surface_create( HWND hwnd ); extern ULONG_PTR zero_bits; diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index cc558aa01f6..c63e7b1fd79 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -115,6 +115,7 @@ extern void ANDROID_SetCapture( HWND hwnd, UINT flags ); extern UINT ANDROID_ShowWindow( HWND hwnd, INT cmd, RECT *rect, UINT swp ); extern LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ); +extern struct client_surface *ANDROID_CreateClientSurface( HWND hwnd, int pixel_format ); extern BOOL ANDROID_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ); extern void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface ); diff --git a/dlls/wineandroid.drv/init.c b/dlls/wineandroid.drv/init.c index df0cb2b72ec..2dca7362a69 100644 --- a/dlls/wineandroid.drv/init.c +++ b/dlls/wineandroid.drv/init.c @@ -322,6 +322,7 @@ static const struct user_driver_funcs android_drv_funcs = .pShowWindow = ANDROID_ShowWindow, .pWindowMessage = ANDROID_WindowMessage, .pWindowPosChanging = ANDROID_WindowPosChanging, + .pCreateClientSurface = ANDROID_CreateClientSurface, .pCreateWindowSurface = ANDROID_CreateWindowSurface, .pWindowPosChanged = ANDROID_WindowPosChanged, .pOpenGLInit = ANDROID_OpenGLInit, diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 62b4fa7dd6c..1cec107420d 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -108,7 +108,7 @@ static BOOL android_surface_create( HWND hwnd, int format, struct opengl_drawabl EGLConfig config = egl_config_for_format( format ); struct client_surface *client; - if (!(client = client_surface_create( sizeof(*client), &android_client_surface_funcs, hwnd ))) return FALSE; + if (!(client = ANDROID_ClientSurfaceCreate( hwnd, format ))) return FALSE; gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, client ); client_surface_release( client ); if (!gl) return FALSE; @@ -194,6 +194,11 @@ static const struct client_surface_funcs android_client_surface_funcs = .present = android_client_surface_present, }; +struct client_surface *ANDROID_ClientSurfaceCreate( HWND hwnd, int pixel_format ) +{ + return client_surface_create( sizeof(struct client_surface), &android_client_surface_funcs, hwnd ); +} + static const struct opengl_drawable_funcs android_drawable_funcs = { .destroy = android_drawable_destroy, diff --git a/dlls/winemac.drv/gdi.c b/dlls/winemac.drv/gdi.c index a0f314234b9..906bb4d09e6 100644 --- a/dlls/winemac.drv/gdi.c +++ b/dlls/winemac.drv/gdi.c @@ -284,6 +284,7 @@ static const struct user_driver_funcs macdrv_funcs = .pWindowPosChanged = macdrv_WindowPosChanged, .pWindowPosChanging = macdrv_WindowPosChanging, .pGetWindowStyleMasks = macdrv_GetWindowStyleMasks, + .pCreateClientSurface = macdrv_CreateClientSurface, .pCreateWindowSurface = macdrv_CreateWindowSurface, .pVulkanInit = macdrv_VulkanInit, .pOpenGLInit = macdrv_OpenGLInit, diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 4f7107baf68..0aef8cdd60f 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -150,6 +150,7 @@ extern void macdrv_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alph extern LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); extern BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects); extern BOOL macdrv_GetWindowStyleMasks(HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask); +extern struct client_surface *macdrv_CreateClientSurface(HWND hwnd, int pixel_format); extern BOOL macdrv_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface); @@ -200,12 +201,7 @@ extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_p macdrv_metal_swapchain metal_swapchain; }; -static inline struct macdrv_client_surface *impl_from_client_surface(struct client_surface *client) -{ - return CONTAINING_RECORD(client, struct macdrv_client_surface, client); -} - -extern struct macdrv_client_surface *macdrv_client_surface_create(HWND hwnd); +extern struct macdrv_client_surface *impl_from_client_surface(struct client_surface *client); extern BOOL macdrv_client_surface_acquire_metal_swapchain(struct macdrv_client_surface *surface); extern struct macdrv_win_data *get_win_data(HWND hwnd); diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 0af1d3f7192..86830bffc80 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -1457,7 +1457,7 @@ static BOOL create_context(struct macdrv_context *context, CGLContextObj share, static BOOL macdrv_surface_create(HWND hwnd, int format, struct opengl_drawable **drawable) { - struct macdrv_client_surface *client; + struct client_surface *client; struct macdrv_win_data *data; struct gl_drawable *gl; @@ -1472,9 +1472,9 @@ static BOOL macdrv_surface_create(HWND hwnd, int format, struct opengl_drawable data->pixel_format = format; release_win_data(data); - if (!(client = macdrv_client_surface_create(hwnd))) return FALSE; - gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, &client->client); - client_surface_release(&client->client); + if (!(client = macdrv_CreateClientSurface(hwnd, format))) return FALSE; + gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, client); + client_surface_release(client); if (!gl) return FALSE; *drawable = &gl->base; diff --git a/dlls/winemac.drv/vulkan.c b/dlls/winemac.drv/vulkan.c index f1643e3e5c4..41c148627fb 100644 --- a/dlls/winemac.drv/vulkan.c +++ b/dlls/winemac.drv/vulkan.c @@ -45,10 +45,12 @@ static VkResult macdrv_vulkan_surface_create(HWND hwnd, const struct vulkan_inst { VkResult res; struct macdrv_client_surface *surface; + struct client_surface *ptr; TRACE("%p %p %p %p\n", hwnd, instance, handle, client); - if (!(surface = macdrv_client_surface_create(hwnd))) return VK_ERROR_OUT_OF_HOST_MEMORY; + if (!(ptr = macdrv_CreateClientSurface(hwnd, 0))) return VK_ERROR_OUT_OF_HOST_MEMORY; + surface = impl_from_client_surface( ptr ); if (!macdrv_client_surface_acquire_metal_swapchain(surface)) goto err; diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index adfc059e34f..4ed488cd760 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1144,7 +1144,13 @@ static const struct client_surface_funcs macdrv_client_surface_funcs = .present = macdrv_client_surface_present, }; -struct macdrv_client_surface *macdrv_client_surface_create(HWND hwnd) +struct macdrv_client_surface *impl_from_client_surface(struct client_surface *client) +{ + assert(client->funcs == &macdrv_client_surface_funcs); + return CONTAINING_RECORD(client, struct macdrv_client_surface, client); +} + +struct client_surface *macdrv_CreateClientSurface(HWND hwnd, int pixel_format) { HWND toplevel = NtUserGetAncestor(hwnd, GA_ROOT); struct macdrv_client_surface *surface; @@ -1163,7 +1169,7 @@ struct macdrv_client_surface *macdrv_client_surface_create(HWND hwnd) macdrv_client_surface_present(&surface->client, 0); } - return surface; + return &surface->client; } BOOL macdrv_client_surface_acquire_metal_swapchain(struct macdrv_client_surface *surface) diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 66457e1aea5..9719c63719d 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -83,10 +83,11 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_drawable **drawable) { EGLConfig config = egl_config_for_format(format); - struct wayland_client_surface *client; + struct wayland_client_surface *surface; EGLint attribs[4], *attrib = attribs; struct opengl_drawable *previous; struct wayland_gl_drawable *gl; + struct client_surface *client; RECT rect; TRACE("hwnd=%p format=%d\n", hwnd, format); @@ -106,9 +107,10 @@ static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_d } *attrib++ = EGL_NONE; - 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 (!(client = WAYLAND_CreateClientSurface(hwnd, format))) return FALSE; + gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, client); + surface = impl_from_client_surface(client); /* reference held by gl */ + client_surface_release(client); if (!gl) return FALSE; opengl_drawable_map_buffer(&gl->base, GL_FRONT_LEFT, GL_BACK_LEFT); @@ -116,9 +118,9 @@ static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_d opengl_drawable_map_buffer(&gl->base, GL_FRONT_AND_BACK, GL_BACK); if (gl->base.stereo) opengl_drawable_map_buffer(&gl->base, GL_FRONT_RIGHT, GL_BACK_RIGHT); - if (!(gl->wl_egl_window = wl_egl_window_create(client->wl_surface, rect.right, rect.bottom))) goto err; + if (!(gl->wl_egl_window = wl_egl_window_create(surface->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, client); + set_client_surface(hwnd, surface); TRACE("Created drawable %s with egl_surface %p\n", debugstr_opengl_drawable(&gl->base), gl->base.surface); diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index b2e91102f58..65ebbc40b1f 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -44,10 +44,13 @@ static VkResult wayland_vulkan_surface_create(HWND hwnd, const struct vulkan_ins VkResult res; VkWaylandSurfaceCreateInfoKHR create_info_host; struct wayland_client_surface *surface; + struct client_surface *ptr; TRACE("%p %p %p %p\n", hwnd, instance, handle, client); - if (!(surface = wayland_client_surface_create(hwnd))) return VK_ERROR_OUT_OF_HOST_MEMORY; + if (!(ptr = WAYLAND_CreateClientSurface(hwnd, 0))) return VK_ERROR_OUT_OF_HOST_MEMORY; + surface = impl_from_client_surface( ptr ); + create_info_host.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; create_info_host.pNext = NULL; create_info_host.flags = 0; /* reserved */ diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 2f8275ddb52..281a45f2cd6 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -1041,11 +1041,6 @@ void wayland_surface_coords_to_window(struct wayland_surface *surface, *window_y = round(surface_y * surface->window.scale); } -static struct wayland_client_surface *impl_from_client_surface(struct client_surface *client) -{ - return CONTAINING_RECORD(client, struct wayland_client_surface, client); -} - static void wayland_client_surface_destroy(struct client_surface *client) { struct wayland_client_surface *surface = impl_from_client_surface(client); @@ -1105,7 +1100,13 @@ static const struct client_surface_funcs wayland_client_surface_funcs = .present = wayland_client_surface_present, }; -struct wayland_client_surface *wayland_client_surface_create(HWND hwnd) +struct wayland_client_surface *impl_from_client_surface(struct client_surface *client) +{ + assert(client->funcs == &wayland_client_surface_funcs); + return CONTAINING_RECORD(client, struct wayland_client_surface, client); +} + +struct client_surface *WAYLAND_CreateClientSurface(HWND hwnd, int pixel_format) { struct wayland_client_surface *client; struct wl_region *empty_region; @@ -1140,7 +1141,7 @@ struct wayland_client_surface *wayland_client_surface_create(HWND hwnd) goto err; } - return client; + return &client->client; err: client_surface_release(&client->client); diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 5f4bd6a7cf6..1de0bd05cfd 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -249,6 +249,8 @@ struct wayland_client_surface struct wp_viewport *wp_viewport; }; +extern struct wayland_client_surface *impl_from_client_surface(struct client_surface *client); + struct wayland_shm_buffer { struct wl_list link; @@ -331,7 +333,6 @@ void wayland_surface_coords_from_window(struct wayland_surface *surface, 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); void wayland_client_surface_attach(struct wayland_client_surface *client, HWND toplevel); void wayland_surface_ensure_contents(struct wayland_surface *surface); void wayland_surface_set_title(struct wayland_surface *surface, LPCWSTR title); @@ -459,6 +460,7 @@ LRESULT WAYLAND_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, HWND owner_hint, UINT swp_flags, const struct window_rects *new_rects, struct window_surface *surface); BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects); +struct client_surface *WAYLAND_CreateClientSurface(HWND hwnd, int pixel_format); BOOL WAYLAND_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface); UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs); UINT WAYLAND_OpenGLInit(UINT version, const struct opengl_funcs *opengl_funcs, const struct opengl_driver_funcs **driver_funcs); diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index b7a8a29be70..b1bfe7d56de 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -52,6 +52,7 @@ static const struct user_driver_funcs waylanddrv_funcs = .pWindowMessage = WAYLAND_WindowMessage, .pWindowPosChanged = WAYLAND_WindowPosChanged, .pWindowPosChanging = WAYLAND_WindowPosChanging, + .pCreateClientSurface = WAYLAND_CreateClientSurface, .pCreateWindowSurface = WAYLAND_CreateWindowSurface, .pVulkanInit = WAYLAND_VulkanInit, .pOpenGLInit = WAYLAND_OpenGLInit, diff --git a/dlls/winex11.drv/init.c b/dlls/winex11.drv/init.c index 09ef2bf8664..d5b4fdbf0aa 100644 --- a/dlls/winex11.drv/init.c +++ b/dlls/winex11.drv/init.c @@ -26,6 +26,7 @@ #include <stdarg.h> #include <string.h> +#include <assert.h> #include "windef.h" #include "winbase.h" @@ -264,25 +265,6 @@ 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; - XWindowChanges changes; - Colormap colormap; - 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 ); @@ -477,17 +459,23 @@ static int visual_class_alloc( int class ) return class == PseudoColor || class == GrayScale || class == DirectColor ? AllocAll : AllocNone; } -Window x11drv_client_surface_create( HWND hwnd, int format, struct client_surface **client ) +struct x11drv_client_surface *impl_from_client_surface( struct client_surface *client ) +{ + assert( client->funcs == &x11drv_client_surface_funcs ); + return CONTAINING_RECORD( client, struct x11drv_client_surface, client ); +} + +struct client_surface *X11DRV_CreateClientSurface( HWND hwnd, int format ) { struct x11drv_client_surface *surface; XVisualInfo visual = default_visual; Colormap colormap; - if (format && !visual_from_pixel_format( format, &visual )) return None; + if (format && !visual_from_pixel_format( format, &visual )) return NULL; if (visual.visualid == default_visual.visualid) colormap = default_colormap; else colormap = XCreateColormap( gdi_display, get_dummy_parent(), visual.visual, visual_class_alloc( visual.class ) ); - if (!colormap) return None; + if (!colormap) return NULL; if (!(surface = client_surface_create( sizeof(*surface), &x11drv_client_surface_funcs, hwnd ))) goto failed; surface->colormap = colormap; @@ -496,13 +484,12 @@ Window x11drv_client_surface_create( HWND hwnd, int format, struct client_surfac if (!(surface->window = create_client_window( hwnd, surface->rect, &visual, colormap ))) goto failed; TRACE( "Created %s for client window %lx\n", debugstr_client_surface( &surface->client ), surface->window ); - *client = &surface->client; - return surface->window; + return &surface->client; failed: if (surface) client_surface_release( &surface->client ); else if (colormap != default_colormap) XFreeColormap( gdi_display, colormap ); - return None; + return NULL; } /********************************************************************** @@ -711,6 +698,7 @@ static const struct user_driver_funcs x11drv_funcs = .pWindowPosChanging = X11DRV_WindowPosChanging, .pGetWindowStyleMasks = X11DRV_GetWindowStyleMasks, .pGetWindowStateUpdates = X11DRV_GetWindowStateUpdates, + .pCreateClientSurface = X11DRV_CreateClientSurface, .pCreateWindowSurface = X11DRV_CreateWindowSurface, .pMoveWindowBits = X11DRV_MoveWindowBits, .pWindowPosChanged = X11DRV_WindowPosChanged, diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 56c22ab7ee7..2b6e1145e47 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -521,14 +521,15 @@ static BOOL x11drv_egl_describe_pixel_format( int format, struct wgl_pixel_forma static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) { + struct x11drv_client_surface *surface; struct opengl_drawable *previous; struct client_surface *client; struct gl_drawable *gl; - Window window; if ((previous = *drawable) && previous->format == format) return TRUE; - if (!(window = x11drv_client_surface_create( hwnd, format, &client ))) return FALSE; + if (!(client = X11DRV_CreateClientSurface( hwnd, format ))) return FALSE; gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, client ); + surface = impl_from_client_surface( client ); /* reference held by gl */ client_surface_release( client ); if (!gl) return FALSE; @@ -538,13 +539,13 @@ static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_draw if (gl->base.stereo) opengl_drawable_map_buffer( &gl->base, GL_FRONT_RIGHT, GL_BACK_RIGHT ); if (!(gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, egl_config_for_format( format ), - (void *)window, NULL ))) + (void *)surface->window, NULL ))) { opengl_drawable_release( &gl->base ); return FALSE; } - TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), window ); + TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), surface->window ); XFlush( gdi_display ); if (previous) opengl_drawable_release( previous ); @@ -959,24 +960,25 @@ static GLXContext create_glxcontext( int format, GLXContext share, const int *at static BOOL x11drv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) { struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); + struct x11drv_client_surface *surface; struct opengl_drawable *previous; struct client_surface *client; struct gl_drawable *gl; - Window window; if ((previous = *drawable) && previous->format == format) return TRUE; - if (!(window = x11drv_client_surface_create( hwnd, format, &client ))) return FALSE; + if (!(client = X11DRV_CreateClientSurface( hwnd, format ))) return FALSE; gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, client ); + surface = impl_from_client_surface( client ); /* reference held by gl */ client_surface_release( client ); if (!gl) return FALSE; - if (!(gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, window, NULL ))) + if (!(gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, surface->window, NULL ))) { opengl_drawable_release( &gl->base ); return FALSE; } - TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), window ); + TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), surface->window ); XFlush( gdi_display ); if (previous) opengl_drawable_release( previous ); diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index e11a989f02d..fd58d4662d7 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -54,10 +54,15 @@ 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_client_surface *surface; + struct client_surface *ptr; TRACE( "%p %p %p %p\n", hwnd, instance, handle, client ); - if (!(info.window = x11drv_client_surface_create( hwnd, 0, client ))) return VK_ERROR_OUT_OF_HOST_MEMORY; + if (!(ptr = X11DRV_CreateClientSurface( hwnd, 0 ))) return VK_ERROR_OUT_OF_HOST_MEMORY; + surface = impl_from_client_surface( ptr ); + + info.window = surface->window; if (instance->p_vkCreateXlibSurfaceKHR( instance->host.instance, &info, NULL /* allocator */, handle )) { ERR("Failed to create Xlib surface\n"); diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 3def37a8f21..56d6c814aad 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -251,6 +251,7 @@ extern LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ) extern BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, BOOL shaped, const struct window_rects *rects ); extern BOOL X11DRV_GetWindowStyleMasks( HWND hwnd, UINT style, UINT ex_style, UINT *style_mask, UINT *ex_style_mask ); extern BOOL X11DRV_GetWindowStateUpdates( HWND hwnd, UINT *state_cmd, UINT *swp_flags, RECT *rect, HWND *foreground ); +extern struct client_surface *X11DRV_CreateClientSurface( HWND hwnd, int format ); extern BOOL X11DRV_CreateWindowSurface( HWND hwnd, BOOL layered, const RECT *surface_rect, struct window_surface **surface ); extern void X11DRV_MoveWindowBits( HWND hwnd, const struct window_rects *old_rects, const struct window_rects *new_rects, const RECT *valid_rects ); @@ -364,11 +365,24 @@ struct x11drv_escape_get_drawable RECT dc_rect; /* DC rectangle relative to drawable */ }; +struct x11drv_client_surface +{ + struct client_surface client; + XWindowChanges changes; + Colormap colormap; + Window window; + RECT rect; + + HDC hdc_src; + HDC hdc_dst; +}; + +extern struct x11drv_client_surface *impl_from_client_surface( struct client_surface *client ); + 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, int format, struct client_surface **client ); /************************************************************************** * X11 USER driver diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 97c646d6ec9..fa1f7232505 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -218,7 +218,7 @@ struct gdi_dc_funcs }; /* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 108 +#define WINE_GDI_DRIVER_VERSION 109 #define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -420,6 +420,7 @@ struct user_driver_funcs BOOL (*pWindowPosChanging)(HWND,UINT,BOOL,const struct window_rects *); BOOL (*pGetWindowStyleMasks)(HWND,UINT,UINT,UINT*,UINT*); BOOL (*pGetWindowStateUpdates)(HWND,UINT*,UINT*,RECT*,HWND*); + struct client_surface *(*pCreateClientSurface)(HWND,int); BOOL (*pCreateWindowSurface)(HWND,BOOL,const RECT *,struct window_surface**); void (*pMoveWindowBits)(HWND,const struct window_rects *,const struct window_rects *,const RECT *); void (*pWindowPosChanged)(HWND,HWND,HWND,UINT,const struct window_rects*,struct window_surface*); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11093
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/vulkan.c | 24 ++++++++---------------- dlls/winemac.drv/vulkan.c | 29 +++++++---------------------- dlls/winewayland.drv/vulkan.c | 25 ++++++------------------- dlls/winex11.drv/vulkan.c | 23 +++++++---------------- include/wine/vulkan_driver.h | 4 ++-- 5 files changed, 30 insertions(+), 75 deletions(-) diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c index c95038ed6a4..00f85243a3f 100644 --- a/dlls/win32u/vulkan.c +++ b/dlls/win32u/vulkan.c @@ -1533,8 +1533,11 @@ static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance client_instance, cons surface->hwnd = dummy; } - if ((res = driver_funcs->p_vulkan_surface_create( surface->hwnd, instance, &host_surface, &surface->client ))) + if (!(surface->client = user_driver->pCreateClientSurface( surface->hwnd, 0 ))) res = VK_ERROR_OUT_OF_HOST_MEMORY; + else res = driver_funcs->p_vulkan_surface_create( surface->client, instance, &host_surface ); + if (res) { + if (surface->client) client_surface_release( surface->client ); if (dummy) NtUserDestroyWindow( dummy ); free( surface ); return res; @@ -2924,20 +2927,10 @@ static struct vulkan_funcs vulkan_funcs = .p_vkUnmapMemory2KHR = win32u_vkUnmapMemory2KHR, }; -static VkResult nulldrv_vulkan_surface_create( HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *surface, - struct client_surface **client ) +static VkResult nulldrv_vulkan_surface_create( struct client_surface *client, const struct vulkan_instance *instance, VkSurfaceKHR *surface ) { VkHeadlessSurfaceCreateInfoEXT create_info = {.sType = VK_STRUCTURE_TYPE_HEADLESS_SURFACE_CREATE_INFO_EXT}; - VkResult res; - - if (!(*client = user_driver->pCreateClientSurface( hwnd, 0 ))) return VK_ERROR_OUT_OF_HOST_MEMORY; - if ((res = instance->p_vkCreateHeadlessSurfaceEXT( instance->host.instance, &create_info, NULL, surface ))) - { - client_surface_release(*client); - *client = NULL; - } - - return res; + return instance->p_vkCreateHeadlessSurfaceEXT( instance->host.instance, &create_info, NULL, surface ); } static VkBool32 nulldrv_get_physical_device_presentation_support( struct vulkan_physical_device *physical_device, uint32_t queue ) @@ -2989,11 +2982,10 @@ static void vulkan_driver_load(void) pthread_once( &init_once, vulkan_driver_init ); } -static VkResult lazydrv_vulkan_surface_create( HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *surface, - struct client_surface **client ) +static VkResult lazydrv_vulkan_surface_create( struct client_surface *client, const struct vulkan_instance *instance, VkSurfaceKHR *surface ) { vulkan_driver_load(); - return driver_funcs->p_vulkan_surface_create( hwnd, instance, surface, client ); + return driver_funcs->p_vulkan_surface_create( client, instance, surface ); } static VkBool32 lazydrv_get_physical_device_presentation_support( struct vulkan_physical_device *physical_device, uint32_t queue ) diff --git a/dlls/winemac.drv/vulkan.c b/dlls/winemac.drv/vulkan.c index 41c148627fb..532f792ed46 100644 --- a/dlls/winemac.drv/vulkan.c +++ b/dlls/winemac.drv/vulkan.c @@ -40,19 +40,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); static const struct vulkan_driver_funcs macdrv_vulkan_driver_funcs; -static VkResult macdrv_vulkan_surface_create(HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *handle, - struct client_surface **client) +static VkResult macdrv_vulkan_surface_create(struct client_surface *client, const struct vulkan_instance *instance, VkSurfaceKHR *handle) { VkResult res; - struct macdrv_client_surface *surface; - struct client_surface *ptr; + struct macdrv_client_surface *surface = impl_from_client_surface(client); - TRACE("%p %p %p %p\n", hwnd, instance, handle, client); + TRACE("%s %p %p\n", debugstr_client_surface(client), instance, handle); - if (!(ptr = macdrv_CreateClientSurface(hwnd, 0))) return VK_ERROR_OUT_OF_HOST_MEMORY; - surface = impl_from_client_surface( ptr ); - - if (!macdrv_client_surface_acquire_metal_swapchain(surface)) goto err; + if (!macdrv_client_surface_acquire_metal_swapchain(surface)) return VK_ERROR_INCOMPATIBLE_DRIVER; if (instance->p_vkCreateMetalSurfaceEXT) { @@ -62,7 +57,7 @@ static VkResult macdrv_vulkan_surface_create(HWND hwnd, const struct vulkan_inst create_info_host.flags = 0; /* reserved */ create_info_host.pLayer = macdrv_swapchain_get_layer(surface->metal_swapchain); - res = instance->p_vkCreateMetalSurfaceEXT(instance->host.instance, &create_info_host, NULL /* allocator */, handle); + if ((res = instance->p_vkCreateMetalSurfaceEXT(instance->host.instance, &create_info_host, NULL /* allocator */, handle))) return res; } else { @@ -72,21 +67,11 @@ static VkResult macdrv_vulkan_surface_create(HWND hwnd, const struct vulkan_inst create_info_host.flags = 0; /* reserved */ create_info_host.pView = macdrv_swapchain_get_layer(surface->metal_swapchain); - res = instance->p_vkCreateMacOSSurfaceMVK(instance->host.instance, &create_info_host, NULL /* allocator */, handle); - } - if (res != VK_SUCCESS) - { - ERR("Failed to create MoltenVK surface, res=%d\n", res); - goto err; + if ((res = instance->p_vkCreateMacOSSurfaceMVK(instance->host.instance, &create_info_host, NULL /* allocator */, handle))) return res; } - *client = &surface->client; - TRACE("Created surface=0x%s, client=%p\n", wine_dbgstr_longlong(*handle), *client); + TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*handle)); return VK_SUCCESS; - -err: - client_surface_release(&surface->client); - return VK_ERROR_INCOMPATIBLE_DRIVER; } static VkBool32 macdrv_get_physical_device_presentation_support(struct vulkan_physical_device *physical_device, diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 65ebbc40b1f..b2c435cb7a4 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -38,37 +38,24 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); 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, - struct client_surface **client) +static VkResult wayland_vulkan_surface_create(struct client_surface *client, const struct vulkan_instance *instance, VkSurfaceKHR *handle) { VkResult res; VkWaylandSurfaceCreateInfoKHR create_info_host; - struct wayland_client_surface *surface; - struct client_surface *ptr; + struct wayland_client_surface *surface = impl_from_client_surface(client); + HWND hwnd = client->hwnd; - TRACE("%p %p %p %p\n", hwnd, instance, handle, client); - - if (!(ptr = WAYLAND_CreateClientSurface(hwnd, 0))) return VK_ERROR_OUT_OF_HOST_MEMORY; - surface = impl_from_client_surface( ptr ); + TRACE("%s %p %p\n", debugstr_client_surface(client), instance, handle); 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->wl_surface; - - res = instance->p_vkCreateWaylandSurfaceKHR(instance->host.instance, &create_info_host, NULL /* allocator */, handle); - if (res != VK_SUCCESS) - { - ERR("Failed to create vulkan wayland surface, res=%d\n", res); - client_surface_release(&surface->client); - return res; - } - + if ((res = instance->p_vkCreateWaylandSurfaceKHR(instance->host.instance, &create_info_host, NULL /* allocator */, handle))) return res; set_client_surface(hwnd, surface); - *client = &surface->client; - TRACE("Created surface=0x%s, client=%p\n", wine_dbgstr_longlong(*handle), *client); + TRACE("Created surface=0x%s\n", wine_dbgstr_longlong(*handle)); return VK_SUCCESS; } diff --git a/dlls/winex11.drv/vulkan.c b/dlls/winex11.drv/vulkan.c index fd58d4662d7..1c1b9cf3ba1 100644 --- a/dlls/winex11.drv/vulkan.c +++ b/dlls/winex11.drv/vulkan.c @@ -46,31 +46,22 @@ WINE_DEFAULT_DEBUG_CHANNEL(vulkan); static const struct vulkan_driver_funcs x11drv_vulkan_driver_funcs; -static VkResult X11DRV_vulkan_surface_create( HWND hwnd, const struct vulkan_instance *instance, VkSurfaceKHR *handle, - struct client_surface **client ) +static VkResult X11DRV_vulkan_surface_create( struct client_surface *client, const struct vulkan_instance *instance, VkSurfaceKHR *handle ) { + struct x11drv_client_surface *surface = impl_from_client_surface( client ); VkXlibSurfaceCreateInfoKHR info = { .sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, .dpy = gdi_display, + .window = surface->window, }; - struct x11drv_client_surface *surface; - struct client_surface *ptr; + VkResult res; - TRACE( "%p %p %p %p\n", hwnd, instance, handle, client ); + TRACE( "%s %p %p\n", debugstr_client_surface( client ), instance, handle ); - if (!(ptr = X11DRV_CreateClientSurface( hwnd, 0 ))) return VK_ERROR_OUT_OF_HOST_MEMORY; - surface = impl_from_client_surface( ptr ); + if ((res = instance->p_vkCreateXlibSurfaceKHR( instance->host.instance, &info, NULL /* allocator */, handle ))) return res; + TRACE( "Created surface 0x%s\n", wine_dbgstr_longlong( *handle ) ); - info.window = surface->window; - if (instance->p_vkCreateXlibSurfaceKHR( instance->host.instance, &info, NULL /* allocator */, handle )) - { - ERR("Failed to create Xlib surface\n"); - client_surface_release( *client ); - return VK_ERROR_OUT_OF_HOST_MEMORY; - } - - TRACE( "Created surface 0x%s, client %s\n", wine_dbgstr_longlong( *handle ), debugstr_client_surface( *client ) ); return VK_SUCCESS; } diff --git a/include/wine/vulkan_driver.h b/include/wine/vulkan_driver.h index 9c18f6d20db..d2209a3ef54 100644 --- a/include/wine/vulkan_driver.h +++ b/include/wine/vulkan_driver.h @@ -89,7 +89,7 @@ struct VkDevice_T #include "wine/list.h" /* Wine internal vulkan driver version, needs to be bumped upon vulkan_funcs changes. */ -#define WINE_VULKAN_DRIVER_VERSION 47 +#define WINE_VULKAN_DRIVER_VERSION 48 struct vulkan_object { @@ -358,7 +358,7 @@ struct vulkan_funcs struct client_surface; struct vulkan_driver_funcs { - VkResult (*p_vulkan_surface_create)(HWND, const struct vulkan_instance *, VkSurfaceKHR *, struct client_surface **); + VkResult (*p_vulkan_surface_create)(struct client_surface *, const struct vulkan_instance *, VkSurfaceKHR *); VkBool32 (*p_get_physical_device_presentation_support)(struct vulkan_physical_device *, uint32_t); void (*p_map_instance_extensions)( struct vulkan_instance_extensions *extensions ); void (*p_map_device_extensions)( struct vulkan_device_extensions *extensions ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11093
From: Rémi Bernon <rbernon@codeweavers.com> --- dlls/win32u/opengl.c | 21 +++++++++++++-------- dlls/wineandroid.drv/opengl.c | 13 ++++--------- dlls/winemac.drv/opengl.c | 13 ++++--------- dlls/winewayland.drv/opengl.c | 18 +++++------------- dlls/winex11.drv/opengl.c | 29 ++++++----------------------- include/wine/opengl_driver.h | 4 ++-- 6 files changed, 34 insertions(+), 64 deletions(-) diff --git a/dlls/win32u/opengl.c b/dlls/win32u/opengl.c index 089452198de..5e09b7ced13 100644 --- a/dlls/win32u/opengl.c +++ b/dlls/win32u/opengl.c @@ -660,14 +660,9 @@ static void egldrv_init_extensions( struct opengl_funcs *funcs, BOOLEAN extensio { } -static BOOL egldrv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) +static BOOL egldrv_surface_create( struct client_surface *client, int format, struct opengl_drawable **drawable ) { - struct client_surface *client; - - if (!(client = user_driver->pCreateClientSurface( hwnd, format ))) return FALSE; *drawable = framebuffer_surface_create( format, client ); - client_surface_release( client ); - return !!*drawable; } @@ -1276,7 +1271,7 @@ static void nulldrv_init_extensions( struct opengl_funcs *funcs, BOOLEAN extensi { } -static BOOL nulldrv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) +static BOOL nulldrv_surface_create( struct client_surface *client, int format, struct opengl_drawable **drawable ) { return TRUE; } @@ -1407,7 +1402,17 @@ static struct opengl_drawable *get_window_unused_drawable( HWND hwnd, int format */ if (!drawable) { - driver_funcs->p_surface_create( hwnd, format, &drawable ); + struct client_surface *client; + + if (!(client = user_driver->pCreateClientSurface( hwnd, format ))) + WARN( "Failed to create a surface for window %p, format %d\n", hwnd, format ); + else + { + if (!(driver_funcs->p_surface_create( client, format, &drawable ))) + WARN( "Failed to create a drawable for window %p, format %d\n", hwnd, format ); + client_surface_release( client ); + } + if (drawable && drawable->client) add_window_client_surface( hwnd, drawable->client ); } diff --git a/dlls/wineandroid.drv/opengl.c b/dlls/wineandroid.drv/opengl.c index 1cec107420d..fc145d33184 100644 --- a/dlls/wineandroid.drv/opengl.c +++ b/dlls/wineandroid.drv/opengl.c @@ -47,7 +47,6 @@ 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 @@ -82,11 +81,11 @@ void update_gl_drawable( HWND hwnd ) NtUserRedrawWindow( hwnd, NULL, 0, RDW_INVALIDATE | RDW_ERASE ); } -static BOOL android_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) +static BOOL android_surface_create( struct client_surface *client, int format, struct opengl_drawable **drawable ) { struct gl_drawable *gl; - TRACE( "hwnd %p, format %d, drawable %p\n", hwnd, format, drawable ); + TRACE( "hwnd %p, format %d, drawable %p\n", client->hwnd, format, drawable ); if (*drawable) { @@ -106,14 +105,10 @@ static BOOL android_surface_create( HWND hwnd, int format, struct opengl_drawabl { static const int attribs[] = { EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE }; EGLConfig config = egl_config_for_format( format ); - struct client_surface *client; - - if (!(client = ANDROID_ClientSurfaceCreate( hwnd, format ))) return FALSE; - gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, client ); - client_surface_release( client ); - if (!gl) return FALSE; + if (!(gl = opengl_drawable_create( sizeof(*gl), &android_drawable_funcs, format, client ))) return FALSE; gl->window = get_client_window( client->hwnd ); + if (!has_client_surface( client->hwnd )) gl->base.surface = funcs->p_eglCreatePbufferSurface( egl->display, config, attribs ); else gl->base.surface = funcs->p_eglCreateWindowSurface( egl->display, config, gl->window, NULL ); diff --git a/dlls/winemac.drv/opengl.c b/dlls/winemac.drv/opengl.c index 86830bffc80..37e63a449b7 100644 --- a/dlls/winemac.drv/opengl.c +++ b/dlls/winemac.drv/opengl.c @@ -1455,28 +1455,23 @@ static BOOL create_context(struct macdrv_context *context, CGLContextObj share, return TRUE; } -static BOOL macdrv_surface_create(HWND hwnd, int format, struct opengl_drawable **drawable) +static BOOL macdrv_surface_create(struct client_surface *client, int format, struct opengl_drawable **drawable) { - struct client_surface *client; struct macdrv_win_data *data; + HWND hwnd = client->hwnd; struct gl_drawable *gl; - TRACE("hwnd %p, format %d, drawable %p\n", hwnd, format, drawable); + TRACE("client %s, format %d, drawable %p\n", debugstr_client_surface(client), format, drawable); if (!(data = get_win_data(hwnd))) { FIXME("DC for window %p of other process: not implemented\n", hwnd); return FALSE; } - data->pixel_format = format; release_win_data(data); - if (!(client = macdrv_CreateClientSurface(hwnd, format))) return FALSE; - gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, client); - client_surface_release(client); - if (!gl) return FALSE; - + if (!(gl = opengl_drawable_create(sizeof(*gl), &macdrv_surface_funcs, format, client))) return FALSE; *drawable = &gl->base; return TRUE; } diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index 9719c63719d..14cb4ce5a25 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -80,19 +80,16 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) wl_egl_window_resize(gl->wl_egl_window, client_width, client_height, 0, 0); } -static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_drawable **drawable) +static BOOL wayland_opengl_surface_create(struct client_surface *client, int format, struct opengl_drawable **drawable) { + struct wayland_client_surface *surface = impl_from_client_surface(client); EGLConfig config = egl_config_for_format(format); - struct wayland_client_surface *surface; EGLint attribs[4], *attrib = attribs; - struct opengl_drawable *previous; struct wayland_gl_drawable *gl; - struct client_surface *client; + HWND hwnd = client->hwnd; RECT rect; - TRACE("hwnd=%p format=%d\n", hwnd, format); - - if ((previous = *drawable) && previous->format == format) return TRUE; + TRACE("client=%s format=%d\n", debugstr_client_surface(client), format); NtUserGetClientRect(hwnd, &rect, NtUserGetDpiForWindow(hwnd)); if (rect.right == rect.left) rect.right = rect.left + 1; @@ -107,11 +104,7 @@ static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_d } *attrib++ = EGL_NONE; - if (!(client = WAYLAND_CreateClientSurface(hwnd, format))) return FALSE; - gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, client); - surface = impl_from_client_surface(client); /* reference held by gl */ - client_surface_release(client); - if (!gl) return FALSE; + if (!(gl = opengl_drawable_create(sizeof(*gl), &wayland_drawable_funcs, format, client))) return FALSE; opengl_drawable_map_buffer(&gl->base, GL_FRONT_LEFT, GL_BACK_LEFT); opengl_drawable_map_buffer(&gl->base, GL_FRONT, GL_BACK); @@ -124,7 +117,6 @@ static BOOL wayland_opengl_surface_create(HWND hwnd, int format, struct opengl_d TRACE("Created drawable %s with egl_surface %p\n", debugstr_opengl_drawable(&gl->base), gl->base.surface); - if (previous) opengl_drawable_release( previous ); *drawable = &gl->base; return TRUE; diff --git a/dlls/winex11.drv/opengl.c b/dlls/winex11.drv/opengl.c index 2b6e1145e47..f080d5dddca 100644 --- a/dlls/winex11.drv/opengl.c +++ b/dlls/winex11.drv/opengl.c @@ -519,19 +519,12 @@ static BOOL x11drv_egl_describe_pixel_format( int format, struct wgl_pixel_forma return TRUE; } -static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) +static BOOL x11drv_egl_surface_create( struct client_surface *client, int format, struct opengl_drawable **drawable ) { - struct x11drv_client_surface *surface; - struct opengl_drawable *previous; - struct client_surface *client; + struct x11drv_client_surface *surface = impl_from_client_surface( client ); struct gl_drawable *gl; - if ((previous = *drawable) && previous->format == format) return TRUE; - if (!(client = X11DRV_CreateClientSurface( hwnd, format ))) return FALSE; - gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, client ); - surface = impl_from_client_surface( client ); /* reference held by gl */ - client_surface_release( client ); - if (!gl) return FALSE; + if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_egl_surface_funcs, format, client ))) return FALSE; opengl_drawable_map_buffer( &gl->base, GL_FRONT_LEFT, GL_BACK_LEFT ); opengl_drawable_map_buffer( &gl->base, GL_FRONT, GL_BACK ); @@ -548,7 +541,6 @@ static BOOL x11drv_egl_surface_create( HWND hwnd, int format, struct opengl_draw TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), surface->window ); XFlush( gdi_display ); - if (previous) opengl_drawable_release( previous ); *drawable = &gl->base; return TRUE; } @@ -957,21 +949,13 @@ static GLXContext create_glxcontext( int format, GLXContext share, const int *at return ctx; } -static BOOL x11drv_surface_create( HWND hwnd, int format, struct opengl_drawable **drawable ) +static BOOL x11drv_surface_create( struct client_surface *client, int format, struct opengl_drawable **drawable ) { + struct x11drv_client_surface *surface = impl_from_client_surface( client ); struct glx_pixel_format *fmt = glx_pixel_format_from_format( format ); - struct x11drv_client_surface *surface; - struct opengl_drawable *previous; - struct client_surface *client; struct gl_drawable *gl; - if ((previous = *drawable) && previous->format == format) return TRUE; - if (!(client = X11DRV_CreateClientSurface( hwnd, format ))) return FALSE; - gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, client ); - surface = impl_from_client_surface( client ); /* reference held by gl */ - client_surface_release( client ); - if (!gl) return FALSE; - + if (!(gl = opengl_drawable_create( sizeof(*gl), &x11drv_surface_funcs, format, client ))) return FALSE; if (!(gl->drawable = pglXCreateWindow( gdi_display, fmt->fbconfig, surface->window, NULL ))) { opengl_drawable_release( &gl->base ); @@ -981,7 +965,6 @@ static BOOL x11drv_surface_create( HWND hwnd, int format, struct opengl_drawable TRACE( "Created drawable %s with client window %lx\n", debugstr_opengl_drawable( &gl->base ), surface->window ); XFlush( gdi_display ); - if (previous) opengl_drawable_release( previous ); *drawable = &gl->base; return TRUE; } diff --git a/include/wine/opengl_driver.h b/include/wine/opengl_driver.h index af745e038a6..3fa0aa91d97 100644 --- a/include/wine/opengl_driver.h +++ b/include/wine/opengl_driver.h @@ -111,7 +111,7 @@ struct __GLsync #include "wine/gdi_driver.h" /* Wine internal opengl driver version, needs to be bumped upon opengl_funcs changes. */ -#define WINE_OPENGL_DRIVER_VERSION 37 +#define WINE_OPENGL_DRIVER_VERSION 38 struct opengl_drawable; @@ -244,7 +244,7 @@ struct opengl_driver_funcs UINT (*p_init_pixel_formats)(UINT*); BOOL (*p_describe_pixel_format)(int,struct wgl_pixel_format*); void (*p_init_extensions)( struct opengl_funcs *funcs, BOOLEAN extensions[GL_EXTENSION_COUNT] ); - BOOL (*p_surface_create)( HWND hwnd, int format, struct opengl_drawable **drawable ); + BOOL (*p_surface_create)( struct client_surface *client, int format, struct opengl_drawable **drawable ); BOOL (*p_context_create)( int format, void *share, const int *attribs, void **context ); BOOL (*p_context_destroy)(void*); BOOL (*p_make_current)( struct opengl_drawable *draw, struct opengl_drawable *read, void *private ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11093
participants (2)
-
Rémi Bernon -
Rémi Bernon (@rbernon)