From 8e8b9a72173727f125af227aaf671c38f7640db3 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 21 Sep 2022 16:16:53 +0200 Subject: [PATCH] output: fix back buffer checks The back buffer is no longer set at commit time since 0556aa0c5918 ("output: rejigger attach/clear for back buffer"). Instead, check whether the buffer belongs to the output swapchain. This is more robust. Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3496 --- include/types/wlr_output.h | 2 ++ types/output/output.c | 2 +- types/output/render.c | 15 +++++++++++++++ types/wlr_output_damage.c | 4 +++- 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/include/types/wlr_output.h b/include/types/wlr_output.h index 5f0cbe33..082df5e3 100644 --- a/include/types/wlr_output.h +++ b/include/types/wlr_output.h @@ -8,6 +8,8 @@ void output_pending_resolution(struct wlr_output *output, const struct wlr_output_state *state, int *width, int *height); void output_state_attach_buffer(struct wlr_output_state *state, struct wlr_buffer *buffer); +bool output_is_direct_scanout(struct wlr_output *output, + struct wlr_buffer *buffer); struct wlr_drm_format *output_pick_format(struct wlr_output *output, const struct wlr_drm_format_set *display_formats, uint32_t format); diff --git a/types/output/output.c b/types/output/output.c index 14c7844a..51a316c2 100644 --- a/types/output/output.c +++ b/types/output/output.c @@ -575,7 +575,7 @@ static bool output_basic_test(struct wlr_output *output, return false; } - if (output->back_buffer == NULL) { + if (output_is_direct_scanout(output, state->buffer)) { if (output->attach_render_locks > 0) { wlr_log(WLR_DEBUG, "Direct scan-out disabled by lock"); return false; diff --git a/types/output/render.c b/types/output/render.c index b36c145e..10203c48 100644 --- a/types/output/render.c +++ b/types/output/render.c @@ -329,3 +329,18 @@ uint32_t wlr_output_preferred_read_format(struct wlr_output *output) { return fmt; } + +bool output_is_direct_scanout(struct wlr_output *output, + struct wlr_buffer *buffer) { + if (output->swapchain == NULL) { + return true; + } + + for (size_t i = 0; i < WLR_SWAPCHAIN_CAP; i++) { + if (output->swapchain->slots[i].buffer == buffer) { + return false; + } + } + + return true; +} diff --git a/types/wlr_output_damage.c b/types/wlr_output_damage.c index 8254f65e..fea5a93d 100644 --- a/types/wlr_output_damage.c +++ b/types/wlr_output_damage.c @@ -5,6 +5,7 @@ #include #include #include +#include "types/wlr_output.h" static void output_handle_destroy(struct wl_listener *listener, void *data) { struct wlr_output_damage *output_damage = @@ -53,7 +54,8 @@ static void output_handle_precommit(struct wl_listener *listener, void *data) { if (state->committed & WLR_OUTPUT_STATE_BUFFER) { // TODO: find a better way to access this info without a precommit // handler - output_damage->pending_attach_render = output->back_buffer != NULL; + output_damage->pending_attach_render = + output_is_direct_scanout(output, state->buffer); } }