Skip to content

Commit

Permalink
egl-swap: provide damage rectangles to wl_surface
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
chergert committed Mar 4, 2022
1 parent 582b2d3 commit 7d6c362
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 7 deletions.
4 changes: 3 additions & 1 deletion include/wayland-eglsurface.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ EGLBoolean wlEglQueryNativeResourceHook(EGLDisplay dpy,
int *value);

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);
Expand Down
25 changes: 21 additions & 4 deletions src/wayland-eglsurface.c
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,13 @@ EGLint wlEglWaitFrameSync(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
Expand Down Expand Up @@ -191,8 +195,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++) {
int y = rects[i*4+1] + rects[i*4+3];
wl_surface_damage_buffer(surface->wlSurface,
rects[i*4],
surface->height - y,
rects[i*4+2],
rects[i*4+3]);
}
} else {
wl_surface_damage(surface->wlSurface, 0, 0, UINT32_MAX, UINT32_MAX);
}

wl_surface_commit(surface->wlSurface);
surface->ctx.isAttached = EGL_TRUE;

Expand Down Expand Up @@ -257,7 +274,7 @@ damage_thread(void *args)
data->egl.streamFlush(display->devDpy->eglDisplay,
surface->ctx.eglStream);
}
ok = wlEglSendDamageEvent(surface, queue);
ok = wlEglSendDamageEvent(surface, queue, NULL, 0);
surface->ctx.framesProcessed++;
}

Expand Down
4 changes: 2 additions & 2 deletions src/wayland-eglswap.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ EGLBoolean wlEglSwapBuffersWithDamageHook(EGLDisplay eglDisplay, EGLSurface eglS
if (surface->ctx.useDamageThread) {
surface->ctx.framesProduced++;
} else {
res = wlEglSendDamageEvent(surface, surface->wlEventQueue);
res = wlEglSendDamageEvent(surface, surface->wlEventQueue, rects, n_rects);
}
}
wlEglCreateFrameSync(surface);
Expand Down Expand Up @@ -285,7 +285,7 @@ EGLBoolean wlEglPostPresentExport(WlEglSurface *surface) {
if (surface->ctx.useDamageThread) {
surface->ctx.framesProduced++;
} else {
res = wlEglSendDamageEvent(surface, surface->wlEventQueue);
res = wlEglSendDamageEvent(surface, surface->wlEventQueue, NULL, 0);
}

wlEglCreateFrameSync(surface);
Expand Down

0 comments on commit 7d6c362

Please sign in to comment.