From cb2289e7b1147cd0c4cff3a70352c89bd3848e6c Mon Sep 17 00:00:00 2001 From: Victoria Brekenfeld Date: Mon, 11 Aug 2025 16:50:45 +0200 Subject: [PATCH] kms: Don't reload outputs for every single event --- src/backend/kms/device.rs | 61 ++++++++++++--------------------------- src/backend/kms/mod.rs | 31 +++++++++----------- src/dbus/mod.rs | 2 ++ 3 files changed, 34 insertions(+), 60 deletions(-) diff --git a/src/backend/kms/device.rs b/src/backend/kms/device.rs index fa55a569..7c57aca7 100644 --- a/src/backend/kms/device.rs +++ b/src/backend/kms/device.rs @@ -370,20 +370,8 @@ impl State { self.common .output_configuration_state .add_heads(wl_outputs.iter()); - self.common.config.read_outputs( - &mut self.common.output_configuration_state, - &mut self.backend, - &self.common.shell, - &self.common.event_loop_handle, - &mut self.common.workspace_state.update(), - &self.common.xdg_activation_state, - self.common.startup_done.clone(), - &self.common.clock, - ); self.backend.kms().refresh_used_devices()?; - self.common.refresh(); - Ok(()) } @@ -469,28 +457,12 @@ impl State { self.common .output_configuration_state .add_heads(outputs_added.iter()); - { - self.common.config.read_outputs( - &mut self.common.output_configuration_state, - &mut self.backend, - &self.common.shell, - &self.common.event_loop_handle, - &mut self.common.workspace_state.update(), - &self.common.xdg_activation_state, - self.common.startup_done.clone(), - &self.common.clock, - ); - // Don't remove the outputs, before potentially new ones have been initialized. - // reading a new config means outputs might become enabled, that were previously disabled. - // This gives the shell more information on how to move outputs. - for output in outputs_removed { - self.common.remove_output(&output); - } - self.common.refresh(); + + for output in outputs_removed { + self.common.remove_output(&output); } self.backend.kms().refresh_used_devices()?; - Ok(()) } @@ -533,29 +505,32 @@ impl State { self.common .output_configuration_state .remove_heads(outputs_removed.iter()); - backend.refresh_used_devices()?; if backend.session.is_active() { for output in outputs_removed { self.common.remove_output(&output); } - self.common.config.read_outputs( - &mut self.common.output_configuration_state, - &mut self.backend, - &self.common.shell, - &self.common.event_loop_handle, - &mut self.common.workspace_state.update(), - &self.common.xdg_activation_state, - self.common.startup_done.clone(), - &self.common.clock, - ); - self.common.refresh(); } else { self.common.output_configuration_state.update(); } + backend.refresh_used_devices()?; Ok(()) } + + pub fn refresh_output_config(&mut self) { + self.common.config.read_outputs( + &mut self.common.output_configuration_state, + &mut self.backend, + &self.common.shell, + &self.common.event_loop_handle, + &mut self.common.workspace_state.update(), + &self.common.xdg_activation_state, + self.common.startup_done.clone(), + &self.common.clock, + ); + self.common.refresh(); + } } pub struct OutputChanges { diff --git a/src/backend/kms/mod.rs b/src/backend/kms/mod.rs index 47bd40c2..fce6088f 100644 --- a/src/backend/kms/mod.rs +++ b/src/backend/kms/mod.rs @@ -40,7 +40,7 @@ use smithay::{ }, }; use surface::GbmDrmOutput; -use tracing::{error, info, trace, warn}; +use tracing::{debug, error, info, trace, warn}; use std::{ collections::{HashMap, HashSet}, @@ -141,6 +141,7 @@ pub fn init_backend( if let Err(err) = state.backend.kms().select_primary_gpu(dh) { warn!("Failed to determine primary gpu: {}", err); } + state.refresh_output_config(); // start x11 let primary = state.backend.kms().primary_node.read().unwrap().clone(); @@ -278,15 +279,20 @@ fn init_udev( .with_context(|| format!("Failed to remove drm device: {}", device_id)), } { Ok(()) => { - trace!("Successfully handled udev event."); - let backend = state.backend.kms(); - if matches!(event, UdevEvent::Added { .. } | UdevEvent::Removed { .. }) - && backend.primary_node.read().unwrap().is_none() + debug!("Successfully handled udev event."); + { - if let Err(err) = state.backend.kms().select_primary_gpu(&dh) { - warn!("Failed to determine a new primary gpu: {}", err); + let backend = state.backend.kms(); + if matches!(event, UdevEvent::Added { .. } | UdevEvent::Removed { .. }) + && backend.primary_node.read().unwrap().is_none() + { + if let Err(err) = state.backend.kms().select_primary_gpu(&dh) { + warn!("Failed to determine a new primary gpu: {}", err); + } } } + + state.refresh_output_config(); } Err(err) => { error!(?err, "Error while handling udev event.") @@ -349,16 +355,7 @@ impl State { } // update outputs - state.common.config.read_outputs( - &mut state.common.output_configuration_state, - &mut state.backend, - &state.common.shell, - &state.common.event_loop_handle, - &mut state.common.workspace_state.update(), - &state.common.xdg_activation_state, - state.common.startup_done.clone(), - &state.common.clock, - ); + state.refresh_output_config(); state.common.refresh(); }); loop_signal.wakeup(); diff --git a/src/dbus/mod.rs b/src/dbus/mod.rs index 3381eb5a..309bece0 100644 --- a/src/dbus/mod.rs +++ b/src/dbus/mod.rs @@ -29,6 +29,8 @@ pub fn init(evlh: &LoopHandle<'static, State>) -> Result> tracing::error!(?err, "Failed to update drm device {}.", node); } } + state.refresh_output_config(); + () } calloop::channel::Event::Closed => (),