diff --git a/drivers/graphics/driver-graphics/src/kms/connector.rs b/drivers/graphics/driver-graphics/src/kms/connector.rs index acb7683db4..8a865141d4 100644 --- a/drivers/graphics/driver-graphics/src/kms/connector.rs +++ b/drivers/graphics/driver-graphics/src/kms/connector.rs @@ -9,7 +9,7 @@ use drm_sys::{ use syscall::Result; use crate::kms::objects::{KmsObjectId, KmsObjects}; -use crate::kms::properties::{define_object_props, KmsPropertyData, DPMS, EDID}; +use crate::kms::properties::{define_object_props, KmsPropertyData, CRTC_ID, DPMS, EDID}; use crate::GraphicsAdapter; impl KmsObjects { @@ -42,6 +42,7 @@ impl KmsObjects { properties: KmsConnector::base_properties(), dpms: KmsDpms::Off, edid: KmsObjectId::INVALID, + crtc_id: KmsObjectId::INVALID, driver_data, })); self.connectors.push(connector_id); @@ -87,6 +88,7 @@ pub struct KmsConnector { pub properties: Vec>, pub dpms: KmsDpms, pub edid: KmsObjectId, + pub crtc_id: KmsObjectId, pub driver_data: T, } @@ -97,6 +99,9 @@ define_object_props!(object, KmsConnector { DPMS { get => object.dpms as u64, } + CRTC_ID { + get => u64::from(object.crtc_id.0), + } }); impl KmsConnector { diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index ae5e13e8f5..9ffc0bd98d 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -70,7 +70,6 @@ impl KmsObjects { let crtc_index = self.crtcs.len() as u32; let id = self.add(Mutex::new(KmsCrtc { crtc_index, - target_connectors: vec![], fb_id: KmsObjectId::INVALID, gamma_size: 0, mode: None, @@ -192,8 +191,6 @@ define_object_kinds! { #[derive(Debug)] pub struct KmsCrtc { pub crtc_index: u32, - // FIXME maybe have this on connector instead? - pub target_connectors: Vec, pub fb_id: KmsObjectId, pub gamma_size: u32, pub mode: Option, diff --git a/drivers/graphics/driver-graphics/src/kms/properties.rs b/drivers/graphics/driver-graphics/src/kms/properties.rs index 585b5a632d..5eedecbf1c 100644 --- a/drivers/graphics/driver-graphics/src/kms/properties.rs +++ b/drivers/graphics/driver-graphics/src/kms/properties.rs @@ -4,7 +4,8 @@ use std::mem; use drm_sys::{ DRM_MODE_DPMS_OFF, DRM_MODE_DPMS_ON, DRM_MODE_DPMS_STANDBY, DRM_MODE_DPMS_SUSPEND, - DRM_PLANE_TYPE_CURSOR, DRM_PLANE_TYPE_OVERLAY, DRM_PLANE_TYPE_PRIMARY, DRM_PROP_NAME_LEN, + DRM_MODE_OBJECT_CRTC, DRM_MODE_OBJECT_FB, DRM_PLANE_TYPE_CURSOR, DRM_PLANE_TYPE_OVERLAY, + DRM_PLANE_TYPE_PRIMARY, DRM_PROP_NAME_LEN, }; use syscall::{Error, Result, EINVAL}; @@ -28,7 +29,7 @@ impl KmsObjects { KmsPropertyKind::Bitmask(_bitmask_flags) => { // FIXME check overlapping flag numbers } - KmsPropertyKind::Object => {} + KmsPropertyKind::Object { type_: _ } => {} KmsPropertyKind::SignedRange(start, end) => assert!(start < end), } @@ -129,7 +130,7 @@ pub enum KmsPropertyKind { Enum(Vec<(KmsPropertyName, u64)>), Blob, Bitmask(Vec<(KmsPropertyName, u64)>), - Object, + Object { type_: u32 }, SignedRange(i64, i64), } @@ -178,8 +179,8 @@ macro_rules! define_properties { (@prop_kind blob) => { KmsPropertyKind::Blob }; - (@prop_kind object) => { - KmsPropertyKind::Object + (@prop_kind object { $type:ident }) => { + KmsPropertyKind::Object { type_: $type } }; (@prop_kind srange { $start:expr, $end:expr }) => { KmsPropertyKind::SignedRange($start, $end) @@ -188,7 +189,7 @@ macro_rules! define_properties { define_properties! { // Connector + Plane - CRTC_ID: object [atomic], + CRTC_ID: object { DRM_MODE_OBJECT_CRTC } [atomic], // Connector EDID: blob [immutable], @@ -209,7 +210,7 @@ define_properties! { Primary = u64::from(DRM_PLANE_TYPE_PRIMARY), Cursor = u64::from(DRM_PLANE_TYPE_CURSOR), } [immutable], - FB_ID: object [atomic], + FB_ID: object { DRM_MODE_OBJECT_FB } [atomic], CRTC_X: srange { i64::from(i32::MIN), i64::from(i32::MAX) } [atomic], CRTC_Y: srange { i64::from(i32::MIN), i64::from(i32::MAX) } [atomic], CRTC_W: range { 0, u64::from(u32::MAX) } [atomic], diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 78275fd9c7..d16d3763b4 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -103,7 +103,6 @@ pub trait GraphicsAdapter: Sized + Debug { &mut self, objects: &KmsObjects, crtc: &Mutex>, - connectors: &[KmsObjectId], mode: Option, framebuffer: Option<&objects::KmsFramebuffer>, damage: Damage, @@ -238,7 +237,9 @@ impl GraphicsScheme { ); for (display_id, fb) in vt_state.display_fbs.iter().enumerate() { - let crtc = self.inner.objects.crtcs().nth(display_id).unwrap(); + let crtc_id = self.inner.objects.crtc_ids()[display_id]; + let crtc = self.inner.objects.get_crtc(crtc_id).unwrap(); + let connector_id = self.inner.objects.connector_ids()[display_id]; crtc.lock().unwrap().fb_id = fb.unwrap_or(KmsObjectId::INVALID); @@ -255,7 +256,6 @@ impl GraphicsScheme { self.inner.adapter.set_crtc( &self.inner.objects, crtc, - &[self.inner.objects.connector_ids()[display_id]], mode, fb, Damage { @@ -266,8 +266,13 @@ impl GraphicsScheme { }, ); - crtc.lock().unwrap().target_connectors = - vec![self.inner.objects.connector_ids()[display_id]]; + self.inner + .objects + .get_connector(connector_id) + .unwrap() + .lock() + .unwrap() + .crtc_id = crtc_id; } if self.inner.adapter.hw_cursor_size().is_some() { @@ -570,7 +575,6 @@ impl SchemeSync for GraphicsSchemeInner { self.adapter.set_crtc( &self.objects, crtc, - &connector_ids, mode, fb.as_deref(), Damage { @@ -581,7 +585,14 @@ impl SchemeSync for GraphicsSchemeInner { }, ); crtc.lock().unwrap().fb_id = KmsObjectId(data.fb_id()); - crtc.lock().unwrap().target_connectors = connector_ids; + + for connector in connector_ids { + self.objects + .get_connector(connector)? + .lock() + .unwrap() + .crtc_id = KmsObjectId(data.crtc_id()); + } } self.vts.get_mut(vt).unwrap().display_fbs[display_id] = if data.fb_id() != 0 { Some(KmsObjectId(data.fb_id())) @@ -702,9 +713,9 @@ impl SchemeSync for GraphicsSchemeInner { .collect::>(), ); } - KmsPropertyKind::Object => { + KmsPropertyKind::Object { type_ } => { data.set_flags(flags | DRM_MODE_PROP_OBJECT); - data.set_values_ptr(&[]); + data.set_values_ptr(&[u64::from(*type_)]); data.set_enum_blob_ptr(&[]); } &KmsPropertyKind::SignedRange(start, end) => { @@ -773,7 +784,6 @@ impl SchemeSync for GraphicsSchemeInner { self.adapter.set_crtc( &self.objects, crtc, - &[self.objects.connector_ids()[display_id]], None, None, Damage { @@ -811,16 +821,9 @@ impl SchemeSync for GraphicsSchemeInner { if *vt == self.active_vt { for crtc in self.objects.crtcs() { if crtc.lock().unwrap().fb_id == KmsObjectId(data.fb_id()) { - let connectors = crtc.lock().unwrap().target_connectors.clone(); let mode = crtc.lock().unwrap().mode; - self.adapter.set_crtc( - &self.objects, - crtc, - &connectors, - mode, - Some(fb), - damage, - ); + self.adapter + .set_crtc(&self.objects, crtc, mode, Some(fb), damage); } } } diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index 01634c154e..9a7c0ac930 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -81,33 +81,35 @@ impl GraphicsAdapter for Device { &mut self, objects: &KmsObjects, crtc: &Mutex>, - connectors: &[KmsObjectId], mode: Option, buffer: Option<&objects::KmsFramebuffer>, damage: Damage, ) { - crtc.lock().unwrap().mode = mode; + let mut crtc = crtc.lock().unwrap(); + crtc.mode = mode; - let framebuffer_id = objects - .get_connector(connectors[0]) - .unwrap() - .lock() - .unwrap() - .driver_data - .framebuffer_id; + for connector in objects.connectors() { + let connector = connector.lock().unwrap(); - let framebuffer = &mut self.framebuffers[framebuffer_id]; - if let Some(buffer) = buffer { - buffer.buffer.sync(framebuffer, damage) - } else { - let onscreen_ptr = framebuffer.onscreen as *mut u32; // FIXME use as_mut_ptr once stable - for row in 0..framebuffer.height { - unsafe { - ptr::write_bytes( - onscreen_ptr.add(row * framebuffer.stride), - 0, - framebuffer.width, - ); + if connector.crtc_id != objects.crtc_ids()[crtc.crtc_index as usize] { + continue; + } + + let framebuffer_id = connector.driver_data.framebuffer_id; + + let framebuffer = &mut self.framebuffers[framebuffer_id]; + if let Some(buffer) = buffer { + buffer.buffer.sync(framebuffer, damage) + } else { + let onscreen_ptr = framebuffer.onscreen as *mut u32; // FIXME use as_mut_ptr once stable + for row in 0..framebuffer.height { + unsafe { + ptr::write_bytes( + onscreen_ptr.add(row * framebuffer.stride), + 0, + framebuffer.width, + ); + } } } } diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 156acd8bde..262ba2c247 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -88,33 +88,35 @@ impl GraphicsAdapter for FbAdapter { &mut self, objects: &KmsObjects, crtc: &Mutex>, - connectors: &[KmsObjectId], mode: Option, buffer: Option<&objects::KmsFramebuffer>, damage: Damage, ) { - crtc.lock().unwrap().mode = mode; + let mut crtc = crtc.lock().unwrap(); + crtc.mode = mode; - let framebuffer_id = objects - .get_connector(connectors[0]) - .unwrap() - .lock() - .unwrap() - .driver_data - .framebuffer_id; - let framebuffer = &mut self.framebuffers[framebuffer_id]; + for connector in objects.connectors() { + let connector = connector.lock().unwrap(); - if let Some(buffer) = buffer { - buffer.buffer.sync(framebuffer, damage) - } else { - let onscreen_ptr = framebuffer.onscreen as *mut u32; // FIXME use as_mut_ptr once stable - for row in 0..framebuffer.height { - unsafe { - ptr::write_bytes( - onscreen_ptr.add(row * framebuffer.stride), - 0, - framebuffer.width, - ); + if connector.crtc_id != objects.crtc_ids()[crtc.crtc_index as usize] { + continue; + } + + let framebuffer_id = connector.driver_data.framebuffer_id; + let framebuffer = &mut self.framebuffers[framebuffer_id]; + + if let Some(buffer) = buffer { + buffer.buffer.sync(framebuffer, damage) + } else { + let onscreen_ptr = framebuffer.onscreen as *mut u32; // FIXME use as_mut_ptr once stable + for row in 0..framebuffer.height { + unsafe { + ptr::write_bytes( + onscreen_ptr.add(row * framebuffer.stride), + 0, + framebuffer.width, + ); + } } } } diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index 3310e432f3..0ee30b3702 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -402,68 +402,72 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { &mut self, objects: &KmsObjects, crtc: &Mutex>, - connectors: &[KmsObjectId], mode: Option, framebuffer: Option<&objects::KmsFramebuffer>, damage: Damage, ) { futures::executor::block_on(async { - crtc.lock().unwrap().mode = mode; + let mut crtc = crtc.lock().unwrap(); + crtc.mode = mode; - let display_id = objects - .get_connector(connectors[0]) - .unwrap() - .lock() - .unwrap() - .driver_data - .display_id; + for connector in objects.connectors() { + let connector = connector.lock().unwrap(); - let Some(framebuffer) = framebuffer else { - let scanout_request = Dma::new(SetScanout::new( - display_id, - ResourceId::NONE, - GpuRect::new(0, 0, 0, 0), - )) - .unwrap(); - let header = self.send_request(scanout_request).await.unwrap(); - assert_eq!(header.ty, CommandTy::RespOkNodata); - self.displays[display_id as usize].active_resource = None; - return; - }; + if connector.crtc_id != objects.crtc_ids()[crtc.crtc_index as usize] { + continue; + } - let req = Dma::new(XferToHost2d::new( - framebuffer.buffer.id, - GpuRect { - x: 0, - y: 0, - width: framebuffer.width, - height: framebuffer.height, - }, - 0, - )) - .unwrap(); - let header = self.send_request(req).await.unwrap(); - assert_eq!(header.ty, CommandTy::RespOkNodata); + let display_id = connector.driver_data.display_id; - // FIXME once we support resizing we also need to check that the current and target size match - if self.displays[display_id as usize].active_resource != Some(framebuffer.buffer.id) { - let scanout_request = Dma::new(SetScanout::new( - display_id, + let Some(framebuffer) = framebuffer else { + let scanout_request = Dma::new(SetScanout::new( + display_id, + ResourceId::NONE, + GpuRect::new(0, 0, 0, 0), + )) + .unwrap(); + let header = self.send_request(scanout_request).await.unwrap(); + assert_eq!(header.ty, CommandTy::RespOkNodata); + self.displays[display_id as usize].active_resource = None; + return; + }; + + let req = Dma::new(XferToHost2d::new( framebuffer.buffer.id, - GpuRect::new(0, 0, framebuffer.width, framebuffer.height), + GpuRect { + x: 0, + y: 0, + width: framebuffer.width, + height: framebuffer.height, + }, + 0, )) .unwrap(); - let header = self.send_request(scanout_request).await.unwrap(); + let header = self.send_request(req).await.unwrap(); assert_eq!(header.ty, CommandTy::RespOkNodata); - self.displays[display_id as usize].active_resource = Some(framebuffer.buffer.id); - } - let flush = ResourceFlush::new( - framebuffer.buffer.id, - damage.clip(framebuffer.width, framebuffer.height).into(), - ); - let header = self.send_request(Dma::new(flush).unwrap()).await.unwrap(); - assert_eq!(header.ty, CommandTy::RespOkNodata); + // FIXME once we support resizing we also need to check that the current and target size match + if self.displays[display_id as usize].active_resource != Some(framebuffer.buffer.id) + { + let scanout_request = Dma::new(SetScanout::new( + display_id, + framebuffer.buffer.id, + GpuRect::new(0, 0, framebuffer.width, framebuffer.height), + )) + .unwrap(); + let header = self.send_request(scanout_request).await.unwrap(); + assert_eq!(header.ty, CommandTy::RespOkNodata); + self.displays[display_id as usize].active_resource = + Some(framebuffer.buffer.id); + } + + let flush = ResourceFlush::new( + framebuffer.buffer.id, + damage.clip(framebuffer.width, framebuffer.height).into(), + ); + let header = self.send_request(Dma::new(flush).unwrap()).await.unwrap(); + assert_eq!(header.ty, CommandTy::RespOkNodata); + } }); }