diff --git a/src/backend/drm/legacy/mod.rs b/src/backend/drm/legacy/mod.rs index a291bd2..df5a5cd 100644 --- a/src/backend/drm/legacy/mod.rs +++ b/src/backend/drm/legacy/mod.rs @@ -235,7 +235,7 @@ impl Device for LegacyDrmDevice { // Now try to do the least possible amount of changes to set this to the state the users requested // TODO! - + let state = State { mode, connectors }; let backend = Rc::new(LegacyDrmSurfaceInternal { dev: self.dev.clone(), diff --git a/src/backend/drm/legacy/surface.rs b/src/backend/drm/legacy/surface.rs index fd9258e..0fd87de 100644 --- a/src/backend/drm/legacy/surface.rs +++ b/src/backend/drm/legacy/surface.rs @@ -118,15 +118,16 @@ impl Surface for LegacyDrmSurfaceInternal { self.pending.write().unwrap().connectors.remove(&connector); Ok(()) } - + fn set_connectors(&self, connectors: &[connector::Handle]) -> Result<(), Self::Error> { let mut pending = self.pending.write().unwrap(); - + if connectors .iter() .map(|conn| self.check_connector(*conn, pending.mode.as_ref().unwrap())) .collect::, _>>()? - .iter().all(|v| *v) + .iter() + .all(|v| *v) { pending.connectors = connectors.into_iter().cloned().collect(); } @@ -175,12 +176,27 @@ impl RawSurface for LegacyDrmSurfaceInternal { let removed = current.connectors.difference(&pending.connectors); let added = pending.connectors.difference(¤t.connectors); + let mut conn_removed = false; for conn in removed { if let Ok(info) = self.get_connector(*conn) { info!(self.logger, "Removing connector: {:?}", info.interface()); } else { info!(self.logger, "Removing unknown connector"); } + // if the connector was mapped to our crtc, we need to ack the disconnect. + // the graphics pipeline will not be freed otherwise + conn_removed = true; + } + + if conn_removed { + // We need to do a null commit to free graphics pipelines + self.set_crtc(self.crtc, None, (0, 0), &[], None) + .compat() + .map_err(|source| Error::Access { + errmsg: "Error setting crtc", + dev: self.dev_path(), + source, + })?; } for conn in added {