diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index 329ca16710..91ecc8c362 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -84,13 +84,9 @@ impl KmsObjects { driver_data_state: ::State, plane_data: T::Plane, plane_data_state: ::State, - ) -> KmsObjectId { - let primary_plane = self.add_plane( - &[], - KmsPlaneType::Primary, - plane_data, - plane_data_state, - ); + ) -> (KmsObjectId, KmsObjectId) { + let primary_plane = + self.add_plane(&[], KmsPlaneType::Primary, plane_data, plane_data_state); let crtc_index = self.crtcs.len() as u32; let id = self.add(Mutex::new(KmsCrtc { @@ -99,7 +95,6 @@ impl KmsObjects { properties: KmsCrtc::base_properties(), primary_plane, state: KmsCrtcState { - fb_id: None, mode: None, driver_data: driver_data_state, }, @@ -107,9 +102,13 @@ impl KmsObjects { })); self.crtcs.push(id); - self.get_plane(primary_plane).unwrap().lock().unwrap().possible_crtcs = 1 << crtc_index; + self.get_plane(primary_plane) + .unwrap() + .lock() + .unwrap() + .possible_crtcs = 1 << crtc_index; - id + (id, primary_plane) } pub fn crtc_ids(&self) -> &[KmsObjectId] { @@ -155,7 +154,9 @@ impl KmsObjects { for &crtc in crtcs { possible_crtcs |= 1 << self.get_crtc(crtc).unwrap().lock().unwrap().crtc_index } + let plane_index = self.planes.len() as u32; let id = self.add(Mutex::new(KmsPlane { + plane_index, possible_crtcs, plane_type, state: KmsPlaneState { @@ -186,6 +187,12 @@ impl KmsObjects { &self.planes } + pub fn planes(&self) -> impl Iterator>> + use<'_, T> { + self.planes + .iter() + .map(|&id| self.get::>>(id).unwrap()) + } + pub fn get_plane(&self, id: KmsObjectId) -> Result<&Mutex>> { self.get(id) } @@ -273,7 +280,6 @@ pub struct KmsCrtc { #[derive(Debug)] pub struct KmsCrtcState { - pub fb_id: Option, pub mode: Option, pub driver_data: ::State, } @@ -281,7 +287,6 @@ pub struct KmsCrtcState { impl Clone for KmsCrtcState { fn clone(&self) -> Self { Self { - fb_id: self.fb_id.clone(), mode: self.mode.clone(), driver_data: self.driver_data.clone(), } @@ -314,6 +319,7 @@ impl KmsPlaneDriver for () { #[derive(Debug)] pub struct KmsPlane { + pub plane_index: u32, pub possible_crtcs: u32, pub plane_type: KmsPlaneType, pub state: KmsPlaneState, diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 137d6d10ca..5a191f28f8 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -112,13 +112,11 @@ pub trait GraphicsAdapter: Sized + Debug { objects: &KmsObjects, crtc: &Mutex>, new_state: KmsCrtcState, - damage: Damage, ) -> syscall::Result<()>; fn set_plane( &mut self, objects: &KmsObjects, - crtc: &Mutex>, plane: &Mutex>, new_plane_state: KmsPlaneState, damage: Damage, @@ -291,6 +289,7 @@ struct GraphicsSchemeInner { struct VtState { connector_state: Vec>, crtc_state: Vec>, + plane_state: Vec>, cursor_plane: Option>, } @@ -320,6 +319,10 @@ impl GraphicsSchemeInner { .crtcs() .map(|crtc| crtc.lock().unwrap().state.clone()) .collect(), + plane_state: objects + .planes() + .map(|plane| plane.lock().unwrap().state.clone()) + .collect(), cursor_plane: adapter.has_cursor_plane().then(|| CursorPlane { x: 0, y: 0, @@ -362,24 +365,8 @@ impl GraphicsSchemeInner { let crtc = self.objects.get_crtc(crtc_id).unwrap(); let connector_id = self.objects.connector_ids()[crtc_idx]; - let fb = crtc_state.fb_id.map(|fb_id| { - self.objects - .get_framebuffer(fb_id) - .expect("removed framebuffers should be unset") - }); - self.adapter - .set_crtc( - &self.objects, - crtc, - crtc_state.clone(), - Damage { - x: 0, - y: 0, - width: fb.map_or(0, |fb| fb.width), - height: fb.map_or(0, |fb| fb.height), - }, - ) + .set_crtc(&self.objects, crtc, crtc_state.clone()) .unwrap(); self.objects @@ -391,6 +378,31 @@ impl GraphicsSchemeInner { .crtc_id = crtc_id; } + for (plane_idx, plane_state) in vt_state.plane_state.iter().enumerate() { + let plane_id = self.objects.plane_ids()[plane_idx]; + let plane = self.objects.get_plane(plane_id).unwrap(); + + let fb = plane_state.fb_id.map(|fb_id| { + self.objects + .get_framebuffer(fb_id) + .expect("removed framebuffers should be unset") + }); + + self.adapter + .set_plane( + &self.objects, + plane, + plane_state.clone(), + Damage { + x: 0, + y: 0, + width: fb.map_or(0, |fb| fb.width), + height: fb.map_or(0, |fb| fb.height), + }, + ) + .unwrap(); + } + if let Some(cursor_plane) = &vt_state.cursor_plane { self.adapter.handle_cursor(cursor_plane, true); } @@ -581,7 +593,17 @@ impl SchemeSync for GraphicsSchemeInner { .lock() .unwrap(); // Don't touch set_connectors, that is only used by MODE_SET_CRTC - data.set_fb_id(crtc.state.fb_id.unwrap_or(KmsObjectId::INVALID).0); + data.set_fb_id( + self.objects + .get_plane(crtc.primary_plane) + .unwrap() + .lock() + .unwrap() + .state + .fb_id + .unwrap_or(KmsObjectId::INVALID) + .0, + ); // FIXME fill x and y with the data from the primary plane data.set_x(0); data.set_y(0); @@ -623,20 +645,10 @@ impl SchemeSync for GraphicsSchemeInner { new_plane_state.fb_id = fb_id; new_plane_state.crtc_id = Some(crtc_id); if *vt == self.active_vt { - self.adapter.set_crtc( - &self.objects, - crtc, - new_crtc_state.clone(), - Damage { - x: 0, - y: 0, - width: 0, - height: 0, - }, - )?; + self.adapter + .set_crtc(&self.objects, crtc, new_crtc_state.clone())?; self.adapter.set_plane( &self.objects, - crtc, plane, new_plane_state.clone(), Damage { @@ -659,6 +671,8 @@ impl SchemeSync for GraphicsSchemeInner { plane.lock().unwrap().state = new_plane_state.clone(); self.vts.get_mut(vt).unwrap().crtc_state [crtc.lock().unwrap().crtc_index as usize] = new_crtc_state; + self.vts.get_mut(vt).unwrap().plane_state + [plane.lock().unwrap().plane_index as usize] = new_plane_state; Ok(0) }), ipc::MODE_CURSOR => ipc::DrmModeCursor::with(payload, |data| { @@ -846,21 +860,21 @@ impl SchemeSync for GraphicsSchemeInner { // Disable planes that use this framebuffer. for (vt, vt_data) in &mut self.vts { - for (crtc_idx, crtc_state) in vt_data.crtc_state.iter_mut().enumerate() { - if crtc_state.fb_id != Some(fb_id) { + for (plane_idx, plane_state) in vt_data.plane_state.iter_mut().enumerate() { + if plane_state.fb_id != Some(fb_id) { continue; } - crtc_state.fb_id = None; + plane_state.fb_id = None; if *vt != self.active_vt { continue; } - let crtc = self.objects.crtcs().nth(crtc_idx).unwrap(); + let plane = self.objects.planes().nth(plane_idx).unwrap(); self.adapter - .set_crtc( + .set_plane( &self.objects, - crtc, - crtc_state.clone(), + plane, + plane_state.clone(), Damage { x: 0, y: 0, @@ -895,10 +909,11 @@ impl SchemeSync for GraphicsSchemeInner { }); if *vt == self.active_vt { - for crtc in self.objects.crtcs() { - let state = crtc.lock().unwrap().state.clone(); + for plane in self.objects.planes() { + let state = plane.lock().unwrap().state.clone(); if state.fb_id == Some(KmsObjectId(data.fb_id())) { - self.adapter.set_crtc(&self.objects, crtc, state, damage)?; + self.adapter + .set_plane(&self.objects, plane, state, damage)?; } } } @@ -960,8 +975,7 @@ impl SchemeSync for GraphicsSchemeInner { let plane_mutex = self.objects.get_plane(plane_id)?; let crtc_id = KmsObjectId(data.crtc_id()); - let crtc = self.objects.get_crtc(crtc_id)?; - let crtc_index = crtc.lock().unwrap().crtc_index; + let crtc_index = self.objects.get_crtc(crtc_id)?.lock().unwrap().crtc_index; let new_state; { @@ -996,7 +1010,6 @@ impl SchemeSync for GraphicsSchemeInner { if *vt == self.active_vt { self.adapter.set_plane( &self.objects, - crtc, plane_mutex, new_state, Damage { diff --git a/drivers/graphics/ihdgd/src/device/mod.rs b/drivers/graphics/ihdgd/src/device/mod.rs index eb3ff9723f..f1845c40b5 100644 --- a/drivers/graphics/ihdgd/src/device/mod.rs +++ b/drivers/graphics/ihdgd/src/device/mod.rs @@ -449,7 +449,7 @@ impl Device { } fn add_kms_pipe(objects: &mut KmsObjects, pipe_idx: usize, fb: KmsFramebuffer) { - let crtc_id = objects.add_crtc(Crtc { pipe_idx }, (), (), ()); + let (crtc_id, primary_plane_id) = objects.add_crtc(Crtc { pipe_idx }, (), (), ()); let (width, height) = (fb.width, fb.height); @@ -462,7 +462,7 @@ impl Device { drop(connector); objects - .get_crtc(crtc_id) + .get_plane(primary_plane_id) .unwrap() .lock() .unwrap() diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index d746e725aa..a02e2b71b3 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -100,10 +100,9 @@ impl GraphicsAdapter for Device { fn set_crtc( &mut self, - objects: &KmsObjects, + _objects: &KmsObjects, crtc: &Mutex>, state: KmsCrtcState, - _damage: Damage, ) -> syscall::Result<()> { let mut crtc = crtc.lock().unwrap(); crtc.state = state; @@ -113,12 +112,14 @@ impl GraphicsAdapter for Device { fn set_plane( &mut self, objects: &KmsObjects, - crtc: &Mutex>, plane: &Mutex>, new_plane_state: KmsPlaneState, - damage: Damage, + _damage: Damage, ) -> syscall::Result<()> { - let crtc = crtc.lock().unwrap(); + let Some(crtc_id) = new_plane_state.crtc_id else { + return Ok(()); + }; + let crtc = objects.get_crtc(crtc_id).unwrap().lock().unwrap(); let mut plane = plane.lock().unwrap(); let buffer = new_plane_state diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index c8bab6d81f..50eb113d05 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -49,7 +49,7 @@ impl GraphicsAdapter for FbAdapter { fn init(&mut self, objects: &mut KmsObjects) { for (framebuffer_id, framebuffer) in self.framebuffers.iter().enumerate() { - let crtc = objects.add_crtc((), (), (), ()); + let (crtc, _primary_plane_id) = objects.add_crtc((), (), (), ()); objects.add_connector( Connector { @@ -107,10 +107,9 @@ impl GraphicsAdapter for FbAdapter { fn set_crtc( &mut self, - objects: &KmsObjects, + _objects: &KmsObjects, crtc: &Mutex>, state: KmsCrtcState, - damage: Damage, ) -> syscall::Result<()> { let mut crtc = crtc.lock().unwrap(); crtc.state = state; @@ -120,12 +119,14 @@ impl GraphicsAdapter for FbAdapter { fn set_plane( &mut self, objects: &KmsObjects, - crtc: &Mutex>, plane: &Mutex>, new_plane_state: KmsPlaneState, damage: Damage, ) -> syscall::Result<()> { - let mut crtc = crtc.lock().unwrap(); + let Some(crtc_id) = new_plane_state.crtc_id else { + return Ok(()); + }; + let crtc = objects.get_crtc(crtc_id).unwrap().lock().unwrap(); let mut plane = plane.lock().unwrap(); let buffer = new_plane_state diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index de1f86d766..a1f45429e7 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -363,7 +363,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { }); for display_id in 0..self.config.num_scanouts.get() { - let crtc = objects.add_crtc((), (), (), ()); + let (crtc, _primary_plane_id) = objects.add_crtc((), (), (), ()); objects.add_connector(VirtGpuConnector { display_id }, (), &[crtc]); } @@ -428,10 +428,9 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { fn set_crtc( &mut self, - objects: &KmsObjects, + _objects: &KmsObjects, crtc: &Mutex>, state: KmsCrtcState, - damage: Damage, ) -> syscall::Result<()> { let mut crtc = crtc.lock().unwrap(); crtc.state = state; @@ -441,13 +440,15 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { fn set_plane( &mut self, objects: &KmsObjects, - crtc: &Mutex>, plane: &Mutex>, new_plane_state: KmsPlaneState, damage: Damage, ) -> syscall::Result<()> { futures::executor::block_on(async { - let crtc = crtc.lock().unwrap(); + let Some(crtc_id) = new_plane_state.crtc_id else { + return Ok(()); + }; + let crtc = objects.get_crtc(crtc_id).unwrap().lock().unwrap(); let mut plane = plane.lock().unwrap(); // fb_id now in plane state