116 lines
4.7 KiB
Diff
116 lines
4.7 KiB
Diff
From 8dbdd61b7c07e23bc5b8913fe3d52f32995be98a Mon Sep 17 00:00:00 2001
|
|
From: Christian Hergert <chergert@redhat.com>
|
|
Date: Fri, 23 Aug 2024 19:10:27 +0200
|
|
Subject: [PATCH 4/9] egl-swap: provide damage rectangles to wl_surface
|
|
|
|
Previously, wlEglSendDamageEvent used the entire surface as damage to
|
|
the compositor but in the wrong coordinate system. wl_surface_damage()
|
|
requires coordinates for the surface which could be scaled while
|
|
wl_surface_damage_buffer() expects buffer coordinates which is what
|
|
surface->width and surface->height represent.
|
|
|
|
This ensures that the parameters to eglSwapBuffersWithDamage() are passed
|
|
along to the compositor as well. The coordinate system is flipped between
|
|
eglSwapBuffersWithDamage() and wl_surface_damage_buffer() which is handled
|
|
as well.
|
|
|
|
Signed-off-by: Christian Hergert <chergert@redhat.com>
|
|
---
|
|
include/wayland-eglsurface-internal.h | 4 +++-
|
|
src/wayland-eglsurface.c | 25 +++++++++++++++++++++----
|
|
src/wayland-eglswap.c | 4 ++--
|
|
3 files changed, 26 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/include/wayland-eglsurface-internal.h b/include/wayland-eglsurface-internal.h
|
|
index dfc5fd4..b70b9d3 100644
|
|
--- a/include/wayland-eglsurface-internal.h
|
|
+++ b/include/wayland-eglsurface-internal.h
|
|
@@ -206,7 +206,9 @@ EGLBoolean
|
|
wlEglSurfaceCheckReleasePoints(WlEglDisplay *display, WlEglSurface *surface);
|
|
|
|
EGLBoolean wlEglSendDamageEvent(WlEglSurface *surface,
|
|
- struct wl_event_queue *queue);
|
|
+ struct wl_event_queue *queue,
|
|
+ EGLint *rects,
|
|
+ EGLint n_rects);
|
|
|
|
void wlEglCreateFrameSync(WlEglSurface *surface);
|
|
EGLint wlEglWaitFrameSync(WlEglSurface *surface);
|
|
diff --git a/src/wayland-eglsurface.c b/src/wayland-eglsurface.c
|
|
index da08fb2..1f01616 100644
|
|
--- a/src/wayland-eglsurface.c
|
|
+++ b/src/wayland-eglsurface.c
|
|
@@ -242,9 +242,13 @@ send_explicit_sync_points (WlEglDisplay *display, WlEglSurface *surface,
|
|
}
|
|
|
|
EGLBoolean
|
|
-wlEglSendDamageEvent(WlEglSurface *surface, struct wl_event_queue *queue)
|
|
+wlEglSendDamageEvent(WlEglSurface *surface,
|
|
+ struct wl_event_queue *queue,
|
|
+ EGLint *rects,
|
|
+ EGLint n_rects)
|
|
{
|
|
struct wl_display *wlDpy = surface->wlEglDpy->nativeDpy;
|
|
+ EGLint i;
|
|
|
|
if (surface->ctx.wlStreamResource) {
|
|
/* Attach same buffer to indicate new content for the surface is
|
|
@@ -286,8 +290,21 @@ wlEglSendDamageEvent(WlEglSurface *surface, struct wl_event_queue *queue)
|
|
surface->dy);
|
|
}
|
|
|
|
- wl_surface_damage(surface->wlSurface, 0, 0,
|
|
- surface->width, surface->height);
|
|
+ if (n_rects > 0 &&
|
|
+ (wl_proxy_get_version((struct wl_proxy *)surface->wlSurface) >=
|
|
+ WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)) {
|
|
+ for (i = 0; i < n_rects; i++) {
|
|
+ const EGLint *rect = &rects[i * 4];
|
|
+ // Coordinate systems are flipped between eglSwapBuffersWithDamage
|
|
+ // and wl_surface_damage_buffer, so invert Y values.
|
|
+ int inv_y = surface->height - (rect[1] + rect[3]);
|
|
+ wl_surface_damage_buffer(surface->wlSurface, rect[0], inv_y, rect[2], rect[3]);
|
|
+ }
|
|
+ } else {
|
|
+ wl_surface_damage(surface->wlSurface, 0, 0, UINT32_MAX, UINT32_MAX);
|
|
+ }
|
|
+
|
|
+
|
|
wl_surface_commit(surface->wlSurface);
|
|
surface->ctx.isAttached = EGL_TRUE;
|
|
|
|
@@ -357,7 +374,7 @@ damage_thread(void *args)
|
|
|
|
wlEglCreateFrameSync(surface);
|
|
|
|
- ok = wlEglSendDamageEvent(surface, queue);
|
|
+ ok = wlEglSendDamageEvent(surface, queue, NULL, 0);
|
|
surface->ctx.framesProcessed++;
|
|
|
|
pthread_cond_signal(&surface->condFrameSync);
|
|
diff --git a/src/wayland-eglswap.c b/src/wayland-eglswap.c
|
|
index bf1157d..ea99f49 100644
|
|
--- a/src/wayland-eglswap.c
|
|
+++ b/src/wayland-eglswap.c
|
|
@@ -147,7 +147,7 @@ EGLBoolean wlEglSwapBuffersWithDamageHook(EGLDisplay eglDisplay, EGLSurface eglS
|
|
surface->ctx.framesProduced++;
|
|
} else {
|
|
wlEglCreateFrameSync(surface);
|
|
- res = wlEglSendDamageEvent(surface, surface->wlEventQueue);
|
|
+ res = wlEglSendDamageEvent(surface, surface->wlEventQueue, rects, n_rects);
|
|
wlEglSurfaceCheckReleasePoints(display, surface);
|
|
}
|
|
}
|
|
@@ -434,7 +434,7 @@ EGLBoolean wlEglPostPresentExport2(WlEglSurface *surface,
|
|
surface->ctx.framesProduced++;
|
|
} else {
|
|
wlEglCreateFrameSync(surface);
|
|
- res = wlEglSendDamageEvent(surface, surface->wlEventQueue);
|
|
+ res = wlEglSendDamageEvent(surface, surface->wlEventQueue, NULL, 0);
|
|
}
|
|
|
|
// Release wlEglSurface lock.
|
|
--
|
|
2.43.0
|
|
|