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 496a6f1ea60..8d554d6a3fa 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 096dd2bb5fb..45ef876c4eb 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 0d5eb0bd9ff..0e4747fce2f 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; @@ -353,12 +353,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) @@ -368,13 +368,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 { @@ -390,12 +391,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);