aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIvan Molodetskikh <yalterz@gmail.com>2025-01-04 15:37:54 +0300
committerIvan Molodetskikh <yalterz@gmail.com>2025-01-04 17:56:13 +0300
commit37771259d930baf8550c2e240815c9ff87928412 (patch)
treec86479f5f44f4db0786c51fc3ca64b6931e427d5 /src
parent4618e4851ccac8b5d6e708ea926a25a1c22a3e27 (diff)
downloadniri-37771259d930baf8550c2e240815c9ff87928412.tar.gz
niri-37771259d930baf8550c2e240815c9ff87928412.tar.bz2
niri-37771259d930baf8550c2e240815c9ff87928412.zip
Fetch monitor name from EDID only once
Reduce spam when it's unavailable. Assume the name cannot change at runtime; before if it changed, bad things would probably happen anyway.
Diffstat (limited to 'src')
-rw-r--r--src/backend/tty.rs113
1 files changed, 62 insertions, 51 deletions
diff --git a/src/backend/tty.rs b/src/backend/tty.rs
index bf94ed12..60dc50ba 100644
--- a/src/backend/tty.rs
+++ b/src/backend/tty.rs
@@ -123,7 +123,7 @@ pub struct OutputDevice {
render_node: DrmNode,
drm_scanner: DrmScanner,
surfaces: HashMap<crtc::Handle, Surface>,
- output_ids: HashMap<crtc::Handle, OutputId>,
+ known_crtcs: HashMap<crtc::Handle, CrtcInfo>,
// SAFETY: drop after all the objects used with them are dropped.
// See https://github.com/Smithay/smithay/issues/1102.
drm: DrmDevice,
@@ -134,6 +134,13 @@ pub struct OutputDevice {
active_leases: Vec<DrmLease>,
}
+// A connected, but not necessarily enabled, crtc.
+#[derive(Debug, Clone)]
+pub struct CrtcInfo {
+ id: OutputId,
+ name: OutputName,
+}
+
impl OutputDevice {
pub fn lease_request(
&self,
@@ -173,6 +180,35 @@ impl OutputDevice {
pub fn remove_lease(&mut self, lease_id: u32) {
self.active_leases.retain(|l| l.id() != lease_id);
}
+
+ pub fn known_crtc_name(
+ &self,
+ crtc: &crtc::Handle,
+ conn: &connector::Info,
+ disable_monitor_names: bool,
+ ) -> OutputName {
+ if disable_monitor_names {
+ let conn_name = format_connector_name(conn);
+ return OutputName {
+ connector: conn_name,
+ make: None,
+ model: None,
+ serial: None,
+ };
+ }
+
+ let Some(info) = self.known_crtcs.get(crtc) else {
+ let conn_name = format_connector_name(conn);
+ error!("crtc for connector {conn_name} missing from known");
+ return OutputName {
+ connector: conn_name,
+ make: None,
+ model: None,
+ serial: None,
+ };
+ };
+ info.name.clone()
+ }
}
#[derive(Debug, Clone, Copy)]
@@ -572,7 +608,7 @@ impl Tty {
gbm,
drm_scanner: DrmScanner::new(),
surfaces: HashMap::new(),
- output_ids: HashMap::new(),
+ known_crtcs: HashMap::new(),
drm_lease_state,
active_leases: Vec::new(),
non_desktop_connectors: HashSet::new(),
@@ -613,16 +649,16 @@ impl Tty {
crtc: Some(crtc),
} => {
let connector_name = format_connector_name(&connector);
- let output_name =
- make_output_name(&device.drm, connector.handle(), connector_name, false);
+ let name = make_output_name(&device.drm, connector.handle(), connector_name);
debug!(
"new connector: {} \"{}\"",
- &output_name.connector,
- output_name.format_make_model_serial(),
+ &name.connector,
+ name.format_make_model_serial(),
);
// Assign an id to this crtc.
- device.output_ids.insert(crtc, OutputId::next());
+ let id = OutputId::next();
+ device.known_crtcs.insert(crtc, CrtcInfo { id, name });
}
DrmScanEvent::Disconnected {
crtc: Some(crtc), ..
@@ -643,7 +679,7 @@ impl Tty {
};
for crtc in removed {
- if device.output_ids.remove(&crtc).is_none() {
+ if device.known_crtcs.remove(&crtc).is_none() {
error!("output ID missing for disconnected crtc: {crtc:?}");
}
}
@@ -739,12 +775,8 @@ impl Tty {
let device = self.devices.get_mut(&node).context("missing device")?;
- let output_name = make_output_name(
- &device.drm,
- connector.handle(),
- connector_name.clone(),
- self.config.borrow().debug.disable_monitor_names,
- );
+ let disable_monitor_names = self.config.borrow().debug.disable_monitor_names;
+ let output_name = device.known_crtc_name(&crtc, &connector, disable_monitor_names);
let non_desktop = find_drm_property(&device.drm, connector.handle(), "non-desktop")
.and_then(|(_, info, value)| info.value_type().convert_value(value).as_boolean())
@@ -1543,17 +1575,13 @@ impl Tty {
let _span = tracy_client::span!("Tty::refresh_ipc_outputs");
let mut ipc_outputs = HashMap::new();
+ let disable_monitor_names = self.config.borrow().debug.disable_monitor_names;
for (node, device) in &self.devices {
for (connector, crtc) in device.drm_scanner.crtcs() {
let connector_name = format_connector_name(connector);
let physical_size = connector.size();
- let output_name = make_output_name(
- &device.drm,
- connector.handle(),
- connector_name.clone(),
- self.config.borrow().debug.disable_monitor_names,
- );
+ let output_name = device.known_crtc_name(&crtc, connector, disable_monitor_names);
let surface = device.surfaces.get(&crtc);
let current_crtc_mode = surface.map(|surface| surface.compositor.pending_mode());
@@ -1609,6 +1637,12 @@ impl Tty {
})
.map(logical_output);
+ let id = device.known_crtcs.get(&crtc).map(|info| info.id);
+ let id = id.unwrap_or_else(|| {
+ error!("crtc for connector {connector_name} missing from known");
+ OutputId::next()
+ });
+
let ipc_output = niri_ipc::Output {
name: connector_name,
make: output_name.make.unwrap_or_else(|| "Unknown".into()),
@@ -1622,10 +1656,6 @@ impl Tty {
logical,
};
- let id = device.output_ids.get(&crtc).copied().unwrap_or_else(|| {
- error!("output ID missing for crtc: {crtc:?}");
- OutputId::next()
- });
ipc_outputs.insert(id, ipc_output);
}
}
@@ -1838,6 +1868,9 @@ impl Tty {
}
}
+ let config = self.config.borrow();
+ let disable_monitor_names = config.debug.disable_monitor_names;
+
for (connector, crtc) in device.drm_scanner.crtcs() {
// Check if connected.
if connector.state() != connector::State::Connected {
@@ -1853,16 +1886,9 @@ impl Tty {
continue;
}
- let connector_name = format_connector_name(connector);
- let output_name = make_output_name(
- &device.drm,
- connector.handle(),
- connector_name,
- self.config.borrow().debug.disable_monitor_names,
- );
- let config = self
- .config
- .borrow()
+ let output_name = device.known_crtc_name(&crtc, connector, disable_monitor_names);
+
+ let config = config
.outputs
.find(&output_name)
.cloned()
@@ -1896,6 +1922,7 @@ impl Tty {
}
pub fn disconnected_connector_name_by_name_match(&self, target: &str) -> Option<OutputName> {
+ let disable_monitor_names = self.config.borrow().debug.disable_monitor_names;
for device in self.devices.values() {
for (connector, crtc) in device.drm_scanner.crtcs() {
// Check if connected.
@@ -1912,13 +1939,7 @@ impl Tty {
continue;
}
- let connector_name = format_connector_name(connector);
- let output_name = make_output_name(
- &device.drm,
- connector.handle(),
- connector_name,
- self.config.borrow().debug.disable_monitor_names,
- );
+ let output_name = device.known_crtc_name(&crtc, connector, disable_monitor_names);
if output_name.matches(target) {
return Some(output_name);
}
@@ -2479,17 +2500,7 @@ fn make_output_name(
device: &DrmDevice,
connector: connector::Handle,
connector_name: String,
- disable_monitor_names: bool,
) -> OutputName {
- if disable_monitor_names {
- return OutputName {
- connector: connector_name,
- make: None,
- model: None,
- serial: None,
- };
- }
-
let info = get_edid_info(device, connector)
.map_err(|err| warn!("error getting EDID info for {connector_name}: {err:?}"))
.ok();