kms: Don't reload outputs for every single event

This commit is contained in:
Victoria Brekenfeld 2025-08-11 16:50:45 +02:00 committed by Victoria Brekenfeld
parent 6897f81984
commit cb2289e7b1
3 changed files with 34 additions and 60 deletions

View file

@ -370,20 +370,8 @@ impl State {
self.common self.common
.output_configuration_state .output_configuration_state
.add_heads(wl_outputs.iter()); .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.backend.kms().refresh_used_devices()?;
self.common.refresh();
Ok(()) Ok(())
} }
@ -469,28 +457,12 @@ impl State {
self.common self.common
.output_configuration_state .output_configuration_state
.add_heads(outputs_added.iter()); .add_heads(outputs_added.iter());
{
self.common.config.read_outputs( for output in outputs_removed {
&mut self.common.output_configuration_state, self.common.remove_output(&output);
&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();
} }
self.backend.kms().refresh_used_devices()?; self.backend.kms().refresh_used_devices()?;
Ok(()) Ok(())
} }
@ -533,29 +505,32 @@ impl State {
self.common self.common
.output_configuration_state .output_configuration_state
.remove_heads(outputs_removed.iter()); .remove_heads(outputs_removed.iter());
backend.refresh_used_devices()?;
if backend.session.is_active() { if backend.session.is_active() {
for output in outputs_removed { for output in outputs_removed {
self.common.remove_output(&output); 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 { } else {
self.common.output_configuration_state.update(); self.common.output_configuration_state.update();
} }
backend.refresh_used_devices()?;
Ok(()) 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 { pub struct OutputChanges {

View file

@ -40,7 +40,7 @@ use smithay::{
}, },
}; };
use surface::GbmDrmOutput; use surface::GbmDrmOutput;
use tracing::{error, info, trace, warn}; use tracing::{debug, error, info, trace, warn};
use std::{ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
@ -141,6 +141,7 @@ pub fn init_backend(
if let Err(err) = state.backend.kms().select_primary_gpu(dh) { if let Err(err) = state.backend.kms().select_primary_gpu(dh) {
warn!("Failed to determine primary gpu: {}", err); warn!("Failed to determine primary gpu: {}", err);
} }
state.refresh_output_config();
// start x11 // start x11
let primary = state.backend.kms().primary_node.read().unwrap().clone(); 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)), .with_context(|| format!("Failed to remove drm device: {}", device_id)),
} { } {
Ok(()) => { Ok(()) => {
trace!("Successfully handled udev event."); debug!("Successfully handled udev event.");
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) { let backend = state.backend.kms();
warn!("Failed to determine a new primary gpu: {}", err); 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) => { Err(err) => {
error!(?err, "Error while handling udev event.") error!(?err, "Error while handling udev event.")
@ -349,16 +355,7 @@ impl State {
} }
// update outputs // update outputs
state.common.config.read_outputs( state.refresh_output_config();
&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.common.refresh(); state.common.refresh();
}); });
loop_signal.wakeup(); loop_signal.wakeup();

View file

@ -29,6 +29,8 @@ pub fn init(evlh: &LoopHandle<'static, State>) -> Result<Vec<RegistrationToken>>
tracing::error!(?err, "Failed to update drm device {}.", node); tracing::error!(?err, "Failed to update drm device {}.", node);
} }
} }
state.refresh_output_config();
() ()
} }
calloop::channel::Event::Closed => (), calloop::channel::Event::Closed => (),