(From https://gitlab.winehq.org/wine/wine/-/merge_requests/6323)
-- v3: winewayland: Get rid of the window surface individual locks. winewayland: Introduce a new wayland_client_surface_create helper. winewayland: Get rid of window_surface reference from wayland_win_data. winewayland: Get rid of wayland_surface reference from window_surface. winewayland: Move window contents buffer to wayland_win_data struct. winewayland: Reset the buffer damage region immediately after copy. winewayland: Introduce a new get_window_surface_contents helper. winewayland: Introduce a new set_window_surface_contents helper. winewayland: Introduce a new ensure_window_surface_contents helper. winewayland: Post WM_WAYLAND_CONFIGURE outside of the surface lock.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/wayland_surface.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 5ca8b010746..040a07463a0 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -38,7 +38,7 @@ static void xdg_surface_handle_configure(void *data, struct xdg_surface *xdg_sur uint32_t serial) { struct wayland_surface *surface; - BOOL initial_configure = FALSE; + BOOL should_post = FALSE, initial_configure = FALSE; HWND hwnd = data;
TRACE("serial=%u\n", serial); @@ -52,16 +52,17 @@ static void xdg_surface_handle_configure(void *data, struct xdg_surface *xdg_sur /* If we have a previously requested config, we have already sent a * WM_WAYLAND_CONFIGURE which hasn't been handled yet. In that case, * avoid sending another message to reduce message queue traffic. */ - BOOL should_post = surface->requested.serial == 0; + should_post = surface->requested.serial == 0; initial_configure = surface->current.serial == 0; surface->pending.serial = serial; surface->requested = surface->pending; memset(&surface->pending, 0, sizeof(surface->pending)); - if (should_post) NtUserPostMessage(hwnd, WM_WAYLAND_CONFIGURE, 0, 0); }
pthread_mutex_unlock(&surface->mutex);
+ if (should_post) NtUserPostMessage(hwnd, WM_WAYLAND_CONFIGURE, 0, 0); + /* Flush the window surface in case there is content that we weren't * able to flush before due to the lack of the initial configure. */ if (initial_configure)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/opengl.c | 22 +--------------------- dlls/winewayland.drv/vulkan.c | 18 +----------------- dlls/winewayland.drv/waylanddrv.h | 2 ++ dlls/winewayland.drv/window.c | 21 +++++++++++++++++++++ 4 files changed, 25 insertions(+), 38 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index fd13bdbb406..b99d80cbcf2 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -308,26 +308,6 @@ static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) } }
-static void wayland_gl_drawable_sync_surface_state(struct wayland_gl_drawable *gl) -{ - struct wayland_surface *wayland_surface; - - if (!(wayland_surface = wayland_surface_lock_hwnd(gl->hwnd))) return; - - wayland_surface_ensure_contents(wayland_surface); - - /* Handle any processed configure request, to ensure the related - * surface state is applied by the compositor. */ - if (wayland_surface->processing.serial && - wayland_surface->processing.processed && - wayland_surface_reconfigure(wayland_surface)) - { - wl_surface_commit(wayland_surface->wl_surface); - } - - pthread_mutex_unlock(&wayland_surface->mutex); -} - static BOOL wgl_context_make_current(struct wgl_context *ctx, HDC draw_hdc, HDC read_hdc) { BOOL ret; @@ -753,7 +733,7 @@ static BOOL wayland_wglSwapBuffers(HDC hdc) if (!(gl = wayland_gl_drawable_get(NtUserWindowFromDC(hdc), hdc))) return FALSE;
if (ctx) wgl_context_refresh(ctx); - wayland_gl_drawable_sync_surface_state(gl); + ensure_window_surface_contents(gl->hwnd); /* Although all the EGL surfaces we create are double-buffered, we want to * use some as single-buffered, so avoid swapping those. */ if (gl->double_buffered) p_eglSwapBuffers(egl_display, gl->surface); diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index 16084175013..a828d736da1 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -138,23 +138,7 @@ static void wayland_vulkan_surface_detach(HWND hwnd, void *private)
static void wayland_vulkan_surface_presented(HWND hwnd, VkResult result) { - struct wayland_surface *wayland_surface; - - if ((wayland_surface = wayland_surface_lock_hwnd(hwnd))) - { - wayland_surface_ensure_contents(wayland_surface); - - /* Handle any processed configure request, to ensure the related - * surface state is applied by the compositor. */ - if (wayland_surface->processing.serial && - wayland_surface->processing.processed && - wayland_surface_reconfigure(wayland_surface)) - { - wl_surface_commit(wayland_surface->wl_surface); - } - - pthread_mutex_unlock(&wayland_surface->mutex); - } + ensure_window_surface_contents(hwnd); }
static VkBool32 wayland_vkGetPhysicalDeviceWin32PresentationSupportKHR(VkPhysicalDevice phys_dev, diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index e5db629a5b1..651478a9863 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -297,6 +297,8 @@ struct wayland_win_data struct wayland_win_data *wayland_win_data_get(HWND hwnd); void wayland_win_data_release(struct wayland_win_data *data);
+void ensure_window_surface_contents(HWND hwnd); + /********************************************************************** * Wayland Keyboard */ diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index a6285ab592c..b78d304351a 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -710,3 +710,24 @@ struct wayland_surface *wayland_surface_lock_hwnd(HWND hwnd)
return surface; } + +void ensure_window_surface_contents(HWND hwnd) +{ + struct wayland_surface *wayland_surface; + + if ((wayland_surface = wayland_surface_lock_hwnd(hwnd))) + { + wayland_surface_ensure_contents(wayland_surface); + + /* Handle any processed configure request, to ensure the related + * surface state is applied by the compositor. */ + if (wayland_surface->processing.serial && + wayland_surface->processing.processed && + wayland_surface_reconfigure(wayland_surface)) + { + wl_surface_commit(wayland_surface->wl_surface); + } + + pthread_mutex_unlock(&wayland_surface->mutex); + } +}
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/waylanddrv.h | 1 + dlls/winewayland.drv/window.c | 23 +++++++++++++++++++++++ dlls/winewayland.drv/window_surface.c | 14 +------------- 3 files changed, 25 insertions(+), 13 deletions(-)
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 651478a9863..67a93753bdc 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -297,6 +297,7 @@ struct wayland_win_data struct wayland_win_data *wayland_win_data_get(HWND hwnd); void wayland_win_data_release(struct wayland_win_data *data);
+BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffer, HRGN damage_region); void ensure_window_surface_contents(HWND hwnd);
/********************************************************************** diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index b78d304351a..8da3654c6bf 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -711,6 +711,29 @@ struct wayland_surface *wayland_surface_lock_hwnd(HWND hwnd) return surface; }
+BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffer, HRGN damage_region) +{ + struct wayland_surface *wayland_surface; + BOOL committed = FALSE; + + if ((wayland_surface = wayland_surface_lock_hwnd(hwnd))) + { + if (wayland_surface_reconfigure(wayland_surface)) + { + wayland_surface_attach_shm(wayland_surface, shm_buffer, damage_region); + wl_surface_commit(wayland_surface->wl_surface); + committed = TRUE; + } + else + { + TRACE("Wayland surface not configured yet, not flushing\n"); + } + pthread_mutex_unlock(&wayland_surface->mutex); + } + + return committed; +} + void ensure_window_surface_contents(HWND hwnd) { struct wayland_surface *wayland_surface; diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index 7e4ea202e89..5074e851648 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -385,19 +385,7 @@ static BOOL wayland_window_surface_flush(struct window_surface *window_surface,
wayland_shm_buffer_copy_data(shm_buffer, color_bits, &surface_rect, copy_from_window_region);
- pthread_mutex_lock(&wws->wayland_surface->mutex); - if (wayland_surface_reconfigure(wws->wayland_surface)) - { - wayland_surface_attach_shm(wws->wayland_surface, shm_buffer, - surface_damage_region); - wl_surface_commit(wws->wayland_surface->wl_surface); - flushed = TRUE; - } - else - { - TRACE("Wayland surface not configured yet, not flushing\n"); - } - pthread_mutex_unlock(&wws->wayland_surface->mutex); + flushed = set_window_surface_contents(window_surface->hwnd, shm_buffer, surface_damage_region); wl_display_flush(process_wayland.wl_display);
NtGdiSetRectRgn(shm_buffer->damage_region, 0, 0, 0, 0);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/waylanddrv.h | 1 + dlls/winewayland.drv/window.c | 20 ++++++++++++++++++++ dlls/winewayland.drv/window_surface.c | 17 ++++++----------- 3 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 67a93753bdc..35c18ffe468 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -298,6 +298,7 @@ struct wayland_win_data *wayland_win_data_get(HWND hwnd); void wayland_win_data_release(struct wayland_win_data *data);
BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffer, HRGN damage_region); +struct wayland_shm_buffer *get_window_surface_contents(HWND hwnd); void ensure_window_surface_contents(HWND hwnd);
/********************************************************************** diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 8da3654c6bf..ce755de6b9e 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -728,12 +728,32 @@ BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffe { TRACE("Wayland surface not configured yet, not flushing\n"); } + + /* Update the latest window buffer for the wayland surface. Note that we + * only care whether the buffer contains the latest window contents, + * it's irrelevant if it was actually committed or not. */ + if (wayland_surface->latest_window_buffer) + wayland_shm_buffer_unref(wayland_surface->latest_window_buffer); + wayland_shm_buffer_ref((wayland_surface->latest_window_buffer = shm_buffer)); + pthread_mutex_unlock(&wayland_surface->mutex); }
return committed; }
+struct wayland_shm_buffer *get_window_surface_contents(HWND hwnd) +{ + struct wayland_surface *wayland_surface; + struct wayland_shm_buffer *shm_buffer; + + if (!(wayland_surface = wayland_surface_lock_hwnd(hwnd))) return NULL; + if ((shm_buffer = wayland_surface->latest_window_buffer)) wayland_shm_buffer_ref(shm_buffer); + pthread_mutex_unlock(&wayland_surface->mutex); + + return shm_buffer; +} + void ensure_window_surface_contents(HWND hwnd) { struct wayland_surface *wayland_surface; diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index 5074e851648..1781018a17f 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -324,7 +324,7 @@ static BOOL wayland_window_surface_flush(struct window_surface *window_surface, { RECT surface_rect = {.right = color_info->bmiHeader.biWidth, .bottom = abs(color_info->bmiHeader.biHeight)}; struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface); - struct wayland_shm_buffer *shm_buffer = NULL; + struct wayland_shm_buffer *shm_buffer = NULL, *latest_buffer; BOOL flushed = FALSE; HRGN surface_damage_region = NULL; HRGN copy_from_window_region; @@ -352,12 +352,12 @@ static BOOL wayland_window_surface_flush(struct window_surface *window_surface, goto done; }
- if (wws->wayland_surface->latest_window_buffer) + if ((latest_buffer = get_window_surface_contents(window_surface->hwnd))) { - TRACE("latest_window_buffer=%p\n", wws->wayland_surface->latest_window_buffer); + TRACE("latest_window_buffer=%p\n", latest_buffer); /* If we have a latest buffer, use it as the source of all pixel * data that are not contained in the bounds of the flush... */ - if (wws->wayland_surface->latest_window_buffer != shm_buffer) + if (latest_buffer != shm_buffer) { HRGN copy_from_latest_region = NtGdiCreateRectRgn(0, 0, 0, 0); if (!copy_from_latest_region) @@ -367,13 +367,14 @@ static BOOL wayland_window_surface_flush(struct window_surface *window_surface, } NtGdiCombineRgn(copy_from_latest_region, shm_buffer->damage_region, surface_damage_region, RGN_DIFF); - wayland_shm_buffer_copy(wws->wayland_surface->latest_window_buffer, + wayland_shm_buffer_copy(latest_buffer, shm_buffer, copy_from_latest_region); NtGdiDeleteObjectApp(copy_from_latest_region); } /* ... and use the window_surface as the source of pixel data contained * in the flush bounds. */ copy_from_window_region = surface_damage_region; + wayland_shm_buffer_unref(latest_buffer); } else { @@ -389,12 +390,6 @@ static BOOL wayland_window_surface_flush(struct window_surface *window_surface, wl_display_flush(process_wayland.wl_display);
NtGdiSetRectRgn(shm_buffer->damage_region, 0, 0, 0, 0); - /* Update the latest window buffer for the wayland surface. Note that we - * only care whether the buffer contains the latest window contents, - * it's irrelevant if it was actually committed or not. */ - if (wws->wayland_surface->latest_window_buffer) - wayland_shm_buffer_unref(wws->wayland_surface->latest_window_buffer); - wayland_shm_buffer_ref((wws->wayland_surface->latest_window_buffer = shm_buffer));
done: if (surface_damage_region) NtGdiDeleteObjectApp(surface_damage_region);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/window_surface.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index 1781018a17f..b4aea7ab580 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -385,12 +385,11 @@ static BOOL wayland_window_surface_flush(struct window_surface *window_surface, }
wayland_shm_buffer_copy_data(shm_buffer, color_bits, &surface_rect, copy_from_window_region); + NtGdiSetRectRgn(shm_buffer->damage_region, 0, 0, 0, 0);
flushed = set_window_surface_contents(window_surface->hwnd, shm_buffer, surface_damage_region); wl_display_flush(process_wayland.wl_display);
- NtGdiSetRectRgn(shm_buffer->damage_region, 0, 0, 0, 0); - done: if (surface_damage_region) NtGdiDeleteObjectApp(surface_damage_region); return flushed;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/wayland_surface.c | 3 --- dlls/winewayland.drv/waylanddrv.h | 3 ++- dlls/winewayland.drv/window.c | 32 ++++++++++++++++---------- 3 files changed, 22 insertions(+), 16 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 040a07463a0..146c688ef4c 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -232,9 +232,6 @@ void wayland_surface_destroy(struct wayland_surface *surface)
pthread_mutex_unlock(&surface->mutex);
- if (surface->latest_window_buffer) - wayland_shm_buffer_unref(surface->latest_window_buffer); - wl_display_flush(process_wayland.wl_display);
pthread_mutex_destroy(&surface->mutex); diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 35c18ffe468..5644045109c 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -198,7 +198,6 @@ struct wayland_surface struct wp_viewport *wp_viewport; pthread_mutex_t mutex; struct wayland_surface_config pending, requested, processing, current; - struct wayland_shm_buffer *latest_window_buffer; BOOL resizing; struct wayland_window_config window; struct wayland_client_surface *client; @@ -285,6 +284,8 @@ struct wayland_win_data struct rb_entry entry; /* hwnd that this private data belongs to */ HWND hwnd; + /* last buffer that was set as window contents */ + struct wayland_shm_buffer *window_contents; /* wayland surface (if any) for this window */ struct wayland_surface *wayland_surface; /* wine window_surface backing this window */ diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index ce755de6b9e..a4446b34c56 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -125,6 +125,7 @@ static void wayland_win_data_destroy(struct wayland_win_data *data) window_surface_release(data->window_surface); } if (data->wayland_surface) wayland_surface_destroy(data->wayland_surface); + if (data->window_contents) wayland_shm_buffer_unref(data->window_contents); free(data); }
@@ -714,10 +715,15 @@ struct wayland_surface *wayland_surface_lock_hwnd(HWND hwnd) BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffer, HRGN damage_region) { struct wayland_surface *wayland_surface; + struct wayland_win_data *data; BOOL committed = FALSE;
- if ((wayland_surface = wayland_surface_lock_hwnd(hwnd))) + if (!(data = wayland_win_data_get(hwnd))) return FALSE; + + if ((wayland_surface = data->wayland_surface)) { + pthread_mutex_lock(&wayland_surface->mutex); + if (wayland_surface_reconfigure(wayland_surface)) { wayland_surface_attach_shm(wayland_surface, shm_buffer, damage_region); @@ -729,27 +735,29 @@ BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffe TRACE("Wayland surface not configured yet, not flushing\n"); }
- /* Update the latest window buffer for the wayland surface. Note that we - * only care whether the buffer contains the latest window contents, - * it's irrelevant if it was actually committed or not. */ - if (wayland_surface->latest_window_buffer) - wayland_shm_buffer_unref(wayland_surface->latest_window_buffer); - wayland_shm_buffer_ref((wayland_surface->latest_window_buffer = shm_buffer)); - pthread_mutex_unlock(&wayland_surface->mutex); }
+ /* Update the latest window buffer for the wayland surface. Note that we + * only care whether the buffer contains the latest window contents, + * it's irrelevant if it was actually committed or not. */ + if (data->window_contents) + wayland_shm_buffer_unref(data->window_contents); + wayland_shm_buffer_ref((data->window_contents = shm_buffer)); + + wayland_win_data_release(data); + return committed; }
struct wayland_shm_buffer *get_window_surface_contents(HWND hwnd) { - struct wayland_surface *wayland_surface; struct wayland_shm_buffer *shm_buffer; + struct wayland_win_data *data;
- if (!(wayland_surface = wayland_surface_lock_hwnd(hwnd))) return NULL; - if ((shm_buffer = wayland_surface->latest_window_buffer)) wayland_shm_buffer_ref(shm_buffer); - pthread_mutex_unlock(&wayland_surface->mutex); + if (!(data = wayland_win_data_get(hwnd))) return NULL; + if ((shm_buffer = data->window_contents)) wayland_shm_buffer_ref(shm_buffer); + wayland_win_data_release(data);
return shm_buffer; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/waylanddrv.h | 7 ------- dlls/winewayland.drv/window.c | 12 +---------- dlls/winewayland.drv/window_surface.c | 29 --------------------------- 3 files changed, 1 insertion(+), 47 deletions(-)
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 5644045109c..85df9865a3d 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -267,13 +267,6 @@ struct wayland_shm_buffer *wayland_shm_buffer_create(int width, int height, void wayland_shm_buffer_ref(struct wayland_shm_buffer *shm_buffer); void wayland_shm_buffer_unref(struct wayland_shm_buffer *shm_buffer);
-/********************************************************************** - * Wayland window surface - */ - -void wayland_window_surface_update_wayland_surface(struct window_surface *surface, const RECT *visible_rect, - struct wayland_surface *wayland_surface); - /********************************************************************** * Wayland Window */ diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index a4446b34c56..7b273fdd202 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -119,11 +119,7 @@ static void wayland_win_data_destroy(struct wayland_win_data *data)
pthread_mutex_unlock(&win_data_mutex);
- if (data->window_surface) - { - wayland_window_surface_update_wayland_surface(data->window_surface, NULL, NULL); - window_surface_release(data->window_surface); - } + if (data->window_surface) window_surface_release(data->window_surface); if (data->wayland_surface) wayland_surface_destroy(data->wayland_surface); if (data->window_contents) wayland_shm_buffer_unref(data->window_contents); free(data); @@ -210,8 +206,6 @@ static void wayland_win_data_update_wayland_surface(struct wayland_win_data *dat /* We don't want wayland surfaces for child windows. */ if (parent != NtUserGetDesktopWindow() && parent != 0) { - if (data->window_surface) - wayland_window_surface_update_wayland_surface(data->window_surface, NULL, NULL); if (surface) wayland_surface_destroy(surface); surface = NULL; goto out; @@ -248,10 +242,6 @@ static void wayland_win_data_update_wayland_surface(struct wayland_win_data *dat
pthread_mutex_unlock(&surface->mutex);
- if (data->window_surface) - wayland_window_surface_update_wayland_surface(data->window_surface, - &data->rects.visible, surface); - /* Size/position changes affect the effective pointer constraint, so update * it as needed. */ if (data->hwnd == NtUserGetForegroundWindow()) reapply_cursor_clipping(); diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index b4aea7ab580..36bbb2d4f67 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -43,7 +43,6 @@ struct wayland_buffer_queue struct wayland_window_surface { struct window_surface header; - struct wayland_surface *wayland_surface; struct wayland_buffer_queue *wayland_buffer_queue; };
@@ -329,12 +328,6 @@ static BOOL wayland_window_surface_flush(struct window_surface *window_surface, HRGN surface_damage_region = NULL; HRGN copy_from_window_region;
- if (!wws->wayland_surface) - { - ERR("missing wayland surface=%p, returning\n", wws->wayland_surface); - goto done; - } - surface_damage_region = NtGdiCreateRectRgn(rect->left + dirty->left, rect->top + dirty->top, rect->left + dirty->right, rect->top + dirty->bottom); if (!surface_damage_region) @@ -446,28 +439,6 @@ static struct window_surface *wayland_window_surface_create(HWND hwnd, const REC return window_surface; }
-/*********************************************************************** - * wayland_window_surface_update_wayland_surface - */ -void wayland_window_surface_update_wayland_surface(struct window_surface *window_surface, const RECT *visible_rect, - struct wayland_surface *wayland_surface) -{ - struct wayland_window_surface *wws; - - /* ignore calls with the dummy surface */ - if (window_surface->funcs != &wayland_window_surface_funcs) return; - - wws = wayland_window_surface_cast(window_surface); - window_surface_lock(window_surface); - - TRACE("surface=%p hwnd=%p visible_rect=%s wayland_surface=%p\n", wws, window_surface->hwnd, - wine_dbgstr_rect(visible_rect), wayland_surface); - - wws->wayland_surface = wayland_surface; - window_surface_unlock(window_surface); -} - - /*********************************************************************** * WAYLAND_CreateWindowSurface */
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/waylanddrv.h | 2 -- dlls/winewayland.drv/window.c | 5 ----- 2 files changed, 7 deletions(-)
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 85df9865a3d..f6d4f2e519c 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -281,8 +281,6 @@ struct wayland_win_data struct wayland_shm_buffer *window_contents; /* wayland surface (if any) for this window */ struct wayland_surface *wayland_surface; - /* wine window_surface backing this window */ - struct window_surface *window_surface; /* window rects, relative to parent client area */ struct window_rects rects; BOOL managed; diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 7b273fdd202..4a621115c03 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -119,7 +119,6 @@ static void wayland_win_data_destroy(struct wayland_win_data *data)
pthread_mutex_unlock(&win_data_mutex);
- if (data->window_surface) window_surface_release(data->window_surface); if (data->wayland_surface) wayland_surface_destroy(data->wayland_surface); if (data->window_contents) wayland_shm_buffer_unref(data->window_contents); free(data); @@ -451,10 +450,6 @@ void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, cons data->rects = *new_rects; data->managed = managed;
- if (surface) window_surface_add_ref(surface); - if (data->window_surface) window_surface_release(data->window_surface); - data->window_surface = surface; - wayland_win_data_update_wayland_surface(data); if (data->wayland_surface) wayland_win_data_update_wayland_state(data);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/opengl.c | 7 +-- dlls/winewayland.drv/wayland_surface.c | 84 ++++++++++++++------------ dlls/winewayland.drv/waylanddrv.h | 1 + 3 files changed, 49 insertions(+), 43 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index b99d80cbcf2..fe7499f5256 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -218,13 +218,10 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, int for client_width = client_height = 1; pthread_mutex_unlock(&wayland_surface->mutex); } - else if ((wayland_surface = wayland_surface_create(0))) + else { - gl->client = wayland_surface_get_client(wayland_surface); + gl->client = wayland_client_surface_create(hwnd); client_width = client_height = 1; - /* It's fine to destroy the wayland surface, the client surface - * can safely outlive it. */ - wayland_surface_destroy(wayland_surface); } if (!gl->client) goto err;
diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 146c688ef4c..79b73f24f6c 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -774,36 +774,26 @@ BOOL wayland_client_surface_release(struct wayland_client_surface *client) return TRUE; }
-/********************************************************************** - * wayland_surface_get_client - */ -struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface) +struct wayland_client_surface *wayland_client_surface_create(HWND hwnd) { + struct wayland_client_surface *client; struct wl_region *empty_region;
- if (surface->client) - { - InterlockedIncrement(&surface->client->ref); - return surface->client; - } - - surface->client = calloc(1, sizeof(*surface->client)); - if (!surface->client) + if (!(client = calloc(1, sizeof(*client)))) { ERR("Failed to allocate space for client surface\n"); - goto err; + return NULL; } + client->ref = 1;
- surface->client->ref = 1; - - surface->client->wl_surface = + client->wl_surface = wl_compositor_create_surface(process_wayland.wl_compositor); - if (!surface->client->wl_surface) + if (!client->wl_surface) { ERR("Failed to create client wl_surface\n"); goto err; } - wl_surface_set_user_data(surface->client->wl_surface, surface->hwnd); + wl_surface_set_user_data(client->wl_surface, hwnd);
/* Let parent handle all pointer events. */ empty_region = wl_compositor_create_region(process_wayland.wl_compositor); @@ -812,42 +802,60 @@ struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface ERR("Failed to create wl_region\n"); goto err; } - wl_surface_set_input_region(surface->client->wl_surface, empty_region); + wl_surface_set_input_region(client->wl_surface, empty_region); wl_region_destroy(empty_region);
- surface->client->wl_subsurface = + if (process_wayland.wp_viewporter) + { + client->wp_viewport = + wp_viewporter_get_viewport(process_wayland.wp_viewporter, + client->wl_surface); + } + + return client; + +err: + wayland_client_surface_release(client); + return NULL; +} + +/********************************************************************** + * wayland_surface_get_client + */ +struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface) +{ + struct wayland_client_surface *client; + + if ((client = surface->client)) + { + InterlockedIncrement(&client->ref); + return client; + } + + if (!(client = wayland_client_surface_create(surface->hwnd))) + return NULL; + + client->wl_subsurface = wl_subcompositor_get_subsurface(process_wayland.wl_subcompositor, - surface->client->wl_surface, + client->wl_surface, surface->wl_surface); - if (!surface->client->wl_subsurface) + if (!client->wl_subsurface) { ERR("Failed to create client wl_subsurface\n"); goto err; } /* Present contents independently of the parent surface. */ - wl_subsurface_set_desync(surface->client->wl_subsurface); - - surface->client->wp_viewport = - wp_viewporter_get_viewport(process_wayland.wp_viewporter, - surface->client->wl_surface); - if (!surface->client->wp_viewport) - { - ERR("Failed to create client wp_viewport\n"); - goto err; - } + wl_subsurface_set_desync(client->wl_subsurface);
wayland_surface_reconfigure_client(surface); /* Commit to apply subsurface positioning. */ wl_surface_commit(surface->wl_surface);
- return surface->client; + surface->client = client; + return client;
err: - if (surface->client) - { - wayland_client_surface_release(surface->client); - surface->client = NULL; - } + wayland_client_surface_release(client); return NULL; }
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index f6d4f2e519c..c1b647435ab 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -253,6 +253,7 @@ 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); struct wayland_client_surface *wayland_surface_get_client(struct wayland_surface *surface); BOOL wayland_client_surface_release(struct wayland_client_surface *client); void wayland_surface_ensure_contents(struct wayland_surface *surface);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/opengl.c | 53 +++++++++++-------- dlls/winewayland.drv/vulkan.c | 28 +++++----- dlls/winewayland.drv/wayland_keyboard.c | 10 ++-- dlls/winewayland.drv/wayland_pointer.c | 30 +++++++---- dlls/winewayland.drv/wayland_surface.c | 30 +++++------ dlls/winewayland.drv/waylanddrv.h | 2 - dlls/winewayland.drv/window.c | 68 ++++++++++--------------- 7 files changed, 111 insertions(+), 110 deletions(-)
diff --git a/dlls/winewayland.drv/opengl.c b/dlls/winewayland.drv/opengl.c index fe7499f5256..94ff32c81f1 100644 --- a/dlls/winewayland.drv/opengl.c +++ b/dlls/winewayland.drv/opengl.c @@ -166,12 +166,12 @@ static void wayland_gl_drawable_release(struct wayland_gl_drawable *gl) if (gl->client) { HWND hwnd = wl_surface_get_user_data(gl->client->wl_surface); - struct wayland_surface *wayland_surface = wayland_surface_lock_hwnd(hwnd); + struct wayland_win_data *data = wayland_win_data_get(hwnd);
- if (wayland_client_surface_release(gl->client) && wayland_surface) - wayland_surface->client = NULL; + if (wayland_client_surface_release(gl->client) && data && data->wayland_surface) + data->wayland_surface->client = NULL;
- if (wayland_surface) pthread_mutex_unlock(&wayland_surface->mutex); + if (data) wayland_win_data_release(data); }
free(gl); @@ -194,6 +194,7 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, int for struct wayland_gl_drawable *gl; struct wayland_surface *wayland_surface; int client_width = 0, client_height = 0; + struct wayland_win_data *data;
TRACE("hwnd=%p format=%d\n", hwnd, format);
@@ -207,16 +208,24 @@ static struct wayland_gl_drawable *wayland_gl_drawable_create(HWND hwnd, int for /* Get the client surface for the HWND. If don't have a wayland surface * (e.g., HWND_MESSAGE windows) just create a dummy surface to act as the * target render surface. */ - if ((wayland_surface = wayland_surface_lock_hwnd(hwnd))) + if ((data = wayland_win_data_get(hwnd))) { - gl->client = wayland_surface_get_client(wayland_surface); - client_width = wayland_surface->window.client_rect.right - - wayland_surface->window.client_rect.left; - client_height = wayland_surface->window.client_rect.bottom - - wayland_surface->window.client_rect.top; - if (client_width == 0 || client_height == 0) + if (!(wayland_surface = data->wayland_surface)) + { + gl->client = wayland_client_surface_create(hwnd); client_width = client_height = 1; - pthread_mutex_unlock(&wayland_surface->mutex); + } + else + { + gl->client = wayland_surface_get_client(wayland_surface); + client_width = wayland_surface->window.client_rect.right - + wayland_surface->window.client_rect.left; + client_height = wayland_surface->window.client_rect.bottom - + wayland_surface->window.client_rect.top; + if (client_width == 0 || client_height == 0) + client_width = client_height = 1; + } + wayland_win_data_release(data); } else { @@ -285,23 +294,27 @@ static void wayland_update_gl_drawable(HWND hwnd, struct wayland_gl_drawable *ne
static void wayland_gl_drawable_sync_size(struct wayland_gl_drawable *gl) { - int client_width, client_height; + int client_width = 0, client_height = 0; struct wayland_surface *wayland_surface; + struct wayland_win_data *data;
if (InterlockedCompareExchange(&gl->resized, FALSE, TRUE)) { - if (!(wayland_surface = wayland_surface_lock_hwnd(gl->hwnd))) return; + if (!(data = wayland_win_data_get(gl->hwnd))) return; + + if ((wayland_surface = data->wayland_surface)) + { + client_width = wayland_surface->window.client_rect.right - + wayland_surface->window.client_rect.left; + client_height = wayland_surface->window.client_rect.bottom - + wayland_surface->window.client_rect.top; + }
- client_width = wayland_surface->window.client_rect.right - - wayland_surface->window.client_rect.left; - client_height = wayland_surface->window.client_rect.bottom - - wayland_surface->window.client_rect.top; if (client_width == 0 || client_height == 0) client_width = client_height = 1; + wayland_win_data_release(data);
wl_egl_window_resize(gl->wl_egl_window, client_width, client_height, 0, 0); - - pthread_mutex_unlock(&wayland_surface->mutex); } }
diff --git a/dlls/winewayland.drv/vulkan.c b/dlls/winewayland.drv/vulkan.c index a828d736da1..7a075a925b7 100644 --- a/dlls/winewayland.drv/vulkan.c +++ b/dlls/winewayland.drv/vulkan.c @@ -58,22 +58,15 @@ static VkBool32 (*pvkGetPhysicalDeviceWaylandPresentationSupportKHR)(VkPhysicalD
static const struct vulkan_driver_funcs wayland_vulkan_driver_funcs;
-static HWND wine_vk_surface_get_hwnd(struct wayland_client_surface *client) -{ - return wl_surface_get_user_data(client->wl_surface); -} - static void wine_vk_surface_destroy(struct wayland_client_surface *client) { - HWND hwnd = wine_vk_surface_get_hwnd(client); - struct wayland_surface *wayland_surface = wayland_surface_lock_hwnd(hwnd); + 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) && wayland_surface) - { - wayland_surface->client = NULL; - } + if (wayland_client_surface_release(client) && data && data->wayland_surface) + data->wayland_surface->client = NULL;
- if (wayland_surface) pthread_mutex_unlock(&wayland_surface->mutex); + if (data) wayland_win_data_release(data); }
static VkResult wayland_vulkan_surface_create(HWND hwnd, VkInstance instance, VkSurfaceKHR *surface, void **private) @@ -82,18 +75,21 @@ static VkResult wayland_vulkan_surface_create(HWND hwnd, VkInstance instance, Vk VkWaylandSurfaceCreateInfoKHR create_info_host; struct wayland_surface *wayland_surface; struct wayland_client_surface *client; + struct wayland_win_data *data;
TRACE("%p %p %p %p\n", hwnd, instance, surface, private);
- wayland_surface = wayland_surface_lock_hwnd(hwnd); - if (!wayland_surface) + if (!(data = wayland_win_data_get(hwnd))) { ERR("Failed to find wayland surface for hwnd=%p\n", hwnd); return VK_ERROR_OUT_OF_HOST_MEMORY; }
- client = wayland_surface_get_client(wayland_surface); - pthread_mutex_unlock(&wayland_surface->mutex); + if ((wayland_surface = data->wayland_surface)) + client = wayland_surface_get_client(wayland_surface); + else + client = wayland_client_surface_create(hwnd); + wayland_win_data_release(data);
if (!client) { diff --git a/dlls/winewayland.drv/wayland_keyboard.c b/dlls/winewayland.drv/wayland_keyboard.c index 5c2fe15273e..8f7b6dce30f 100644 --- a/dlls/winewayland.drv/wayland_keyboard.c +++ b/dlls/winewayland.drv/wayland_keyboard.c @@ -736,12 +736,13 @@ static void keyboard_handle_keymap(void *data, struct wl_keyboard *wl_keyboard, xkb_keymap_unref(xkb_keymap); }
-static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, +static void keyboard_handle_enter(void *private, struct wl_keyboard *wl_keyboard, uint32_t serial, struct wl_surface *wl_surface, struct wl_array *keys) { struct wayland_keyboard *keyboard = &process_wayland.keyboard; struct wayland_surface *surface; + struct wayland_win_data *data; HWND hwnd;
if (!wl_surface) return; @@ -758,7 +759,9 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, NtUserPostMessage(keyboard->focused_hwnd, WM_INPUTLANGCHANGEREQUEST, 0 /*FIXME*/, (LPARAM)keyboard_hkl);
- if ((surface = wayland_surface_lock_hwnd(hwnd))) + if (!(data = wayland_win_data_get(hwnd))) return; + + if ((surface = data->wayland_surface)) { /* TODO: Drop the internal message and call NtUserSetForegroundWindow * directly once it's updated to not explicitly deactivate the old @@ -766,8 +769,9 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *wl_keyboard, * are in the same non-current thread. */ if (surface->window.managed) NtUserPostMessage(hwnd, WM_WAYLAND_SET_FOREGROUND, 0, 0); - pthread_mutex_unlock(&surface->mutex); } + + wayland_win_data_release(data); }
static void keyboard_handle_leave(void *data, struct wl_keyboard *wl_keyboard, diff --git a/dlls/winewayland.drv/wayland_pointer.c b/dlls/winewayland.drv/wayland_pointer.c index b549aa28257..07e56ec2451 100644 --- a/dlls/winewayland.drv/wayland_pointer.c +++ b/dlls/winewayland.drv/wayland_pointer.c @@ -53,9 +53,15 @@ static void pointer_handle_motion_internal(wl_fixed_t sx, wl_fixed_t sy) HWND hwnd; POINT screen; struct wayland_surface *surface; + struct wayland_win_data *data;
if (!(hwnd = wayland_pointer_get_focused_hwnd())) return; - if (!(surface = wayland_surface_lock_hwnd(hwnd))) return; + if (!(data = wayland_win_data_get(hwnd))) return; + if (!(surface = data->wayland_surface)) + { + wayland_win_data_release(data); + return; + }
window_rect = &surface->window.rect;
@@ -72,7 +78,7 @@ static void pointer_handle_motion_internal(wl_fixed_t sx, wl_fixed_t sy) if (screen.y >= window_rect->bottom) screen.y = window_rect->bottom - 1; else if (screen.y < window_rect->top) screen.y = window_rect->top;
- pthread_mutex_unlock(&surface->mutex); + wayland_win_data_release(data);
input.type = INPUT_MOUSE; input.mi.dx = screen.x; @@ -257,14 +263,12 @@ static void relative_pointer_v1_relative_motion(void *data, struct wayland_surface *surface;
if (!(hwnd = wayland_pointer_get_focused_hwnd())) return; - if (!(surface = wayland_surface_lock_hwnd(hwnd))) return;
wayland_surface_coords_to_window(surface, wl_fixed_to_double(dx), wl_fixed_to_double(dy), (int *)&screen.x, (int *)&screen.y);
- pthread_mutex_unlock(&surface->mutex);
input.type = INPUT_MOUSE; input.mi.dx = screen.x; @@ -629,16 +633,22 @@ static void wayland_set_cursor(HWND hwnd, HCURSOR hcursor, BOOL use_hcursor) { struct wayland_pointer *pointer = &process_wayland.pointer; struct wayland_surface *surface; + struct wayland_win_data *data; double scale; BOOL reapply_clip = FALSE;
- if ((surface = wayland_surface_lock_hwnd(hwnd))) + if ((data = wayland_win_data_get(hwnd))) { + if (!(surface = data->wayland_surface)) + { + wayland_win_data_release(data); + return; + } scale = surface->window.scale; if (use_hcursor) surface->hcursor = hcursor; else hcursor = surface->hcursor; use_hcursor = TRUE; - pthread_mutex_unlock(&surface->mutex); + wayland_win_data_release(data); } else { @@ -859,22 +869,24 @@ BOOL WAYLAND_ClipCursor(const RECT *clip, BOOL reset) struct wayland_pointer *pointer = &process_wayland.pointer; struct wl_surface *wl_surface = NULL; struct wayland_surface *surface = NULL; + struct wayland_win_data *data; BOOL covers_vscreen = FALSE; RECT confine_rect;
TRACE("clip=%s reset=%d\n", wine_dbgstr_rect(clip), reset);
- if ((surface = wayland_surface_lock_hwnd(NtUserGetForegroundWindow()))) + if (!(data = wayland_win_data_get(NtUserGetForegroundWindow()))) return FALSE; + if ((surface = data->wayland_surface)) { wl_surface = surface->wl_surface; if (clip) wayland_surface_calc_confine(surface, clip, &confine_rect); covers_vscreen = wayland_surface_client_covers_vscreen(surface); - pthread_mutex_unlock(&surface->mutex); } + wayland_win_data_release(data);
/* Since we are running in the context of the foreground thread we know * that the wl_surface of the foreground HWND will not be invalidated, - * so we can access it without having the surface lock. */ + * so we can access it without having the win data lock. */ pthread_mutex_lock(&pointer->mutex); wayland_pointer_update_constraint(wl_surface, (clip && wl_surface) ? &confine_rect : NULL, diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 79b73f24f6c..cfd8b3c9368 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -34,20 +34,21 @@
WINE_DEFAULT_DEBUG_CHANNEL(waylanddrv);
-static void xdg_surface_handle_configure(void *data, struct xdg_surface *xdg_surface, +static void xdg_surface_handle_configure(void *private, struct xdg_surface *xdg_surface, uint32_t serial) { struct wayland_surface *surface; BOOL should_post = FALSE, initial_configure = FALSE; - HWND hwnd = data; + struct wayland_win_data *data; + HWND hwnd = private;
TRACE("serial=%u\n", serial);
- if (!(surface = wayland_surface_lock_hwnd(hwnd))) return; + if (!(data = wayland_win_data_get(hwnd))) return;
/* Handle this event only if wayland_surface is still associated with * the target xdg_surface. */ - if (surface->xdg_surface == xdg_surface) + if ((surface = data->wayland_surface) && surface->xdg_surface == xdg_surface) { /* If we have a previously requested config, we have already sent a * WM_WAYLAND_CONFIGURE which hasn't been handled yet. In that case, @@ -59,7 +60,7 @@ static void xdg_surface_handle_configure(void *data, struct xdg_surface *xdg_sur memset(&surface->pending, 0, sizeof(surface->pending)); }
- pthread_mutex_unlock(&surface->mutex); + wayland_win_data_release(data);
if (should_post) NtUserPostMessage(hwnd, WM_WAYLAND_CONFIGURE, 0, 0);
@@ -76,15 +77,16 @@ static const struct xdg_surface_listener xdg_surface_listener = xdg_surface_handle_configure };
-static void xdg_toplevel_handle_configure(void *data, +static void xdg_toplevel_handle_configure(void *private, struct xdg_toplevel *xdg_toplevel, int32_t width, int32_t height, struct wl_array *states) { struct wayland_surface *surface; - HWND hwnd = data; + HWND hwnd = private; uint32_t *state; enum wayland_surface_config_state config_state = 0; + struct wayland_win_data *data;
wl_array_for_each(state, states) { @@ -112,16 +114,16 @@ static void xdg_toplevel_handle_configure(void *data,
TRACE("hwnd=%p %dx%d,%#x\n", hwnd, width, height, config_state);
- if (!(surface = wayland_surface_lock_hwnd(hwnd))) return; + if (!(data = wayland_win_data_get(hwnd))) return;
- if (surface->xdg_toplevel == xdg_toplevel) + if ((surface = data->wayland_surface) && surface->xdg_toplevel == xdg_toplevel) { surface->pending.width = width; surface->pending.height = height; surface->pending.state = config_state; }
- pthread_mutex_unlock(&surface->mutex); + wayland_win_data_release(data); }
static void xdg_toplevel_handle_close(void *data, struct xdg_toplevel *xdg_toplevel) @@ -153,8 +155,6 @@ struct wayland_surface *wayland_surface_create(HWND hwnd)
TRACE("surface=%p\n", surface);
- pthread_mutex_init(&surface->mutex, NULL); - surface->hwnd = hwnd; surface->wl_surface = wl_compositor_create_surface(process_wayland.wl_compositor); if (!surface->wl_surface) @@ -204,8 +204,6 @@ void wayland_surface_destroy(struct wayland_surface *surface) process_wayland.keyboard.focused_hwnd = NULL; pthread_mutex_unlock(&process_wayland.keyboard.mutex);
- pthread_mutex_lock(&surface->mutex); - if (surface->wp_viewport) { wp_viewport_destroy(surface->wp_viewport); @@ -230,12 +228,8 @@ void wayland_surface_destroy(struct wayland_surface *surface) surface->wl_surface = NULL; }
- pthread_mutex_unlock(&surface->mutex); - wl_display_flush(process_wayland.wl_display);
- pthread_mutex_destroy(&surface->mutex); - free(surface); }
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index c1b647435ab..4551540e0d4 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -196,7 +196,6 @@ struct wayland_surface struct xdg_surface *xdg_surface; struct xdg_toplevel *xdg_toplevel; struct wp_viewport *wp_viewport; - pthread_mutex_t mutex; struct wayland_surface_config pending, requested, processing, current; BOOL resizing; struct wayland_window_config window; @@ -242,7 +241,6 @@ void wayland_surface_clear_role(struct wayland_surface *surface); void wayland_surface_attach_shm(struct wayland_surface *surface, struct wayland_shm_buffer *shm_buffer, HRGN surface_damage_region); -struct wayland_surface *wayland_surface_lock_hwnd(HWND hwnd); BOOL wayland_surface_reconfigure(struct wayland_surface *surface); BOOL wayland_surface_config_is_compatible(struct wayland_surface_config *conf, int width, int height, diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 4a621115c03..942d56870a3 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -216,8 +216,6 @@ static void wayland_win_data_update_wayland_surface(struct wayland_win_data *dat visible = (NtUserGetWindowLongW(data->hwnd, GWL_STYLE) & WS_VISIBLE) == WS_VISIBLE; xdg_visible = surface->xdg_toplevel != NULL;
- pthread_mutex_lock(&surface->mutex); - if (visible != xdg_visible) { /* If we have a pre-existing surface ensure it has no role. */ @@ -239,8 +237,6 @@ static void wayland_win_data_update_wayland_surface(struct wayland_win_data *dat
wayland_win_data_get_config(data, &surface->window);
- pthread_mutex_unlock(&surface->mutex); - /* Size/position changes affect the effective pointer constraint, so update * it as needed. */ if (data->hwnd == NtUserGetForegroundWindow()) reapply_cursor_clipping(); @@ -255,8 +251,6 @@ static void wayland_win_data_update_wayland_state(struct wayland_win_data *data) struct wayland_surface *surface = data->wayland_surface; BOOL processing_config;
- pthread_mutex_lock(&surface->mutex); - if (!surface->xdg_toplevel) goto out;
processing_config = surface->processing.serial && @@ -301,7 +295,6 @@ static void wayland_win_data_update_wayland_state(struct wayland_win_data *data) }
out: - pthread_mutex_unlock(&surface->mutex); wl_display_flush(process_wayland.wl_display); }
@@ -466,20 +459,26 @@ static void wayland_configure_window(HWND hwnd) DWORD style; BOOL needs_enter_size_move = FALSE; BOOL needs_exit_size_move = FALSE; + struct wayland_win_data *data;
- if (!(surface = wayland_surface_lock_hwnd(hwnd))) return; + if (!(data = wayland_win_data_get(hwnd))) return; + if (!(surface = data->wayland_surface)) + { + wayland_win_data_release(data); + return; + }
if (!surface->xdg_toplevel) { TRACE("missing xdg_toplevel, returning\n"); - pthread_mutex_unlock(&surface->mutex); + wayland_win_data_release(data); return; }
if (!surface->requested.serial) { TRACE("requested configure event already handled, returning\n"); - pthread_mutex_unlock(&surface->mutex); + wayland_win_data_release(data); return; }
@@ -541,7 +540,7 @@ static void wayland_configure_window(HWND hwnd) wayland_surface_coords_to_window(surface, width, height, &window_width, &window_height);
- pthread_mutex_unlock(&surface->mutex); + wayland_win_data_release(data);
TRACE("processing=%dx%d,%#x\n", width, height, state);
@@ -620,14 +619,16 @@ static enum xdg_toplevel_resize_edge hittest_to_resize_edge(WPARAM hittest) */ void WAYLAND_SetWindowText(HWND hwnd, LPCWSTR text) { - struct wayland_surface *surface = wayland_surface_lock_hwnd(hwnd); + struct wayland_surface *surface; + struct wayland_win_data *data;
TRACE("hwnd=%p text=%s\n", hwnd, wine_dbgstr_w(text));
- if (surface) + if ((data = wayland_win_data_get(hwnd))) { - if (surface->xdg_toplevel) wayland_surface_set_title(surface, text); - pthread_mutex_unlock(&surface->mutex); + if ((surface = data->wayland_surface) && surface->xdg_toplevel) + wayland_surface_set_title(surface, text); + wayland_win_data_release(data); } }
@@ -641,6 +642,7 @@ LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam) uint32_t button_serial; struct wl_seat *wl_seat; struct wayland_surface *surface; + struct wayland_win_data *data;
TRACE("cmd=%lx hwnd=%p, %lx, %lx\n", (long)command, hwnd, (long)wparam, lparam); @@ -654,11 +656,11 @@ LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam)
if (command == SC_MOVE || command == SC_SIZE) { - if ((surface = wayland_surface_lock_hwnd(hwnd))) + if ((data = wayland_win_data_get(hwnd))) { pthread_mutex_lock(&process_wayland.seat.mutex); wl_seat = process_wayland.seat.wl_seat; - if (wl_seat && surface->xdg_toplevel && button_serial) + if (wl_seat && (surface = data->wayland_surface) && surface->xdg_toplevel && button_serial) { if (command == SC_MOVE) { @@ -671,7 +673,7 @@ LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam) } } pthread_mutex_unlock(&process_wayland.seat.mutex); - pthread_mutex_unlock(&surface->mutex); + wayland_win_data_release(data); ret = 0; } } @@ -680,23 +682,6 @@ LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam) return ret; }
-/********************************************************************** - * wayland_surface_lock_hwnd - */ -struct wayland_surface *wayland_surface_lock_hwnd(HWND hwnd) -{ - struct wayland_win_data *data = wayland_win_data_get(hwnd); - struct wayland_surface *surface; - - if (!data) return NULL; - - if ((surface = data->wayland_surface)) pthread_mutex_lock(&surface->mutex); - - wayland_win_data_release(data); - - return surface; -} - BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffer, HRGN damage_region) { struct wayland_surface *wayland_surface; @@ -707,8 +692,6 @@ BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffe
if ((wayland_surface = data->wayland_surface)) { - pthread_mutex_lock(&wayland_surface->mutex); - if (wayland_surface_reconfigure(wayland_surface)) { wayland_surface_attach_shm(wayland_surface, shm_buffer, damage_region); @@ -719,8 +702,6 @@ BOOL set_window_surface_contents(HWND hwnd, struct wayland_shm_buffer *shm_buffe { TRACE("Wayland surface not configured yet, not flushing\n"); } - - pthread_mutex_unlock(&wayland_surface->mutex); }
/* Update the latest window buffer for the wayland surface. Note that we @@ -750,8 +731,11 @@ struct wayland_shm_buffer *get_window_surface_contents(HWND hwnd) void ensure_window_surface_contents(HWND hwnd) { struct wayland_surface *wayland_surface; + struct wayland_win_data *data; + + if (!(data = wayland_win_data_get(hwnd))) return;
- if ((wayland_surface = wayland_surface_lock_hwnd(hwnd))) + if ((wayland_surface = data->wayland_surface)) { wayland_surface_ensure_contents(wayland_surface);
@@ -763,7 +747,7 @@ void ensure_window_surface_contents(HWND hwnd) { wl_surface_commit(wayland_surface->wl_surface); } - - pthread_mutex_unlock(&wayland_surface->mutex); } + + wayland_win_data_release(data); }