kms: Fix inconsistent selection of primary GPU

Instead of choosing a primary GPU the first time `device_added` is
called (and then not updating it on the next call, even if that should
be the primary GPU), set the primary GPU only after all devices have
been initially added, and on future changes.

Alternately, the `was_empty` test can just be removed, but it's probably
best not to select the primary GPU multiple times each time the
compositor starts on a multi-GPU system.

Fixes https://github.com/pop-os/cosmic-comp/issues/1437.
This commit is contained in:
Ian Douglas Scott 2025-05-30 21:08:04 -07:00 committed by Victoria Brekenfeld
parent 087ebaa2c7
commit 619e994955
2 changed files with 24 additions and 16 deletions

View file

@ -46,7 +46,7 @@ use std::{
cell::RefCell,
collections::{HashMap, HashSet},
fmt,
path::{Path, PathBuf},
path::Path,
sync::{atomic::AtomicBool, mpsc::Receiver, Arc, RwLock},
time::Duration,
};
@ -144,7 +144,7 @@ pub fn init_egl(gbm: &GbmDevice<DrmDeviceFd>) -> Result<EGLInternals> {
}
impl State {
pub fn device_added(&mut self, dev: dev_t, path: PathBuf, dh: &DisplayHandle) -> Result<()> {
pub fn device_added(&mut self, dev: dev_t, path: &Path, dh: &DisplayHandle) -> Result<()> {
if !self.backend.kms().session.is_active() {
return Ok(());
}
@ -337,13 +337,7 @@ impl State {
// TODO atomic commit all surfaces together and drop surfaces, if it fails due to bandwidth
let kms = self.backend.kms();
let was_empty = kms.drm_devices.is_empty();
kms.drm_devices.insert(drm_node, device);
if was_empty {
if let Err(err) = kms.select_primary_gpu(dh) {
warn!("Failed to determine a new primary gpu: {}", err);
}
}
}
self.common
@ -497,12 +491,11 @@ impl State {
dh.remove_global::<State>(socket.drm_global);
}
backend.api.as_mut().remove_node(&device.render_node);
let was_primary = *backend.primary_node.read().unwrap() == Some(device.render_node);
if was_primary {
if let Err(err) = backend.select_primary_gpu(dh) {
warn!("Failed to determine a new primary gpu: {}", err);
}
}
backend
.primary_node
.write()
.unwrap()
.take_if(|node| node == &device.render_node);
}
self.common
.output_configuration_state