From c9c2d7539c69c8bf349a5b633ab61ce2d7c20e8a Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Tue, 6 Apr 2021 16:57:42 +0200 Subject: [PATCH] backend/drm: fill scratch wlr_output_state for set_mode Populate the wlr_output_state when setting a mode. This will allow drm_connector_set_mode to stop relying on ephemeral fields in wlr_drm_crtc. Also drm_connector_set_mode will be able to apply both a new buffer and a new mode atomically. --- backend/drm/backend.c | 13 +++++++++---- backend/drm/drm.c | 17 ++++++++++++++--- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/backend/drm/backend.c b/backend/drm/backend.c index 53178b2d..5ec709a5 100644 --- a/backend/drm/backend.c +++ b/backend/drm/backend.c @@ -118,12 +118,17 @@ static void handle_session_active(struct wl_listener *listener, void *data) { struct wlr_drm_connector *conn; wl_list_for_each(conn, &drm->outputs, link) { - struct wlr_output_state state = {0}; + struct wlr_output_mode *mode = NULL; if (conn->output.enabled && conn->output.current_mode != NULL) { - drm_connector_set_mode(conn, &state, conn->output.current_mode); - } else { - drm_connector_set_mode(conn, &state, NULL); + mode = conn->output.current_mode; } + struct wlr_output_state state = { + .committed = WLR_OUTPUT_STATE_MODE | WLR_OUTPUT_STATE_ENABLED, + .enabled = mode != NULL, + .mode_type = WLR_OUTPUT_STATE_MODE_FIXED, + .mode = mode, + }; + drm_connector_set_mode(conn, &state, mode); } } else { wlr_log(WLR_INFO, "DRM fd paused"); diff --git a/backend/drm/drm.c b/backend/drm/drm.c index a44506f2..e2a78de8 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -735,7 +735,12 @@ static void attempt_enable_needs_modeset(struct wlr_drm_backend *drm) { conn->desired_enabled) { wlr_drm_conn_log(conn, WLR_DEBUG, "Output has a desired mode and a CRTC, attempting a modeset"); - struct wlr_output_state state = {0}; + struct wlr_output_state state = { + .committed = WLR_OUTPUT_STATE_MODE | WLR_OUTPUT_STATE_ENABLED, + .enabled = true, + .mode_type = WLR_OUTPUT_STATE_MODE_FIXED, + .mode = conn->desired_mode, + }; drm_connector_set_mode(conn, &state, conn->desired_mode); } } @@ -1056,7 +1061,10 @@ static void dealloc_crtc(struct wlr_drm_connector *conn) { conn->crtc->pending_modeset = true; conn->crtc->pending.active = false; - struct wlr_output_state state = {0}; + struct wlr_output_state state = { + .committed = WLR_OUTPUT_STATE_ENABLED, + .enabled = false, + }; if (!drm_crtc_commit(conn, &state, 0)) { // On GPU unplug, disabling the CRTC can fail with EPERM wlr_drm_conn_log(conn, WLR_ERROR, "Failed to disable CRTC %"PRIu32, @@ -1185,7 +1193,10 @@ static void realloc_crtcs(struct wlr_drm_backend *drm) { struct wlr_drm_mode *mode = (struct wlr_drm_mode *)conn->output.current_mode; - struct wlr_output_state state = {0}; + struct wlr_output_state state = { + .committed = WLR_OUTPUT_STATE_ENABLED, + .enabled = true, + }; if (!drm_connector_init_renderer(conn, &state, mode)) { wlr_drm_conn_log(conn, WLR_ERROR, "Failed to initialize renderer"); wlr_output_update_enabled(&conn->output, false);