Skip to content

Commit 1a46148

Browse files
committed
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 <[email protected]>
1 parent 582b2d3 commit 1a46148

File tree

3 files changed

+25
-7
lines changed

3 files changed

+25
-7
lines changed

include/wayland-eglsurface.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,9 @@ EGLBoolean wlEglQueryNativeResourceHook(EGLDisplay dpy,
160160
int *value);
161161

162162
EGLBoolean wlEglSendDamageEvent(WlEglSurface *surface,
163-
struct wl_event_queue *queue);
163+
struct wl_event_queue *queue,
164+
EGLint *rects,
165+
EGLint n_rects);
164166

165167
void wlEglCreateFrameSync(WlEglSurface *surface);
166168
EGLint wlEglWaitFrameSync(WlEglSurface *surface);

src/wayland-eglsurface.c

+20-4
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,13 @@ EGLint wlEglWaitFrameSync(WlEglSurface *surface)
161161
}
162162

163163
EGLBoolean
164-
wlEglSendDamageEvent(WlEglSurface *surface, struct wl_event_queue *queue)
164+
wlEglSendDamageEvent(WlEglSurface *surface,
165+
struct wl_event_queue *queue,
166+
EGLint *rects,
167+
EGLint n_rects)
165168
{
166169
struct wl_display *wlDpy = surface->wlEglDpy->nativeDpy;
170+
EGLint i;
167171

168172
if (surface->ctx.wlStreamResource) {
169173
/* Attach same buffer to indicate new content for the surface is
@@ -191,8 +195,20 @@ wlEglSendDamageEvent(WlEglSurface *surface, struct wl_event_queue *queue)
191195
surface->dy);
192196
}
193197

194-
wl_surface_damage(surface->wlSurface, 0, 0,
195-
surface->width, surface->height);
198+
if (n_rects > 0 &&
199+
(wl_proxy_get_version((struct wl_proxy *)surface->wlSurface) >=
200+
WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION)) {
201+
for (i = 0; i < n_rects; i++) {
202+
wl_surface_damage_buffer(surface->wlSurface,
203+
rects[i*4],
204+
surface->height - rects[i*4+1],
205+
rects[i*4+2],
206+
rects[i*4+3]);
207+
}
208+
} else {
209+
wl_surface_damage(surface->wlSurface, 0, 0, UINT32_MAX, UINT32_MAX);
210+
}
211+
196212
wl_surface_commit(surface->wlSurface);
197213
surface->ctx.isAttached = EGL_TRUE;
198214

@@ -257,7 +273,7 @@ damage_thread(void *args)
257273
data->egl.streamFlush(display->devDpy->eglDisplay,
258274
surface->ctx.eglStream);
259275
}
260-
ok = wlEglSendDamageEvent(surface, queue);
276+
ok = wlEglSendDamageEvent(surface, queue, NULL, 0);
261277
surface->ctx.framesProcessed++;
262278
}
263279

src/wayland-eglswap.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ EGLBoolean wlEglSwapBuffersWithDamageHook(EGLDisplay eglDisplay, EGLSurface eglS
125125
if (surface->ctx.useDamageThread) {
126126
surface->ctx.framesProduced++;
127127
} else {
128-
res = wlEglSendDamageEvent(surface, surface->wlEventQueue);
128+
res = wlEglSendDamageEvent(surface, surface->wlEventQueue, rects, n_rects);
129129
}
130130
}
131131
wlEglCreateFrameSync(surface);
@@ -285,7 +285,7 @@ EGLBoolean wlEglPostPresentExport(WlEglSurface *surface) {
285285
if (surface->ctx.useDamageThread) {
286286
surface->ctx.framesProduced++;
287287
} else {
288-
res = wlEglSendDamageEvent(surface, surface->wlEventQueue);
288+
res = wlEglSendDamageEvent(surface, surface->wlEventQueue, NULL, 0);
289289
}
290290

291291
wlEglCreateFrameSync(surface);

0 commit comments

Comments
 (0)