diff --git a/src/backends/metal/video.rs b/src/backends/metal/video.rs index 31f68433..4de17908 100644 --- a/src/backends/metal/video.rs +++ b/src/backends/metal/video.rs @@ -1,3 +1,11 @@ +mod hardware_cursor; +mod lease; + +pub use { + hardware_cursor::{MetalHardwareCursor, MetalHardwareCursorChange}, + lease::{MetalLease, MetalLeaseData}, +}; + use { crate::{ async_engine::{Phase, SpawnedFuture}, @@ -415,80 +423,6 @@ impl ConnectorDisplayData { linear_ids!(MetalLeaseIds, MetalLeaseId, u64); -pub struct MetalLeaseData { - pub lease: DrmLease, - pub _lessee: Rc, - pub connectors: Vec>, - pub crtcs: Vec>, - pub planes: Vec>, - pub revoked: Cell, -} - -impl MetalLeaseData { - fn try_revoke(&self) -> bool { - if self.revoked.get() { - return true; - } - let res = self.lease.try_revoke(); - if res { - self.revoked.set(res); - for c in &self.connectors { - c.lease.take(); - if let Err(e) = c.update_properties() { - log::error!("Could not update connector properties: {}", ErrorFmt(e)); - } - } - for c in &self.crtcs { - c.lease.take(); - if let Err(e) = c.update_properties() { - log::error!("Could not update crtc properties: {}", ErrorFmt(e)); - } - } - for p in &self.planes { - p.lease.take(); - if let Err(e) = p.update_properties() { - log::error!("Could not update plane properties: {}", ErrorFmt(e)); - } - } - } - res - } -} - -pub struct MetalLease { - dev: Rc, - id: MetalLeaseId, - fd: Rc, -} - -impl Drop for MetalLease { - fn drop(&mut self) { - if let Some(lease) = self.dev.leases.remove(&self.id) { - if !self.dev.paused.get() { - for c in &lease.connectors { - match c.frontend_state.get() { - FrontState::Removed - | FrontState::Disconnected - | FrontState::Connected { .. } => {} - FrontState::Unavailable => { - c.send_event(ConnectorEvent::Available); - } - } - } - } - if !lease.try_revoke() { - self.dev.leases_to_break.set(self.id, lease); - } - } - } -} - -impl BackendDrmLease for MetalLease { - fn fd(&self) -> &Rc { - &self.fd - } -} - #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum FrontState { Removed, @@ -564,58 +498,6 @@ impl Debug for MetalConnector { } } -pub struct MetalHardwareCursor { - pub connector: Rc, -} - -pub struct MetalHardwareCursorChange<'a> { - pub cursor_swap_buffer: Option>, - pub cursor_enabled: bool, - pub cursor_x: i32, - pub cursor_y: i32, - pub cursor_buffer: &'a RenderBuffer, - pub cursor_size: (i32, i32), -} - -impl Debug for MetalHardwareCursor { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - f.debug_struct("MetalHardwareCursor") - .finish_non_exhaustive() - } -} - -impl HardwareCursor for MetalHardwareCursor { - fn damage(&self) { - self.connector.cursor_damage.set(true); - if self.connector.buffers_idle.get() && self.connector.crtc_idle.get() { - self.connector.schedule_present(); - } - } -} - -impl HardwareCursorUpdate for MetalHardwareCursorChange<'_> { - fn set_enabled(&mut self, enabled: bool) { - self.cursor_enabled = enabled; - } - - fn get_buffer(&self) -> Rc { - self.cursor_buffer.render.fb.clone() - } - - fn set_position(&mut self, x: i32, y: i32) { - self.cursor_x = x; - self.cursor_y = y; - } - - fn swap_buffer(&mut self, sync: Option) { - self.cursor_swap_buffer = Some(sync); - } - - fn size(&self) -> (i32, i32) { - self.cursor_size - } -} - pub struct ConnectorFutures { pub _present: SpawnedFuture<()>, } diff --git a/src/backends/metal/video/hardware_cursor.rs b/src/backends/metal/video/hardware_cursor.rs new file mode 100644 index 00000000..3eacbb68 --- /dev/null +++ b/src/backends/metal/video/hardware_cursor.rs @@ -0,0 +1,53 @@ +use super::*; + +pub struct MetalHardwareCursor { + pub connector: Rc, +} + +pub struct MetalHardwareCursorChange<'a> { + pub cursor_swap_buffer: Option>, + pub cursor_enabled: bool, + pub cursor_x: i32, + pub cursor_y: i32, + pub cursor_buffer: &'a RenderBuffer, + pub cursor_size: (i32, i32), +} + +impl Debug for MetalHardwareCursor { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct("MetalHardwareCursor") + .finish_non_exhaustive() + } +} + +impl HardwareCursor for MetalHardwareCursor { + fn damage(&self) { + self.connector.cursor_damage.set(true); + if self.connector.buffers_idle.get() && self.connector.crtc_idle.get() { + self.connector.schedule_present(); + } + } +} + +impl HardwareCursorUpdate for MetalHardwareCursorChange<'_> { + fn set_enabled(&mut self, enabled: bool) { + self.cursor_enabled = enabled; + } + + fn get_buffer(&self) -> Rc { + self.cursor_buffer.render.fb.clone() + } + + fn set_position(&mut self, x: i32, y: i32) { + self.cursor_x = x; + self.cursor_y = y; + } + + fn swap_buffer(&mut self, sync: Option) { + self.cursor_swap_buffer = Some(sync); + } + + fn size(&self) -> (i32, i32) { + self.cursor_size + } +} diff --git a/src/backends/metal/video/lease.rs b/src/backends/metal/video/lease.rs new file mode 100644 index 00000000..cef6cb8d --- /dev/null +++ b/src/backends/metal/video/lease.rs @@ -0,0 +1,75 @@ +use super::*; + +pub struct MetalLeaseData { + pub lease: DrmLease, + pub _lessee: Rc, + pub connectors: Vec>, + pub crtcs: Vec>, + pub planes: Vec>, + pub revoked: Cell, +} + +impl MetalLeaseData { + pub(super) fn try_revoke(&self) -> bool { + if self.revoked.get() { + return true; + } + let res = self.lease.try_revoke(); + if res { + self.revoked.set(res); + for c in &self.connectors { + c.lease.take(); + if let Err(e) = c.update_properties() { + log::error!("Could not update connector properties: {}", ErrorFmt(e)); + } + } + for c in &self.crtcs { + c.lease.take(); + if let Err(e) = c.update_properties() { + log::error!("Could not update crtc properties: {}", ErrorFmt(e)); + } + } + for p in &self.planes { + p.lease.take(); + if let Err(e) = p.update_properties() { + log::error!("Could not update plane properties: {}", ErrorFmt(e)); + } + } + } + res + } +} + +pub struct MetalLease { + pub(super) dev: Rc, + pub(super) id: MetalLeaseId, + pub(super) fd: Rc, +} + +impl Drop for MetalLease { + fn drop(&mut self) { + if let Some(lease) = self.dev.leases.remove(&self.id) { + if !self.dev.paused.get() { + for c in &lease.connectors { + match c.frontend_state.get() { + FrontState::Removed + | FrontState::Disconnected + | FrontState::Connected { .. } => {} + FrontState::Unavailable => { + c.send_event(ConnectorEvent::Available); + } + } + } + } + if !lease.try_revoke() { + self.dev.leases_to_break.set(self.id, lease); + } + } + } +} + +impl BackendDrmLease for MetalLease { + fn fd(&self) -> &Rc { + &self.fd + } +}