From c2093fab998d37e8532c12c40da9d39ef939a98b Mon Sep 17 00:00:00 2001
From: Frank Praznik <[EMAIL REDACTED]>
Date: Fri, 8 Apr 2022 13:58:45 -0400
Subject: [PATCH] video: wayland: Set the surface damage region when using
fullscreen viewports
When using emulated display modes, the output size is often larger than the drawable buffer. As the surface damage region is automatically calculated from the smaller drawable buffer size, the damage region needs to be manually set to cover the entire viewport region or visual repaint artifacts can result.
---
src/video/wayland/SDL_waylandwindow.c | 12 ++++++++++++
src/video/wayland/SDL_waylandwindow.h | 1 +
2 files changed, 13 insertions(+)
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index 89b93b7a3e3..2841e49a344 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -241,6 +241,11 @@ ConfigureViewport(SDL_Window *window)
GetFullScreenDimensions(window, &fs_width, &fs_height, &src_width, &src_height);
SetViewport(window, src_width, src_height, output->width, output->height);
+ data->damage_region.x = 0;
+ data->damage_region.y = 0;
+ data->damage_region.w = output->width;
+ data->damage_region.h = output->height;
+
data->pointer_scale_x = (float)fs_width / (float)output->width;
data->pointer_scale_y = (float)fs_height / (float)output->height;
} else {
@@ -253,6 +258,8 @@ ConfigureViewport(SDL_Window *window)
UnsetViewport(window);
}
+ SDL_zero(data->damage_region);
+
data->pointer_scale_x = 1.0f;
data->pointer_scale_y = 1.0f;
}
@@ -400,6 +407,11 @@ handle_surface_frame_done(void *data, struct wl_callback *cb, uint32_t time)
SDL_WindowData *wind = (SDL_WindowData *) data;
SDL_AtomicSet(&wind->swap_interval_ready, 1); /* mark window as ready to present again. */
+ if (!SDL_RectEmpty(&wind->damage_region)) {
+ wl_surface_damage(wind->surface, wind->damage_region.x, wind->damage_region.y,
+ wind->damage_region.w, wind->damage_region.h);
+ }
+
/* reset this callback to fire again once a new frame was presented and compositor wants the next one. */
wind->frame_callback = wl_surface_frame(wind->frame_surface_wrapper);
wl_callback_destroy(cb);
diff --git a/src/video/wayland/SDL_waylandwindow.h b/src/video/wayland/SDL_waylandwindow.h
index 6b0e2d9e3b5..97ae5ec8a20 100644
--- a/src/video/wayland/SDL_waylandwindow.h
+++ b/src/video/wayland/SDL_waylandwindow.h
@@ -90,6 +90,7 @@ typedef struct {
float pointer_scale_x;
float pointer_scale_y;
int drawable_width, drawable_height;
+ SDL_Rect damage_region;
SDL_bool needs_resize_event;
SDL_bool floating_resize_pending;
} SDL_WindowData;