diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index 805cea1386..a56c587f8d 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -6,7 +6,7 @@ use std::sync::{Arc, Mutex}; use drm_fourcc::DrmFourcc; use drm_sys::{ drm_mode_modeinfo, DRM_MODE_OBJECT_BLOB, DRM_MODE_OBJECT_CONNECTOR, DRM_MODE_OBJECT_CRTC, - DRM_MODE_OBJECT_ENCODER, DRM_MODE_OBJECT_FB, DRM_MODE_OBJECT_PROPERTY, + DRM_MODE_OBJECT_ENCODER, DRM_MODE_OBJECT_FB, DRM_MODE_OBJECT_PLANE, DRM_MODE_OBJECT_PROPERTY, }; use syscall::{Error, Result, ENOENT}; @@ -22,6 +22,7 @@ pub struct KmsObjects { pub(super) connectors: Vec, pub(super) encoders: Vec, crtcs: Vec, + planes: Vec, framebuffers: Vec, pub(super) objects: HashMap>, _marker: PhantomData, @@ -34,6 +35,7 @@ impl KmsObjects { connectors: vec![], encoders: vec![], crtcs: vec![], + planes: vec![], framebuffers: vec![], objects: HashMap::new(), _marker: PhantomData, @@ -80,14 +82,19 @@ impl KmsObjects { &mut self, driver_data: T::Crtc, driver_data_state: ::State, - ) -> KmsObjectId { + plane_data: T::Plane, + plane_data_state: ::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 { crtc_index, gamma_size: 0, properties: KmsCrtc::base_properties(), + primary_plane, state: KmsCrtcState { - fb_id: None, mode: None, driver_data: driver_data_state, }, @@ -95,7 +102,13 @@ impl KmsObjects { })); self.crtcs.push(id); - id + self.get_plane(primary_plane) + .unwrap() + .lock() + .unwrap() + .possible_crtcs = 1 << crtc_index; + + (id, primary_plane) } pub fn crtc_ids(&self) -> &[KmsObjectId] { @@ -112,6 +125,60 @@ impl KmsObjects { self.get(id) } + pub fn add_plane( + &mut self, + crtcs: &[KmsObjectId], + plane_type: KmsPlaneType, + driver_data: T::Plane, + driver_data_state: ::State, + ) -> KmsObjectId { + let mut possible_crtcs = 0u32; + 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 { + fb_id: None, + crtc_id: None, + src_rect: KmsRect { + x: 0u32, + y: 0, + width: 0, + height: 0, + }, + crtc_rect: KmsRect { + x: 0i32, + y: 0, + width: 0, + height: 0, + }, + driver_data: driver_data_state, + }, + driver_data, + })); + self.planes.push(id); + + id + } + + pub fn plane_ids(&self) -> &[KmsObjectId] { + &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) + } + pub fn add_framebuffer(&mut self, fb: KmsFramebuffer) -> KmsObjectId { let id = self.add(fb); self.framebuffers.push(id); @@ -188,6 +255,7 @@ define_object_kinds! { Connector(Mutex>) = DRM_MODE_OBJECT_CONNECTOR, Encoder(KmsEncoder) = DRM_MODE_OBJECT_ENCODER, Property(KmsProperty) = DRM_MODE_OBJECT_PROPERTY, + Plane(Mutex>) = DRM_MODE_OBJECT_PLANE, Framebuffer(KmsFramebuffer) = DRM_MODE_OBJECT_FB, Blob(KmsBlob) = DRM_MODE_OBJECT_BLOB, } @@ -205,13 +273,13 @@ pub struct KmsCrtc { pub crtc_index: u32, pub gamma_size: u32, pub properties: Vec>, + pub primary_plane: KmsObjectId, pub state: KmsCrtcState, pub driver_data: T::Crtc, } #[derive(Debug)] pub struct KmsCrtcState { - pub fb_id: Option, pub mode: Option, pub driver_data: ::State, } @@ -219,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(), } @@ -232,6 +299,59 @@ define_object_props!(object, KmsCrtc { } }); +pub trait KmsPlaneDriver: Debug { + type State: Clone + Debug; +} + +impl KmsPlaneDriver for () { + type State = (); +} + +#[derive(Debug)] +pub struct KmsPlane { + pub plane_index: u32, + pub possible_crtcs: u32, + pub plane_type: KmsPlaneType, + pub state: KmsPlaneState, + pub driver_data: T::Plane, +} + +#[derive(Debug)] +pub struct KmsPlaneState { + pub fb_id: Option, + pub crtc_id: Option, + pub src_rect: KmsRect, + pub crtc_rect: KmsRect, + pub driver_data: ::State, +} + +impl Clone for KmsPlaneState { + fn clone(&self) -> Self { + Self { + fb_id: self.fb_id.clone(), + crtc_id: self.crtc_id.clone(), + src_rect: self.src_rect.clone(), + crtc_rect: self.crtc_rect.clone(), + driver_data: self.driver_data.clone(), + } + } +} + +#[derive(Debug, PartialEq)] +pub enum KmsPlaneType { + Primary, + Overlay, + Cursor, +} + +#[derive(Debug, Clone)] +pub struct KmsRect { + pub x: T, + pub y: T, + pub width: u32, + pub height: u32, +} + #[derive(Debug)] pub struct KmsFramebuffer { pub width: u32, diff --git a/drivers/graphics/driver-graphics/src/kms/properties.rs b/drivers/graphics/driver-graphics/src/kms/properties.rs index 3a0e8bc5fc..bcd16005c7 100644 --- a/drivers/graphics/driver-graphics/src/kms/properties.rs +++ b/drivers/graphics/driver-graphics/src/kms/properties.rs @@ -70,6 +70,7 @@ impl KmsObjects { .unzip()) } KmsObject::Encoder(_) + | KmsObject::Plane(_) | KmsObject::Property(_) | KmsObject::Framebuffer(_) | KmsObject::Blob(_) => Ok((vec![], vec![])), diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 5652986b22..faa60879cc 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -24,7 +24,10 @@ use syscall::schemev2::NewFdFlags; use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EINVAL, ENOENT, ENXIO, EOPNOTSUPP}; use crate::kms::connector::{KmsConnectorDriver, KmsConnectorState}; -use crate::kms::objects::{self, KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects}; +use crate::kms::objects::{ + self, KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneDriver, + KmsPlaneState, KmsRect, +}; use crate::kms::properties::KmsPropertyKind; pub mod kms; @@ -82,6 +85,7 @@ impl Damage { pub trait GraphicsAdapter: Sized + Debug { type Connector: KmsConnectorDriver; type Crtc: KmsCrtcDriver; + type Plane: KmsPlaneDriver; type Buffer: Buffer; type Framebuffer: Framebuffer; @@ -107,6 +111,13 @@ pub trait GraphicsAdapter: Sized + Debug { objects: &KmsObjects, crtc: &Mutex>, new_state: KmsCrtcState, + ) -> syscall::Result<()>; + + fn set_plane( + &mut self, + objects: &KmsObjects, + plane: &Mutex>, + new_plane_state: KmsPlaneState, damage: Damage, ) -> syscall::Result<()>; @@ -277,6 +288,7 @@ struct GraphicsSchemeInner { struct VtState { connector_state: Vec>, crtc_state: Vec>, + plane_state: Vec>, cursor_plane: Option>, } @@ -306,6 +318,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, @@ -348,24 +364,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 @@ -377,6 +377,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); } @@ -460,14 +485,6 @@ impl SchemeSync for GraphicsSchemeInner { ) -> Result { use redox_ioctl::drm as ipc; - fn id_index(id: u32) -> u32 { - id & 0xFF - } - - fn plane_id(i: u32) -> u32 { - id_index(i) | (1 << 13) - } - match self.handles.get_mut(id)? { Handle::SchemeRoot => return Err(Error::new(EOPNOTSUPP)), Handle::V2 { @@ -575,7 +592,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); @@ -590,7 +617,8 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), ipc::MODE_SET_CRTC => ipc::DrmModeCrtc::with(payload, |data| { - let crtc = self.objects.get_crtc(KmsObjectId(data.crtc_id()))?; + let crtc_id = KmsObjectId(data.crtc_id()); + let crtc = self.objects.get_crtc(crtc_id)?; let connector_ids: Vec = data .set_connectors_ptr() .iter() @@ -607,14 +635,21 @@ impl SchemeSync for GraphicsSchemeInner { } else { None }; - let mut new_state = crtc.lock().unwrap().state.clone(); - new_state.fb_id = fb_id; - new_state.mode = mode; + + let primary_plane_id = crtc.lock().unwrap().primary_plane; + let plane = self.objects.get_plane(primary_plane_id)?; + let mut new_crtc_state = crtc.lock().unwrap().state.clone(); + new_crtc_state.mode = mode; + let mut new_plane_state = plane.lock().unwrap().state.clone(); + 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.adapter + .set_crtc(&self.objects, crtc, new_crtc_state.clone())?; + self.adapter.set_plane( &self.objects, - crtc, - new_state.clone(), + plane, + new_plane_state.clone(), Damage { x: data.x(), y: data.y(), @@ -622,18 +657,21 @@ impl SchemeSync for GraphicsSchemeInner { height: mode.map_or(0, |m| m.vdisplay as u32), }, )?; - for connector in connector_ids { self.objects .get_connector(connector)? .lock() .unwrap() .state - .crtc_id = KmsObjectId(data.crtc_id()); + .crtc_id = crtc_id } } + crtc.lock().unwrap().state = new_crtc_state.clone(); + plane.lock().unwrap().state = new_plane_state.clone(); self.vts.get_mut(vt).unwrap().crtc_state - [crtc.lock().unwrap().crtc_index as usize] = new_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| { @@ -821,21 +859,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, @@ -870,10 +908,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)?; } } } @@ -921,14 +960,79 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), ipc::MODE_GET_PLANE_RES => ipc::DrmModeGetPlaneRes::with(payload, |mut data| { - let count = self.objects.crtc_ids().len(); - let mut ids = Vec::with_capacity(count); - for i in 0..(count as u32) { - ids.push(plane_id(i)); - } + let ids = self + .objects + .plane_ids() + .iter() + .map(|id| id.0) + .collect::>(); data.set_plane_id_ptr(&ids); Ok(0) }), + ipc::MODE_SET_PLANE => ipc::DrmModeSetPlane::with(payload, |data| { + let plane_id = KmsObjectId(data.plane_id()); + let plane = self.objects.get_plane(plane_id)?; + + let crtc_id = KmsObjectId(data.crtc_id()); + let crtc_index = self.objects.get_crtc(crtc_id)?.lock().unwrap().crtc_index; + + let mut new_state = { + let plane = plane.lock().unwrap(); + if plane.possible_crtcs & (1 << crtc_index) == 0 { + return Err(Error::new(EINVAL)); + } + plane.state.clone() + }; + let fb_id = if data.fb_id() != 0 { + KmsObjectId(data.fb_id()) + } else { + KmsObjectId::INVALID + }; + new_state.fb_id = Some(fb_id); + new_state.crtc_id = Some(crtc_id); + new_state.src_rect = KmsRect { + x: data.src_x(), + y: data.src_y(), + width: data.src_w(), + height: data.src_h(), + }; + new_state.crtc_rect = KmsRect { + x: data.crtc_x() as i32, + y: data.crtc_y() as i32, + width: data.crtc_w(), + height: data.crtc_h(), + }; + + if *vt == self.active_vt { + self.adapter.set_plane( + &self.objects, + plane, + new_state.clone(), + Damage { + x: 0, + y: 0, + width: 0, + height: 0, + }, + )?; + } + self.vts.get_mut(vt).unwrap().plane_state + [plane.lock().unwrap().plane_index as usize] = new_state; + Ok(0) + }), + ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| { + let plane = self + .objects + .get_plane(KmsObjectId(data.plane_id())) + .unwrap() + .lock() + .unwrap(); + data.set_crtc_id(plane.state.crtc_id.map_or(0, |id| id.0)); + data.set_fb_id(plane.state.fb_id.unwrap_or(KmsObjectId::INVALID).0); + data.set_possible_crtcs(plane.possible_crtcs); + data.set_format_type_ptr(&[DrmFourcc::Argb8888 as u32]); + Ok(0) + }), ipc::MODE_ADD_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| { // FIXME handle multi-plane framebuffers @@ -950,23 +1054,6 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), - ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| { - let i = id_index(data.plane_id()); - let crtc_id = self.objects.crtc_ids()[i as usize]; - let crtc = self.objects.get_crtc(crtc_id).unwrap(); - data.set_crtc_id(crtc_id.0); - data.set_fb_id( - crtc.lock() - .unwrap() - .state - .fb_id - .unwrap_or(KmsObjectId::INVALID) - .0, - ); - data.set_possible_crtcs(1 << i); - data.set_format_type_ptr(&[DrmFourcc::Argb8888 as u32]); - Ok(0) - }), ipc::MODE_OBJ_GET_PROPERTIES => { ipc::DrmModeObjGetProperties::with(payload, |mut data| { // FIXME remove once all drm objects are materialized in self.objects diff --git a/drivers/graphics/ihdgd/src/device/mod.rs b/drivers/graphics/ihdgd/src/device/mod.rs index 607dcea0ab..142d1bc266 100644 --- a/drivers/graphics/ihdgd/src/device/mod.rs +++ b/drivers/graphics/ihdgd/src/device/mod.rs @@ -449,17 +449,28 @@ 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 }, + (), + scheme::Plane { + pipe_idx, + plane_idx: 0, + }, + (), + ); + + let (width, height) = (fb.width, fb.height); + + let fb_id = objects.add_framebuffer(fb); let connector_id = objects.add_connector((), (), &[crtc_id]); let mut connector = objects.get_connector(connector_id).unwrap().lock().unwrap(); connector.connection = KmsConnectorStatus::Connected; - connector.update_from_size(fb.width, fb.height); + connector.update_from_size(width, height); drop(connector); - let fb_id = objects.add_framebuffer(fb); 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 eaa17f2764..4cc81b050a 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -2,7 +2,8 @@ use std::sync::Mutex; use driver_graphics::kms::connector::KmsConnectorStatus; use driver_graphics::kms::objects::{ - KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects, + KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneDriver, + KmsPlaneState, }; use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter}; use drm_sys::{ @@ -19,10 +20,20 @@ pub struct Crtc { pub pipe_idx: usize, } +#[derive(Debug)] +pub struct Plane { + pub pipe_idx: usize, + pub plane_idx: usize, +} + impl KmsCrtcDriver for Crtc { type State = (); } +impl KmsPlaneDriver for Plane { + type State = (); +} + impl Buffer for GpuBuffer { fn size(&self) -> usize { self.size as usize @@ -32,6 +43,7 @@ impl Buffer for GpuBuffer { impl GraphicsAdapter for Device { type Connector = (); type Crtc = Crtc; + type Plane = Plane; type Buffer = GpuBuffer; type Framebuffer = (); @@ -89,20 +101,36 @@ 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(); - let fb = state + crtc.state = state; + Ok(()) + } + + fn set_plane( + &mut self, + objects: &KmsObjects, + plane: &Mutex>, + new_plane_state: KmsPlaneState, + _damage: Damage, + ) -> syscall::Result<()> { + let mut plane = plane.lock().unwrap(); + + let buffer = new_plane_state .fb_id .map(|fb_id| objects.get_framebuffer(fb_id)) .transpose()?; - crtc.state = state; - if let Some(primary_plane) = self.pipes[crtc.driver_data.pipe_idx].planes.first_mut() { - primary_plane.set_framebuffer(fb); + plane.state = new_plane_state; + + if let Some(plane_hw) = self.pipes[plane.driver_data.pipe_idx] + .planes + .get_mut(plane.driver_data.plane_idx) + { + plane_hw.set_framebuffer(buffer); } Ok(()) diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index daa9908855..002b112390 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -4,7 +4,9 @@ use std::ptr::{self, NonNull}; use std::sync::Mutex; use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus}; -use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{ + KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneState, +}; use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter}; use drm_sys::{ DRM_CAP_DUMB_BUFFER, DRM_CAP_DUMB_PREFERRED_DEPTH, DRM_CAP_DUMB_PREFER_SHADOW, @@ -31,6 +33,7 @@ impl KmsConnectorDriver for Connector { impl GraphicsAdapter for FbAdapter { type Connector = Connector; type Crtc = (); + type Plane = (); type Buffer = GraphicScreen; type Framebuffer = (); @@ -45,7 +48,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 { @@ -103,17 +106,34 @@ 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(); - let buffer = state + crtc.state = state; + Ok(()) + } + + fn set_plane( + &mut self, + objects: &KmsObjects, + plane: &Mutex>, + new_plane_state: KmsPlaneState, + damage: Damage, + ) -> syscall::Result<()> { + 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 .fb_id .map(|fb_id| objects.get_framebuffer(fb_id)) .transpose()?; - crtc.state = state; + + plane.state = new_plane_state; for connector in objects.connectors() { let connector = connector.lock().unwrap(); diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index e855eb704e..f3d0aed693 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -3,7 +3,9 @@ use std::sync::{Arc, Mutex}; use common::{dma::Dma, sgl}; use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus}; -use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{ + KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneState, +}; use driver_graphics::{Buffer as DrmBuffer, CursorPlane, Damage, GraphicsAdapter, GraphicsScheme}; use drm_sys::{ DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_CAP_DUMB_BUFFER, DRM_CAP_DUMB_PREFERRED_DEPTH, @@ -341,6 +343,7 @@ impl<'a> VirtGpuAdapter<'a> { impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { type Connector = VirtGpuConnector; type Crtc = (); + type Plane = (); type Buffer = VirtGpuFramebuffer<'a>; type Framebuffer = (); @@ -359,7 +362,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]); } @@ -424,18 +427,35 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { fn set_crtc( &mut self, - objects: &KmsObjects, + _objects: &KmsObjects, crtc: &Mutex>, state: KmsCrtcState, + ) -> syscall::Result<()> { + let mut crtc = crtc.lock().unwrap(); + crtc.state = state; + Ok(()) + } + + fn set_plane( + &mut self, + objects: &KmsObjects, + plane: &Mutex>, + new_plane_state: KmsPlaneState, damage: Damage, ) -> syscall::Result<()> { futures::executor::block_on(async { - let mut crtc = crtc.lock().unwrap(); - let framebuffer = state + 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 framebuffer = new_plane_state .fb_id .map(|fb_id| objects.get_framebuffer(fb_id)) .transpose()?; - crtc.state = state; + + plane.state = new_plane_state; for connector in objects.connectors() { let connector = connector.lock().unwrap();