1
0
Fork 0
forked from wry/wry

metal: re-process unprocessed device changes after resume

This commit is contained in:
Julian Orth 2022-05-20 18:16:46 +02:00
parent 73671c6c58
commit ebe5d4c3e0

View file

@ -103,6 +103,7 @@ pub struct MetalDrmDeviceData {
pub dev: Rc<MetalDrmDevice>, pub dev: Rc<MetalDrmDevice>,
pub connectors: CopyHashMap<DrmConnector, Rc<MetalConnector>>, pub connectors: CopyHashMap<DrmConnector, Rc<MetalConnector>>,
pub futures: CopyHashMap<DrmConnector, ConnectorFutures>, pub futures: CopyHashMap<DrmConnector, ConnectorFutures>,
pub unprocessed_change: Cell<bool>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -758,17 +759,22 @@ impl MetalBackend {
} }
pub fn handle_drm_change(self: &Rc<Self>, dev: UdevDevice) -> Option<()> { pub fn handle_drm_change(self: &Rc<Self>, dev: UdevDevice) -> Option<()> {
if let Err(e) = self.handle_drm_change_(dev) { let dev = match self.device_holder.drm_devices.get(&dev.devnum()) {
Some(dev) => dev,
_ => return None,
};
if let Err(e) = self.handle_drm_change_(&dev, true) {
dev.unprocessed_change.set(true);
log::error!("Could not handle change of drm device: {}", ErrorFmt(e)); log::error!("Could not handle change of drm device: {}", ErrorFmt(e));
} }
None None
} }
fn handle_drm_change_(self: &Rc<Self>, dev: UdevDevice) -> Result<(), MetalError> { fn handle_drm_change_(
let dev = match self.device_holder.drm_devices.get(&dev.devnum()) { self: &Rc<Self>,
Some(dev) => dev, dev: &Rc<MetalDrmDeviceData>,
_ => return Ok(()), preserve_any: bool,
}; ) -> Result<(), MetalError> {
if let Err(e) = self.update_device_properties(&dev) { if let Err(e) = self.update_device_properties(&dev) {
return Err(MetalError::UpdateProperties(e)); return Err(MetalError::UpdateProperties(e));
} }
@ -814,7 +820,7 @@ impl MetalBackend {
c.send_event(ConnectorEvent::Disconnected); c.send_event(ConnectorEvent::Disconnected);
c.connect_sent.set(false); c.connect_sent.set(false);
c.can_present.set(true); c.can_present.set(true);
} else { } else if preserve_any {
preserve.connectors.insert(c.id); preserve.connectors.insert(c.id);
} }
} }
@ -843,6 +849,7 @@ impl MetalBackend {
self.start_connector(connector, &dd); self.start_connector(connector, &dd);
} }
} }
dev.unprocessed_change.set(false);
Ok(()) Ok(())
} }
@ -944,6 +951,7 @@ impl MetalBackend {
dev: dev.clone(), dev: dev.clone(),
connectors, connectors,
futures, futures,
unprocessed_change: Cell::new(false),
}); });
self.init_drm_device(&slf, &mut preserve)?; self.init_drm_device(&slf, &mut preserve)?;
@ -1005,6 +1013,13 @@ impl MetalBackend {
self: &Rc<Self>, self: &Rc<Self>,
dev: &Rc<MetalDrmDeviceData>, dev: &Rc<MetalDrmDeviceData>,
) -> Result<(), MetalError> { ) -> Result<(), MetalError> {
for connector in dev.connectors.lock().values() {
connector.can_present.set(true);
connector.has_damage.set(true);
}
if dev.unprocessed_change.get() {
return self.handle_drm_change_(dev, false);
}
if let Err(e) = self.update_device_properties(dev) { if let Err(e) = self.update_device_properties(dev) {
return Err(MetalError::UpdateProperties(e)); return Err(MetalError::UpdateProperties(e));
} }
@ -1012,8 +1027,6 @@ impl MetalBackend {
self.init_drm_device(dev, &mut preserve)?; self.init_drm_device(dev, &mut preserve)?;
for connector in dev.connectors.lock().values() { for connector in dev.connectors.lock().values() {
if connector.primary_plane.get().is_some() { if connector.primary_plane.get().is_some() {
connector.can_present.set(true);
connector.has_damage.set(true);
connector.schedule_present(); connector.schedule_present();
} }
} }
@ -1382,16 +1395,13 @@ impl MetalBackend {
if dd.connection != ConnectorStatus::Connected { if dd.connection != ConnectorStatus::Connected {
return Ok(()); return Ok(());
} }
let crtc = match connector.crtc.get() { let crtc = 'crtc: {
Some(c) => c, for crtc in dd.crtcs.values() {
_ => 'crtc: { if crtc.connector.get().is_none() {
for crtc in dd.crtcs.values() { break 'crtc crtc.clone();
if crtc.connector.get().is_none() {
break 'crtc crtc.clone();
}
} }
return Err(MetalError::NoCrtcForConnector);
} }
return Err(MetalError::NoCrtcForConnector);
}; };
let mode = match &dd.mode { let mode = match &dd.mode {
Some(m) => m, Some(m) => m,
@ -1433,19 +1443,16 @@ impl MetalBackend {
return Ok(()); return Ok(());
} }
}; };
let primary_plane = match connector.primary_plane.get() { let primary_plane = 'primary_plane: {
Some(p) => p, for plane in crtc.possible_planes.values() {
_ => 'primary_plane: { if plane.ty == PlaneType::Primary
for plane in crtc.possible_planes.values() { && plane.crtc_id.value.get().is_none()
if plane.ty == PlaneType::Primary && plane.formats.contains_key(&XRGB8888.drm)
&& plane.crtc_id.value.get().is_none() {
&& plane.formats.contains_key(&XRGB8888.drm) break 'primary_plane plane.clone();
{
break 'primary_plane plane.clone();
}
} }
return Err(MetalError::NoPrimaryPlaneForConnector);
} }
return Err(MetalError::NoPrimaryPlaneForConnector);
}; };
let format = ModifiedFormat { let format = ModifiedFormat {
format: XRGB8888, format: XRGB8888,