From: Alexandros Frantzis alexandros.frantzis@collabora.com
Send the surface damage region to the compositor, to enable it to optimize pixel data transfers. --- dlls/winewayland.drv/wayland_surface.c | 26 +++++++++++++++++++++++--- dlls/winewayland.drv/waylanddrv.h | 5 ++++- dlls/winewayland.drv/window_surface.c | 5 +++-- 3 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index ed9ae4ee0e4..13764a2e645 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -223,14 +223,34 @@ void wayland_surface_clear_role(struct wayland_surface *surface) * Attaches a SHM buffer to a wayland surface. */ void wayland_surface_attach_shm(struct wayland_surface *surface, - struct wayland_shm_buffer *shm_buffer) + struct wayland_shm_buffer *shm_buffer, + HRGN surface_damage_region) { + RGNDATA *surface_damage; + TRACE("surface=%p shm_buffer=%p (%dx%d)\n", surface, shm_buffer, shm_buffer->width, shm_buffer->height);
wl_surface_attach(surface->wl_surface, shm_buffer->wl_buffer, 0, 0); - wl_surface_damage_buffer(surface->wl_surface, 0, 0, - shm_buffer->width, shm_buffer->height); + + /* Add surface damage, i.e., which parts of the surface have changed since + * the last surface commit. Note that this is different from the buffer + * damage region. */ + surface_damage = get_region_data(surface_damage_region); + if (surface_damage) + { + RECT *rgn_rect = (RECT *)surface_damage->Buffer; + RECT *rgn_rect_end = rgn_rect + surface_damage->rdh.nCount; + + for (;rgn_rect < rgn_rect_end; rgn_rect++) + { + wl_surface_damage_buffer(surface->wl_surface, + rgn_rect->left, rgn_rect->top, + rgn_rect->right - rgn_rect->left, + rgn_rect->bottom - rgn_rect->top); + } + free(surface_damage); + } }
/********************************************************************** diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 909c8ef5b7b..0fd2a7a6c77 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -146,7 +146,8 @@ void wayland_surface_destroy(struct wayland_surface *surface) DECLSPEC_HIDDEN; void wayland_surface_make_toplevel(struct wayland_surface *surface) DECLSPEC_HIDDEN; void wayland_surface_clear_role(struct wayland_surface *surface) DECLSPEC_HIDDEN; void wayland_surface_attach_shm(struct wayland_surface *surface, - struct wayland_shm_buffer *shm_buffer) DECLSPEC_HIDDEN; + struct wayland_shm_buffer *shm_buffer, + HRGN surface_damage_region) DECLSPEC_HIDDEN;
/********************************************************************** * Wayland SHM buffer @@ -179,6 +180,8 @@ static inline BOOL intersect_rect(RECT *dst, const RECT *src1, const RECT *src2) return !IsRectEmpty(dst); }
+RGNDATA *get_region_data(HRGN region) DECLSPEC_HIDDEN; + /********************************************************************** * USER driver functions */ diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index f88b1eb6010..e1d8ab68ddf 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -277,7 +277,7 @@ static void wayland_window_surface_set_region(struct window_surface *window_surf /********************************************************************** * get_region_data */ -static RGNDATA *get_region_data(HRGN region) +RGNDATA *get_region_data(HRGN region) { RGNDATA *data; DWORD size; @@ -452,7 +452,8 @@ static void wayland_window_surface_flush(struct window_surface *window_surface) pthread_mutex_lock(&wws->wayland_surface->mutex); if (wws->wayland_surface->current_serial) { - wayland_surface_attach_shm(wws->wayland_surface, shm_buffer); + wayland_surface_attach_shm(wws->wayland_surface, shm_buffer, + surface_damage_region); wl_surface_commit(wws->wayland_surface->wl_surface); flushed = TRUE; }