From 5e7fc9d71acfc36175cd3bdb8bfe95a53f228550 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Mar 2026 20:27:43 +0100 Subject: [PATCH 1/5] drivers/graphics: Remove refcounting for all KmsObject's Doing the refcounting outside the enum doesn't allow refcounting a downcasted object. And most objects don't need refcounting after all. --- drivers/graphics/driver-graphics/src/kms/objects.rs | 8 ++++---- drivers/graphics/driver-graphics/src/kms/properties.rs | 2 +- drivers/graphics/driver-graphics/src/lib.rs | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index 86e486f0b4..7a761f1bff 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -22,7 +22,7 @@ pub struct KmsObjects { pub(crate) encoders: Vec, crtcs: Vec, framebuffers: Vec, - pub(crate) objects: HashMap>>, + pub(crate) objects: HashMap>, _marker: PhantomData, } @@ -43,7 +43,7 @@ impl KmsObjects { pub(crate) fn add>>(&mut self, data: U) -> KmsObjectId { let id = self.next_id; - self.objects.insert(id, Arc::new(data.into())); + self.objects.insert(id, data.into()); self.next_id.0 += 1; id @@ -54,7 +54,7 @@ impl KmsObjects { &'a U: TryFrom<&'a KmsObject>, { let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?; - if let Ok(object) = (&**object).try_into() { + if let Ok(object) = object.try_into() { Ok(object) } else { Err(Error::new(EINVAL)) @@ -112,7 +112,7 @@ impl KmsObjects { } pub fn remove_framebuffer(&mut self, id: KmsObjectId) -> Result<()> { - let Some(object) = self.objects.get(&id).map(|object| &**object) else { + let Some(object) = self.objects.get(&id) else { return Err(Error::new(EINVAL)); }; let KmsObject::Framebuffer(_) = object else { diff --git a/drivers/graphics/driver-graphics/src/kms/properties.rs b/drivers/graphics/driver-graphics/src/kms/properties.rs index fd7ec79071..e22527a702 100644 --- a/drivers/graphics/driver-graphics/src/kms/properties.rs +++ b/drivers/graphics/driver-graphics/src/kms/properties.rs @@ -52,7 +52,7 @@ impl KmsObjects { pub fn get_object_properties_data(&self, id: KmsObjectId) -> Result<(Vec, Vec)> { let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?; - match &**object { + match object { KmsObject::Crtc(crtc) => { let crtc = crtc.lock().unwrap(); let props = &crtc.properties; diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 716e0bbd38..44aad7eb90 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -577,7 +577,7 @@ impl SchemeSync for GraphicsSchemeInner { &self.objects, crtc, mode, - fb.as_deref(), + fb, Damage { x: data.x(), y: data.y(), From d08300c8b5aba28d04bc5c20aa33e8943bc00c5e Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Mar 2026 20:41:04 +0100 Subject: [PATCH 2/5] drivers/graphics: Make objects generic over GraphicsAdapter rather than specific driver data --- .../driver-graphics/src/kms/connector.rs | 80 +++++++++---------- .../driver-graphics/src/kms/objects.rs | 40 ++++------ drivers/graphics/driver-graphics/src/lib.rs | 9 +-- drivers/graphics/ihdgd/src/device/scheme.rs | 6 +- drivers/graphics/vesad/src/scheme.rs | 6 +- drivers/graphics/virtio-gpud/src/scheme.rs | 6 +- 6 files changed, 69 insertions(+), 78 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/kms/connector.rs b/drivers/graphics/driver-graphics/src/kms/connector.rs index c9542edce4..76bf65fa3e 100644 --- a/drivers/graphics/driver-graphics/src/kms/connector.rs +++ b/drivers/graphics/driver-graphics/src/kms/connector.rs @@ -58,15 +58,13 @@ impl KmsObjects { &self.connectors } - pub fn connectors( - &self, - ) -> impl Iterator>> + use<'_, T> { + pub fn connectors(&self) -> impl Iterator>> + use<'_, T> { self.connectors .iter() .map(|&id| self.get_connector(id).unwrap()) } - pub fn get_connector(&self, id: KmsObjectId) -> Result<&Mutex>> { + pub fn get_connector(&self, id: KmsObjectId) -> Result<&Mutex>> { self.get(id) } @@ -88,7 +86,7 @@ impl KmsConnectorDriver for () { } #[derive(Debug)] -pub struct KmsConnector { +pub struct KmsConnector { pub encoder_id: KmsObjectId, pub modes: Vec, pub connector_type: u32, @@ -99,18 +97,18 @@ pub struct KmsConnector { pub subpixel: DrmSubpixelOrder, pub properties: Vec>, pub edid: KmsObjectId, - pub state: KmsConnectorState, - pub driver_data: T, + pub state: KmsConnectorState, + pub driver_data: T::Connector, } #[derive(Debug, Clone)] -pub struct KmsConnectorState { +pub struct KmsConnectorState { pub dpms: KmsDpms, pub crtc_id: KmsObjectId, - pub driver_data: T, + pub driver_data: ::State, } -define_object_props!(object, KmsConnector { +define_object_props!(object, KmsConnector { EDID { get => u64::from(object.edid.0), } @@ -122,9 +120,9 @@ define_object_props!(object, KmsConnector { } }); -impl KmsConnector { +impl KmsConnector { pub fn update_from_size(&mut self, width: u32, height: u32) { - self.modes = vec![Self::modeinfo_for_size(width, height)]; + self.modes = vec![modeinfo_for_size(width, height)]; } pub fn update_from_edid(&mut self, edid: &[u8]) { @@ -151,7 +149,7 @@ impl KmsConnector { match descriptor { edid::Descriptor::DetailedTiming(detailed_timing) => { // FIXME extract full information - Some(Self::modeinfo_for_size( + Some(modeinfo_for_size( u32::from(detailed_timing.horizontal_active_pixels), u32::from(detailed_timing.vertical_active_lines), )) @@ -168,40 +166,40 @@ impl KmsConnector { // FIXME update the EDID property } +} - pub(crate) fn modeinfo_for_size(width: u32, height: u32) -> drm_mode_modeinfo { - let mut modeinfo = drm_mode_modeinfo { - // The actual visible display size - hdisplay: width as u16, - vdisplay: height as u16, +pub(crate) fn modeinfo_for_size(width: u32, height: u32) -> drm_mode_modeinfo { + let mut modeinfo = drm_mode_modeinfo { + // The actual visible display size + hdisplay: width as u16, + vdisplay: height as u16, - // These are used to calculate the refresh rate - clock: 60 * width * height / 1000, - htotal: width as u16, - vtotal: height as u16, - vscan: 0, - vrefresh: 60, + // These are used to calculate the refresh rate + clock: 60 * width * height / 1000, + htotal: width as u16, + vtotal: height as u16, + vscan: 0, + vrefresh: 60, - type_: drm_sys::DRM_MODE_TYPE_PREFERRED | drm_sys::DRM_MODE_TYPE_DRIVER, - name: [0; 32], + type_: drm_sys::DRM_MODE_TYPE_PREFERRED | drm_sys::DRM_MODE_TYPE_DRIVER, + name: [0; 32], - // These only matter when modesetting physical display adapters. For - // those we should be able to parse the EDID blob. - hsync_start: width as u16, - hsync_end: width as u16, - hskew: 0, - vsync_start: height as u16, - vsync_end: height as u16, - flags: 0, - }; + // These only matter when modesetting physical display adapters. For + // those we should be able to parse the EDID blob. + hsync_start: width as u16, + hsync_end: width as u16, + hskew: 0, + vsync_start: height as u16, + vsync_end: height as u16, + flags: 0, + }; - let name = format!("{width}x{height}").into_bytes(); - for (to, from) in modeinfo.name.iter_mut().zip(name) { - *to = from as c_char; - } - - modeinfo + let name = format!("{width}x{height}").into_bytes(); + for (to, from) in modeinfo.name.iter_mut().zip(name) { + *to = from as c_char; } + + modeinfo } #[derive(Debug, Copy, Clone)] diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index 7a761f1bff..5dd4b4ca79 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -92,20 +92,17 @@ impl KmsObjects { &self.crtcs } - pub fn crtcs(&self) -> impl Iterator>> + use<'_, T> { + pub fn crtcs(&self) -> impl Iterator>> + use<'_, T> { self.crtcs .iter() - .map(|&id| self.get::>>(id).unwrap()) + .map(|&id| self.get::>>(id).unwrap()) } - pub fn get_crtc(&self, id: KmsObjectId) -> Result<&Mutex>> { + pub fn get_crtc(&self, id: KmsObjectId) -> Result<&Mutex>> { self.get(id) } - pub fn add_framebuffer( - &mut self, - fb: KmsFramebuffer, - ) -> KmsObjectId { + pub fn add_framebuffer(&mut self, fb: KmsFramebuffer) -> KmsObjectId { let id = self.add(fb); self.framebuffers.push(id); id @@ -127,10 +124,7 @@ impl KmsObjects { &self.framebuffers } - pub fn get_framebuffer( - &self, - id: KmsObjectId, - ) -> Result<&KmsFramebuffer> { + pub fn get_framebuffer(&self, id: KmsObjectId) -> Result<&KmsFramebuffer> { self.get(id) } } @@ -187,11 +181,11 @@ macro_rules! define_object_kinds { } define_object_kinds! { - Crtc(Mutex>) = DRM_MODE_OBJECT_CRTC, - Connector(Mutex>) = DRM_MODE_OBJECT_CONNECTOR, + Crtc(Mutex>) = DRM_MODE_OBJECT_CRTC, + Connector(Mutex>) = DRM_MODE_OBJECT_CONNECTOR, Encoder(KmsEncoder) = DRM_MODE_OBJECT_ENCODER, Property(KmsProperty) = DRM_MODE_OBJECT_PROPERTY, - Framebuffer(KmsFramebuffer) = DRM_MODE_OBJECT_FB, + Framebuffer(KmsFramebuffer) = DRM_MODE_OBJECT_FB, Blob(KmsBlob) = DRM_MODE_OBJECT_BLOB, } @@ -204,30 +198,30 @@ impl KmsCrtcDriver for () { } #[derive(Debug)] -pub struct KmsCrtc { +pub struct KmsCrtc { pub crtc_index: u32, pub gamma_size: u32, pub properties: Vec>, - pub state: KmsCrtcState, - pub driver_data: T, + pub state: KmsCrtcState, + pub driver_data: T::Crtc, } #[derive(Debug, Clone)] -pub struct KmsCrtcState { +pub struct KmsCrtcState { pub fb_id: KmsObjectId, pub mode: Option, - pub driver_data: T, + pub driver_data: ::State, } -define_object_props!(object, KmsCrtc {}); +define_object_props!(object, KmsCrtc {}); #[derive(Debug)] -pub struct KmsFramebuffer { +pub struct KmsFramebuffer { pub width: u32, pub height: u32, pub pitch: u32, pub bpp: u32, pub depth: u32, - pub buffer: Arc, - pub driver_data: T, + pub buffer: Arc, + pub driver_data: T::Framebuffer, } diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 44aad7eb90..bdefaba6f2 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -21,7 +21,7 @@ use redox_scheme::{CallerCtx, OpenResult, RequestKind, SignalBehavior, Socket}; use syscall::schemev2::NewFdFlags; use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EBADF, EINVAL, ENOENT, EOPNOTSUPP}; -use crate::kms::connector::{KmsConnector, KmsConnectorDriver}; +use crate::kms::connector::{self, KmsConnectorDriver}; use crate::kms::objects::{self, KmsCrtc, KmsCrtcDriver, KmsObjectId, KmsObjects}; use crate::kms::properties::KmsPropertyKind; @@ -102,9 +102,9 @@ pub trait GraphicsAdapter: Sized + Debug { fn set_crtc( &mut self, objects: &KmsObjects, - crtc: &Mutex>, + crtc: &Mutex>, mode: Option, - framebuffer: Option<&objects::KmsFramebuffer>, + framebuffer: Option<&objects::KmsFramebuffer>, damage: Damage, ); @@ -250,8 +250,7 @@ impl GraphicsScheme { .expect("removed framebuffers should be unset") }); - let mode = - fb.map(|fb| KmsConnector::<()>::modeinfo_for_size(fb.width, fb.height)); + let mode = fb.map(|fb| connector::modeinfo_for_size(fb.width, fb.height)); self.inner.adapter.set_crtc( &self.inner.objects, diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index 14bb0f01d0..f4851a0c5b 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -6,7 +6,7 @@ use std::ptr::{self, NonNull}; use std::sync::Mutex; use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus}; -use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{KmsCrtc, KmsFramebuffer, KmsObjectId, KmsObjects}; use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter}; use drm_sys::{drm_mode_modeinfo, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; use syscall::{error::EINVAL, PAGE_SIZE}; @@ -84,9 +84,9 @@ impl GraphicsAdapter for Device { fn set_crtc( &mut self, objects: &KmsObjects, - crtc: &Mutex>, + crtc: &Mutex>, mode: Option, - buffer: Option<&objects::KmsFramebuffer>, + buffer: Option<&KmsFramebuffer>, damage: Damage, ) { let mut crtc = crtc.lock().unwrap(); diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 061bc255bc..8905460282 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -4,7 +4,7 @@ use std::ptr::{self, NonNull}; use std::sync::Mutex; use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus}; -use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{KmsCrtc, KmsFramebuffer, KmsObjectId, KmsObjects}; use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter}; use drm_sys::{drm_mode_modeinfo, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; use syscall::{EINVAL, PAGE_SIZE}; @@ -92,9 +92,9 @@ impl GraphicsAdapter for FbAdapter { fn set_crtc( &mut self, objects: &KmsObjects, - crtc: &Mutex>, + crtc: &Mutex>, mode: Option, - buffer: Option<&objects::KmsFramebuffer>, + buffer: Option<&KmsFramebuffer>, damage: Damage, ) { let mut crtc = crtc.lock().unwrap(); diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index 4a828c9803..91dc1c8ef3 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -3,7 +3,7 @@ use std::sync::{Arc, Mutex}; use common::{dma::Dma, sgl}; use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus}; -use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{KmsCrtc, KmsFramebuffer, KmsObjectId, KmsObjects}; use driver_graphics::{Buffer as DrmBuffer, CursorPlane, Damage, GraphicsAdapter, GraphicsScheme}; use drm_sys::{ drm_mode_modeinfo, DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_CAP_DUMB_BUFFER, @@ -405,9 +405,9 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { fn set_crtc( &mut self, objects: &KmsObjects, - crtc: &Mutex>, + crtc: &Mutex>, mode: Option, - framebuffer: Option<&objects::KmsFramebuffer>, + framebuffer: Option<&KmsFramebuffer>, damage: Damage, ) { futures::executor::block_on(async { From 925951ce85931ce553eb23bb8d17fc813c1943fa Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Mar 2026 21:11:58 +0100 Subject: [PATCH 3/5] drivers/graphics: Make KmsCrtcState::fb_id an Option --- .../driver-graphics/src/kms/objects.rs | 4 +-- drivers/graphics/driver-graphics/src/lib.rs | 26 +++++++++++++------ 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index 5dd4b4ca79..5958257c64 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -77,7 +77,7 @@ impl KmsObjects { gamma_size: 0, properties: KmsCrtc::base_properties(), state: KmsCrtcState { - fb_id: KmsObjectId::INVALID, + fb_id: None, mode: None, driver_data: driver_data_state, }, @@ -208,7 +208,7 @@ pub struct KmsCrtc { #[derive(Debug, Clone)] pub struct KmsCrtcState { - pub fb_id: KmsObjectId, + pub fb_id: Option, pub mode: Option, pub driver_data: ::State, } diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index bdefaba6f2..4949c5fae1 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -241,7 +241,7 @@ impl GraphicsScheme { let crtc = self.inner.objects.get_crtc(crtc_id).unwrap(); let connector_id = self.inner.objects.connector_ids()[display_id]; - crtc.lock().unwrap().state.fb_id = fb.unwrap_or(KmsObjectId::INVALID); + crtc.lock().unwrap().state.fb_id = *fb; let fb = fb.map(|fb| { self.inner @@ -538,7 +538,7 @@ 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.0); + data.set_fb_id(crtc.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); @@ -561,11 +561,14 @@ impl SchemeSync for GraphicsSchemeInner { .take(data.count_connectors() as usize) .map(|&id| KmsObjectId(id)) .collect(); - let fb = if data.fb_id() != 0 { - Some(self.objects.get_framebuffer(KmsObjectId(data.fb_id()))?) + let fb_id = if data.fb_id() != 0 { + Some(KmsObjectId(data.fb_id())) } else { None }; + let fb = fb_id + .map(|fb_id| self.objects.get_framebuffer(fb_id)) + .transpose()?; let mode = if data.mode_valid() != 0 { Some(data.mode()) } else { @@ -584,7 +587,7 @@ impl SchemeSync for GraphicsSchemeInner { height: mode.map_or(0, |m| m.vdisplay as u32), }, ); - crtc.lock().unwrap().state.fb_id = KmsObjectId(data.fb_id()); + crtc.lock().unwrap().state.fb_id = fb_id; for connector in connector_ids { self.objects @@ -781,7 +784,7 @@ impl SchemeSync for GraphicsSchemeInner { continue; } let crtc = self.objects.crtcs().nth(display_id).unwrap(); - crtc.lock().unwrap().state.fb_id = KmsObjectId::INVALID; + crtc.lock().unwrap().state.fb_id = None; self.adapter.set_crtc( &self.objects, crtc, @@ -821,7 +824,7 @@ impl SchemeSync for GraphicsSchemeInner { if *vt == self.active_vt { for crtc in self.objects.crtcs() { - if crtc.lock().unwrap().state.fb_id == KmsObjectId(data.fb_id()) { + if crtc.lock().unwrap().state.fb_id == Some(KmsObjectId(data.fb_id())) { let mode = crtc.lock().unwrap().state.mode; self.adapter .set_crtc(&self.objects, crtc, mode, Some(fb), damage); @@ -886,7 +889,14 @@ impl SchemeSync for GraphicsSchemeInner { 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.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) From 6def27936a3e02e3542896c7678c29a164d3c34d Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 20 Mar 2026 21:16:57 +0100 Subject: [PATCH 4/5] drivers/graphics: Pass KmsCrtcState to set_crtc --- .../driver-graphics/src/kms/connector.rs | 12 +- .../driver-graphics/src/kms/objects.rs | 12 +- drivers/graphics/driver-graphics/src/lib.rs | 142 ++++++++++-------- drivers/graphics/ihdgd/src/device/scheme.rs | 17 ++- drivers/graphics/vesad/src/scheme.rs | 17 ++- drivers/graphics/virtio-gpud/src/scheme.rs | 21 ++- 6 files changed, 134 insertions(+), 87 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/kms/connector.rs b/drivers/graphics/driver-graphics/src/kms/connector.rs index 76bf65fa3e..c885f41351 100644 --- a/drivers/graphics/driver-graphics/src/kms/connector.rs +++ b/drivers/graphics/driver-graphics/src/kms/connector.rs @@ -101,13 +101,23 @@ pub struct KmsConnector { pub driver_data: T::Connector, } -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct KmsConnectorState { pub dpms: KmsDpms, pub crtc_id: KmsObjectId, pub driver_data: ::State, } +impl Clone for KmsConnectorState { + fn clone(&self) -> Self { + Self { + dpms: self.dpms.clone(), + crtc_id: self.crtc_id.clone(), + driver_data: self.driver_data.clone(), + } + } +} + define_object_props!(object, KmsConnector { EDID { get => u64::from(object.edid.0), diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index 5958257c64..1daf32212d 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -206,13 +206,23 @@ pub struct KmsCrtc { pub driver_data: T::Crtc, } -#[derive(Debug, Clone)] +#[derive(Debug)] pub struct KmsCrtcState { pub fb_id: Option, pub mode: Option, pub driver_data: ::State, } +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(), + } + } +} + define_object_props!(object, KmsCrtc {}); #[derive(Debug)] diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 4949c5fae1..22db654381 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -10,9 +10,9 @@ use std::{cmp, mem}; use drm_fourcc::DrmFourcc; use drm_sys::{ - drm_mode_modeinfo, drm_mode_property_enum, DRM_MODE_CURSOR_BO, DRM_MODE_CURSOR_MOVE, - DRM_MODE_PROP_ATOMIC, DRM_MODE_PROP_BITMASK, DRM_MODE_PROP_BLOB, DRM_MODE_PROP_ENUM, - DRM_MODE_PROP_IMMUTABLE, DRM_MODE_PROP_OBJECT, DRM_MODE_PROP_RANGE, DRM_MODE_PROP_SIGNED_RANGE, + drm_mode_property_enum, DRM_MODE_CURSOR_BO, DRM_MODE_CURSOR_MOVE, DRM_MODE_PROP_ATOMIC, + DRM_MODE_PROP_BITMASK, DRM_MODE_PROP_BLOB, DRM_MODE_PROP_ENUM, DRM_MODE_PROP_IMMUTABLE, + DRM_MODE_PROP_OBJECT, DRM_MODE_PROP_RANGE, DRM_MODE_PROP_SIGNED_RANGE, }; use inputd::{DisplayHandle, VtEventKind}; use libredox::Fd; @@ -21,8 +21,8 @@ use redox_scheme::{CallerCtx, OpenResult, RequestKind, SignalBehavior, Socket}; use syscall::schemev2::NewFdFlags; use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EBADF, EINVAL, ENOENT, EOPNOTSUPP}; -use crate::kms::connector::{self, KmsConnectorDriver}; -use crate::kms::objects::{self, KmsCrtc, KmsCrtcDriver, KmsObjectId, KmsObjects}; +use crate::kms::connector::{KmsConnectorDriver, KmsConnectorState}; +use crate::kms::objects::{self, KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects}; use crate::kms::properties::KmsPropertyKind; pub mod kms; @@ -103,10 +103,9 @@ pub trait GraphicsAdapter: Sized + Debug { &mut self, objects: &KmsObjects, crtc: &Mutex>, - mode: Option, - framebuffer: Option<&objects::KmsFramebuffer>, + new_state: KmsCrtcState, damage: Damage, - ); + ) -> syscall::Result<()>; fn hw_cursor_size(&self) -> Option<(u32, u32)>; fn handle_cursor(&mut self, cursor: &CursorPlane, dirty_fb: bool); @@ -236,34 +235,46 @@ impl GraphicsScheme { vt_event.vt, ); - for (display_id, fb) in vt_state.display_fbs.iter().enumerate() { - let crtc_id = self.inner.objects.crtc_ids()[display_id]; + for (connector_idx, connector_state) in + vt_state.connector_state.iter().enumerate() + { + let connector_id = self.inner.objects.connector_ids()[connector_idx]; + let mut connector = self + .inner + .objects + .get_connector(connector_id) + .unwrap() + .lock() + .unwrap(); + connector.state = connector_state.clone(); + } + + for (crtc_idx, crtc_state) in vt_state.crtc_state.iter().enumerate() { + let crtc_id = self.inner.objects.crtc_ids()[crtc_idx]; let crtc = self.inner.objects.get_crtc(crtc_id).unwrap(); - let connector_id = self.inner.objects.connector_ids()[display_id]; + let connector_id = self.inner.objects.connector_ids()[crtc_idx]; - crtc.lock().unwrap().state.fb_id = *fb; - - let fb = fb.map(|fb| { + let fb = crtc_state.fb_id.map(|fb_id| { self.inner .objects - .get_framebuffer(fb) + .get_framebuffer(fb_id) .expect("removed framebuffers should be unset") }); - let mode = fb.map(|fb| connector::modeinfo_for_size(fb.width, fb.height)); - - self.inner.adapter.set_crtc( - &self.inner.objects, - crtc, - mode, - fb, - Damage { - x: 0, - y: 0, - width: fb.map_or(0, |fb| fb.width), - height: fb.map_or(0, |fb| fb.height), - }, - ); + self.inner + .adapter + .set_crtc( + &self.inner.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), + }, + ) + .unwrap(); self.inner .objects @@ -343,7 +354,8 @@ struct GraphicsSchemeInner { } struct VtState { - display_fbs: Vec>, + connector_state: Vec>, + crtc_state: Vec>, cursor_plane: CursorPlane, } @@ -363,7 +375,14 @@ impl GraphicsSchemeInner { vt: usize, ) -> &'a mut VtState { vts.entry(vt).or_insert_with(|| VtState { - display_fbs: vec![None; objects.crtc_ids().len()], + connector_state: objects + .connectors() + .map(|connector| connector.lock().unwrap().state.clone()) + .collect(), + crtc_state: objects + .crtcs() + .map(|crtc| crtc.lock().unwrap().state.clone()) + .collect(), cursor_plane: CursorPlane { x: 0, y: 0, @@ -554,7 +573,6 @@ impl SchemeSync for GraphicsSchemeInner { }), ipc::MODE_SET_CRTC => ipc::DrmModeCrtc::with(payload, |data| { let crtc = self.objects.get_crtc(KmsObjectId(data.crtc_id()))?; - let display_id = crtc.lock().unwrap().crtc_index as usize; let connector_ids: Vec = data .set_connectors_ptr() .iter() @@ -566,28 +584,26 @@ impl SchemeSync for GraphicsSchemeInner { } else { None }; - let fb = fb_id - .map(|fb_id| self.objects.get_framebuffer(fb_id)) - .transpose()?; let mode = if data.mode_valid() != 0 { Some(data.mode()) } else { None }; + let mut new_state = crtc.lock().unwrap().state.clone(); + new_state.fb_id = fb_id; + new_state.mode = mode; if *vt == self.active_vt { self.adapter.set_crtc( &self.objects, crtc, - mode, - fb, + new_state.clone(), Damage { x: data.x(), y: data.y(), width: mode.map_or(0, |m| m.hdisplay as u32), height: mode.map_or(0, |m| m.vdisplay as u32), }, - ); - crtc.lock().unwrap().state.fb_id = fb_id; + )?; for connector in connector_ids { self.objects @@ -598,11 +614,8 @@ impl SchemeSync for GraphicsSchemeInner { .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())) - } else { - None - }; + self.vts.get_mut(vt).unwrap().crtc_state + [crtc.lock().unwrap().crtc_index as usize] = new_state; Ok(0) }), ipc::MODE_CURSOR => ipc::DrmModeCursor::with(payload, |data| { @@ -774,29 +787,29 @@ impl SchemeSync for GraphicsSchemeInner { // Disable planes that use this framebuffer. for (vt, vt_data) in &mut self.vts { - for (display_id, fb) in vt_data.display_fbs.iter_mut().enumerate() { - if *fb != Some(fb_id) { + for (crtc_idx, crtc_state) in vt_data.crtc_state.iter_mut().enumerate() { + if crtc_state.fb_id != Some(fb_id) { continue; } - *fb = None; + crtc_state.fb_id = None; if *vt != self.active_vt { continue; } - let crtc = self.objects.crtcs().nth(display_id).unwrap(); - crtc.lock().unwrap().state.fb_id = None; - self.adapter.set_crtc( - &self.objects, - crtc, - None, - None, - Damage { - x: 0, - y: 0, - width: 0, - height: 0, - }, - ); + let crtc = self.objects.crtcs().nth(crtc_idx).unwrap(); + self.adapter + .set_crtc( + &self.objects, + crtc, + crtc_state.clone(), + Damage { + x: 0, + y: 0, + width: 0, + height: 0, + }, + ) + .unwrap(); } } @@ -824,10 +837,9 @@ impl SchemeSync for GraphicsSchemeInner { if *vt == self.active_vt { for crtc in self.objects.crtcs() { - if crtc.lock().unwrap().state.fb_id == Some(KmsObjectId(data.fb_id())) { - let mode = crtc.lock().unwrap().state.mode; - self.adapter - .set_crtc(&self.objects, crtc, mode, Some(fb), damage); + let state = crtc.lock().unwrap().state.clone(); + if state.fb_id == Some(KmsObjectId(data.fb_id())) { + self.adapter.set_crtc(&self.objects, crtc, state, damage)?; } } } diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index f4851a0c5b..0c3a296cd8 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -6,9 +6,9 @@ use std::ptr::{self, NonNull}; use std::sync::Mutex; use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus}; -use driver_graphics::kms::objects::{KmsCrtc, KmsFramebuffer, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects}; use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter}; -use drm_sys::{drm_mode_modeinfo, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; +use drm_sys::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; use syscall::{error::EINVAL, PAGE_SIZE}; use super::Device; @@ -85,12 +85,15 @@ impl GraphicsAdapter for Device { &mut self, objects: &KmsObjects, crtc: &Mutex>, - mode: Option, - buffer: Option<&KmsFramebuffer>, + state: KmsCrtcState, damage: Damage, - ) { + ) -> syscall::Result<()> { let mut crtc = crtc.lock().unwrap(); - crtc.state.mode = mode; + let buffer = state + .fb_id + .map(|fb_id| objects.get_framebuffer(fb_id)) + .transpose()?; + crtc.state = state; for connector in objects.connectors() { let connector = connector.lock().unwrap(); @@ -117,6 +120,8 @@ impl GraphicsAdapter for Device { } } } + + Ok(()) } fn hw_cursor_size(&self) -> Option<(u32, u32)> { diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 8905460282..d1dd1a99c0 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -4,9 +4,9 @@ use std::ptr::{self, NonNull}; use std::sync::Mutex; use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus}; -use driver_graphics::kms::objects::{KmsCrtc, KmsFramebuffer, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects}; use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter}; -use drm_sys::{drm_mode_modeinfo, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; +use drm_sys::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; use syscall::{EINVAL, PAGE_SIZE}; #[derive(Debug)] @@ -93,12 +93,15 @@ impl GraphicsAdapter for FbAdapter { &mut self, objects: &KmsObjects, crtc: &Mutex>, - mode: Option, - buffer: Option<&KmsFramebuffer>, + state: KmsCrtcState, damage: Damage, - ) { + ) -> syscall::Result<()> { let mut crtc = crtc.lock().unwrap(); - crtc.state.mode = mode; + let buffer = state + .fb_id + .map(|fb_id| objects.get_framebuffer(fb_id)) + .transpose()?; + crtc.state = state; for connector in objects.connectors() { let connector = connector.lock().unwrap(); @@ -125,6 +128,8 @@ impl GraphicsAdapter for FbAdapter { } } } + + Ok(()) } fn hw_cursor_size(&self) -> Option<(u32, u32)> { diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index 91dc1c8ef3..1b6e48d412 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -3,10 +3,10 @@ use std::sync::{Arc, Mutex}; use common::{dma::Dma, sgl}; use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus}; -use driver_graphics::kms::objects::{KmsCrtc, KmsFramebuffer, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects}; use driver_graphics::{Buffer as DrmBuffer, CursorPlane, Damage, GraphicsAdapter, GraphicsScheme}; use drm_sys::{ - drm_mode_modeinfo, DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_CAP_DUMB_BUFFER, + DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT, }; @@ -406,13 +406,16 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { &mut self, objects: &KmsObjects, crtc: &Mutex>, - mode: Option, - framebuffer: Option<&KmsFramebuffer>, + state: KmsCrtcState, damage: Damage, - ) { + ) -> syscall::Result<()> { futures::executor::block_on(async { let mut crtc = crtc.lock().unwrap(); - crtc.state.mode = mode; + let framebuffer = state + .fb_id + .map(|fb_id| objects.get_framebuffer(fb_id)) + .transpose()?; + crtc.state = state; for connector in objects.connectors() { let connector = connector.lock().unwrap(); @@ -433,7 +436,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { 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; + return Ok(()); }; let req = Dma::new(XferToHost2d::new( @@ -472,7 +475,9 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { let header = self.send_request(Dma::new(flush).unwrap()).await.unwrap(); assert_eq!(header.ty, CommandTy::RespOkNodata); } - }); + + Ok(()) + }) } fn hw_cursor_size(&self) -> Option<(u32, u32)> { From f5ce77203e876b1883921a84b49bf41c55106c80 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 15 Mar 2026 16:02:55 +0100 Subject: [PATCH 5/5] drivers/graphics/ihdgd: Initialize planes inside GraphicsAdapter::init --- drivers/graphics/ihdgd/src/device/mod.rs | 30 ++++++++------------- drivers/graphics/ihdgd/src/device/scheme.rs | 2 ++ 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/drivers/graphics/ihdgd/src/device/mod.rs b/drivers/graphics/ihdgd/src/device/mod.rs index e71b832a80..d04e394358 100644 --- a/drivers/graphics/ihdgd/src/device/mod.rs +++ b/drivers/graphics/ihdgd/src/device/mod.rs @@ -404,7 +404,7 @@ impl Device { let buffers = 1024; //TODO: how to use 64-bit surface addresses? let surface_memory = gm.size.min(u32::max_value() as usize) as u32; - let mut this = Self { + Ok(Self { kind, alloc_buffers: RangeAllocator::new(0..buffers), alloc_surfaces: RangeAllocator::new(0..surface_memory), @@ -422,12 +422,10 @@ impl Device { power_wells, ref_freq, transcoders, - }; - this.init()?; - Ok(this) + }) } - pub fn init(&mut self) -> Result<()> { + pub fn init_inner(&mut self) { // Discover current framebuffers self.alloc_buffers.reset(); self.alloc_surfaces.reset(); @@ -440,15 +438,12 @@ impl Device { let buffer_end = (buf_cfg >> 16) & 0x7FF; self.alloc_buffers .allocate_exact_range(buffer_start..(buffer_end + 1)) - .map_err(|err| { - log::warn!( + .unwrap_or_else(|err| { + panic!( "failed to allocate pre-existing buffer blocks {} to {}: {:?}", - buffer_start, - buffer_end, - err + buffer_start, buffer_end, err ); - Error::new(EIO) - })?; + }); let size = plane.size.read(); let width = (size & 0xFFFF) + 1; @@ -459,10 +454,9 @@ impl Device { let surf = plane.surf.read() & 0xFFFFF000; //TODO: read bits per pixel let surf_size = (stride * height * 4).next_multiple_of(4096); - self.alloc_surfaces.allocate_exact_range(surf .. (surf + surf_size)).map_err(|err| { - log::warn!("failed to allocate pre-existing surface at 0x{:x} of size {}: {:?}", surf, surf_size, err); - Error::new(EIO) - })?; + self.alloc_surfaces.allocate_exact_range(surf .. (surf + surf_size)).unwrap_or_else(|err| { + panic!("failed to allocate pre-existing surface at 0x{:x} of size {}: {:?}", surf, surf_size, err); + }); self.framebuffers.push(unsafe { DeviceFb::new( @@ -480,7 +474,7 @@ impl Device { // Probe all DDIs let ddi_names: Vec<&str> = self.ddis.iter().map(|ddi| ddi.name).collect(); for ddi_name in ddi_names { - self.probe_ddi(ddi_name)?; + self.probe_ddi(ddi_name).expect("failed to probe DDI"); } self.dump(); @@ -517,8 +511,6 @@ impl Device { for change_detect in self.int.change_detects.iter_mut() { change_detect.log(); } - - Ok(()) } pub fn dump(&self) { diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index 0c3a296cd8..b86d8ffcb8 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -38,6 +38,8 @@ impl GraphicsAdapter for Device { } fn init(&mut self, objects: &mut KmsObjects) { + self.init_inner(); + // FIXME enumerate actual connectors for (framebuffer_id, _) in self.framebuffers.iter().enumerate() { let crtc = objects.add_crtc((), ());