backend/wayland: allow superseding a previous commit

During a modeset, the core wlr_output logic will allocate a buffer
with a new size and commit it. However if we still have a frame
callback pending we'd refuse to perform the commit. This is
inconsistent with the DRM backend, which performs a blocking
modeset.

This is visible when resizing the Wayland toplevel. The logs are
filled with "Skipping buffer swap", and the wlr_damage_ring's
bounds are not properly updated.

Fix this by destroying the pending frame wl_callback.
This commit is contained in:
Simon Ser 2023-01-30 14:20:36 +01:00
parent 92eedb84c1
commit 2e49fa1a0a

View file

@ -43,7 +43,12 @@ static struct wlr_wl_output *get_wl_output_from_output(
static void surface_frame_callback(void *data, struct wl_callback *cb, static void surface_frame_callback(void *data, struct wl_callback *cb,
uint32_t time) { uint32_t time) {
struct wlr_wl_output *output = data; struct wlr_wl_output *output = data;
assert(output);
if (cb == NULL) {
return;
}
assert(output->frame_callback == cb);
wl_callback_destroy(cb); wl_callback_destroy(cb);
output->frame_callback = NULL; output->frame_callback = NULL;
@ -300,10 +305,8 @@ static bool output_commit(struct wlr_output *wlr_output,
} }
if (output->frame_callback != NULL) { if (output->frame_callback != NULL) {
wlr_log(WLR_ERROR, "Skipping buffer swap"); wl_callback_destroy(output->frame_callback);
return false;
} }
output->frame_callback = wl_surface_frame(output->surface); output->frame_callback = wl_surface_frame(output->surface);
wl_callback_add_listener(output->frame_callback, &frame_listener, output); wl_callback_add_listener(output->frame_callback, &frame_listener, output);