From e5fc8cd4c734717c471567de98a77e2482a7015f Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Mon, 14 Aug 2023 19:39:33 +0200 Subject: [PATCH] output: trigger frame/present events on all commits on enabled output Up until now, frame/present events were only triggered when the user submitted a buffer. Change the wlr_output API so that these events are triggered when any commit is applied on an enabled output. Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3708 --- backend/drm/drm.c | 7 ++----- backend/headless/output.c | 3 ++- backend/wayland/output.c | 3 ++- backend/x11/output.c | 5 +++++ include/types/wlr_output.h | 2 ++ include/wlr/types/wlr_output.h | 3 ++- types/output/output.c | 10 +++++++++- 7 files changed, 24 insertions(+), 9 deletions(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index 85240448..a012e678 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -715,12 +715,10 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn, } } - uint32_t flags = 0; if (pending.base->committed & WLR_OUTPUT_STATE_BUFFER) { if (!drm_connector_state_update_primary_fb(conn, &pending)) { goto out; } - flags |= DRM_MODE_PAGE_FLIP_EVENT; // wlr_drm_interface.crtc_commit will perform either a non-blocking // page-flip, either a blocking modeset. When performing a blocking modeset @@ -732,9 +730,6 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn, goto out; } } - if (pending.modeset && pending.active) { - flags |= DRM_MODE_PAGE_FLIP_EVENT; - } if (pending.base->committed & WLR_OUTPUT_STATE_LAYERS) { if (!drm_connector_set_pending_layer_fbs(conn, pending.base)) { return false; @@ -751,6 +746,8 @@ bool drm_connector_commit_state(struct wlr_drm_connector *conn, } } + uint32_t flags = pending.active ? DRM_MODE_PAGE_FLIP_EVENT : 0; + ok = drm_crtc_commit(conn, &pending, flags, false); if (!ok) { goto out; diff --git a/backend/headless/output.c b/backend/headless/output.c index 7dc7f0bc..f4719a3c 100644 --- a/backend/headless/output.c +++ b/backend/headless/output.c @@ -5,6 +5,7 @@ #include #include #include "backend/headless.h" +#include "types/wlr_output.h" static const uint32_t SUPPORTED_OUTPUT_STATE = WLR_OUTPUT_STATE_BACKEND_OPTIONAL | @@ -65,7 +66,7 @@ static bool output_commit(struct wlr_output *wlr_output, output_update_refresh(output, state->custom_mode.refresh); } - if (state->committed & WLR_OUTPUT_STATE_BUFFER) { + if (output_pending_enabled(wlr_output, state)) { struct wlr_output_event_present present_event = { .commit_seq = wlr_output->commit_seq + 1, .presented = true, diff --git a/backend/wayland/output.c b/backend/wayland/output.c index 7854d476..e51be4c5 100644 --- a/backend/wayland/output.c +++ b/backend/wayland/output.c @@ -19,6 +19,7 @@ #include "backend/wayland.h" #include "render/pixel_format.h" #include "render/wlr_renderer.h" +#include "types/wlr_output.h" #include "linux-dmabuf-unstable-v1-client-protocol.h" #include "presentation-time-client-protocol.h" @@ -555,7 +556,7 @@ static bool output_commit(struct wlr_output *wlr_output, return false; } - if (state->committed & (WLR_OUTPUT_STATE_BUFFER | WLR_OUTPUT_STATE_LAYERS)) { + if (output_pending_enabled(wlr_output, state)) { if (output->frame_callback != NULL) { wl_callback_destroy(output->frame_callback); } diff --git a/backend/x11/output.c b/backend/x11/output.c index d95f0767..553f56a8 100644 --- a/backend/x11/output.c +++ b/backend/x11/output.c @@ -22,6 +22,7 @@ #include "backend/x11.h" #include "util/time.h" +#include "types/wlr_output.h" static const uint32_t SUPPORTED_OUTPUT_STATE = WLR_OUTPUT_STATE_BACKEND_OPTIONAL | @@ -375,6 +376,10 @@ static bool output_commit(struct wlr_output *wlr_output, if (!output_commit_buffer(output, state)) { return false; } + } else if (output_pending_enabled(wlr_output, state)) { + uint32_t serial = output->wlr_output.commit_seq; + uint64_t target_msc = output->last_msc ? output->last_msc + 1 : 0; + xcb_present_notify_msc(x11->xcb, output->win, serial, target_msc, 0, 0); } xcb_flush(x11->xcb); diff --git a/include/types/wlr_output.h b/include/types/wlr_output.h index 1fbe3949..b885fd08 100644 --- a/include/types/wlr_output.h +++ b/include/types/wlr_output.h @@ -6,6 +6,8 @@ void output_pending_resolution(struct wlr_output *output, const struct wlr_output_state *state, int *width, int *height); +bool output_pending_enabled(struct wlr_output *output, + const struct wlr_output_state *state); bool output_pick_format(struct wlr_output *output, const struct wlr_drm_format_set *display_formats, diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index a71bf9ca..30331fba 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -170,7 +170,8 @@ struct wlr_output { struct wl_signal precommit; // struct wlr_output_event_precommit // Emitted right after commit struct wl_signal commit; // struct wlr_output_event_commit - // Emitted right after the buffer has been presented to the user + // Emitted right after a commit has been presented to the user for + // enabled outputs struct wl_signal present; // struct wlr_output_event_present // Emitted after a client bound the wl_output global struct wl_signal bind; // struct wlr_output_event_bind diff --git a/types/output/output.c b/types/output/output.c index 931b152c..036fa469 100644 --- a/types/output/output.c +++ b/types/output/output.c @@ -319,7 +319,7 @@ static void output_apply_state(struct wlr_output *output, output->cursor_swapchain = NULL; } - if (state->committed & WLR_OUTPUT_STATE_BUFFER) { + if (output_pending_enabled(output, state)) { output->frame_pending = true; output->needs_frame = false; } @@ -592,6 +592,14 @@ void output_pending_resolution(struct wlr_output *output, } } +bool output_pending_enabled(struct wlr_output *output, + const struct wlr_output_state *state) { + if (state->committed & WLR_OUTPUT_STATE_ENABLED) { + return state->enabled; + } + return output->enabled; +} + /** * Compare a struct wlr_output_state with the current state of a struct * wlr_output.