mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-23 02:05:33 +07:00
tty: Make sure to cleanup all CRTCs except used ones
Apparently a CRTC can be active and use bandwidth even without any connectors on it.
This commit is contained in:
+13
-42
@@ -228,47 +228,31 @@ impl OutputDevice {
|
|||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let _span = tracy_client::span!("OutputDevice::cleanup_disconnected_resources");
|
let _span = tracy_client::span!("OutputDevice::cleanup_disconnected_resources");
|
||||||
|
|
||||||
let mut req = AtomicModeReq::new();
|
let res_handles = self
|
||||||
|
.drm
|
||||||
|
.resource_handles()
|
||||||
|
.context("error getting plane handles")?;
|
||||||
let plane_handles = self
|
let plane_handles = self
|
||||||
.drm
|
.drm
|
||||||
.plane_handles()
|
.plane_handles()
|
||||||
.context("error getting plane handles")?;
|
.context("error getting plane handles")?;
|
||||||
|
|
||||||
let mut cleanup = HashSet::new();
|
let mut req = AtomicModeReq::new();
|
||||||
let mut should_be_off_conn = HashSet::new();
|
|
||||||
|
// We want to disable all CRTCs that do not correspond to a connector we're using.
|
||||||
|
let mut cleanup = HashSet::<crtc::Handle>::new();
|
||||||
|
cleanup.extend(res_handles.crtcs());
|
||||||
|
|
||||||
for (conn, info) in self.drm_scanner.connectors() {
|
for (conn, info) in self.drm_scanner.connectors() {
|
||||||
let Some(enc) = info.current_encoder() else {
|
// We only keep the connector if it has a CRTC and the output isn't off in niri.
|
||||||
// Not enabled.
|
if let Some(crtc) = self.drm_scanner.crtc_for_connector(conn) {
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
let enc = match self.drm.get_encoder(enc) {
|
|
||||||
Ok(x) => x,
|
|
||||||
Err(err) => {
|
|
||||||
debug!("couldn't get encoder: {err:?}");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let Some(crtc) = enc.crtc() else {
|
|
||||||
// Encoder has no CRTC?
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
// All Connected connectors are returned by the DrmScanner and will be attempted for
|
|
||||||
// connection.
|
|
||||||
if info.state() == connector::State::Connected {
|
|
||||||
// But we also need to clear the connectors that should be off according to our
|
|
||||||
// config, since those ones will not be cleared elsewhere.
|
|
||||||
if !should_be_off(crtc, info) {
|
if !should_be_off(crtc, info) {
|
||||||
|
// Keep the corresponding CRTC.
|
||||||
|
cleanup.remove(&crtc);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
should_be_off_conn.insert(conn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup.insert(crtc);
|
|
||||||
|
|
||||||
// Clear the connector.
|
// Clear the connector.
|
||||||
let Some((crtc_id, _, _)) = find_drm_property(&self.drm, *conn, "CRTC_ID") else {
|
let Some((crtc_id, _, _)) = find_drm_property(&self.drm, *conn, "CRTC_ID") else {
|
||||||
debug!("couldn't find connector CRTC_ID property");
|
debug!("couldn't find connector CRTC_ID property");
|
||||||
@@ -278,25 +262,12 @@ impl OutputDevice {
|
|||||||
req.add_property(*conn, crtc_id, property::Value::CRTC(None));
|
req.add_property(*conn, crtc_id, property::Value::CRTC(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't cleanup CRTCs that also correspond to some connected connectors.
|
|
||||||
for (conn, crtc) in self.drm_scanner.crtcs() {
|
|
||||||
// If the connector is enabled, but we're about to disable it, then it will be present
|
|
||||||
// in the DrmScanner; keep it in the cleanup list.
|
|
||||||
if should_be_off_conn.contains(&conn.handle()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup.remove(&crtc);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Legacy fallback.
|
// Legacy fallback.
|
||||||
if !self.drm.is_atomic() {
|
if !self.drm.is_atomic() {
|
||||||
if let Ok(res_handles) = self.drm.resource_handles() {
|
|
||||||
for crtc in res_handles.crtcs() {
|
for crtc in res_handles.crtcs() {
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
let _ = self.drm.set_cursor(*crtc, Option::<&DumbBuffer>::None);
|
let _ = self.drm.set_cursor(*crtc, Option::<&DumbBuffer>::None);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
for crtc in cleanup {
|
for crtc in cleanup {
|
||||||
let _ = self.drm.set_crtc(crtc, None, (0, 0), &[], None);
|
let _ = self.drm.set_crtc(crtc, None, (0, 0), &[], None);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user