From be6ae85541404beb0d5e96a0077969b31644377a Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 11 Mar 2026 22:40:44 +0100 Subject: [PATCH 1/5] drivers/graphics: Implement proper support for framebuffers Including support for creating and destroying framebuffers. --- .../driver-graphics/src/kms/objects.rs | 49 ++++- drivers/graphics/driver-graphics/src/lib.rs | 171 ++++++++++++------ drivers/graphics/ihdgd/src/device/scheme.rs | 11 +- drivers/graphics/vesad/src/scheme.rs | 11 +- drivers/graphics/virtio-gpud/src/scheme.rs | 23 ++- 5 files changed, 197 insertions(+), 68 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index c7b16ebf39..e2850d64b2 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -5,7 +5,7 @@ use std::sync::{Arc, Mutex}; 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_PROPERTY, + DRM_MODE_OBJECT_ENCODER, DRM_MODE_OBJECT_FB, DRM_MODE_OBJECT_PROPERTY, }; use syscall::{Error, Result, EINVAL}; @@ -19,6 +19,7 @@ pub struct KmsObjects { pub(crate) connectors: Vec, pub(crate) encoders: Vec, crtcs: Vec, + framebuffers: Vec, pub(crate) objects: HashMap>>, _marker: PhantomData, } @@ -30,6 +31,7 @@ impl KmsObjects { connectors: vec![], encoders: vec![], crtcs: vec![], + framebuffers: vec![], objects: HashMap::new(), _marker: PhantomData, } @@ -93,6 +95,39 @@ impl KmsObjects { pub fn get_crtc(&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); + id + } + + pub fn remove_framebuffer(&mut self, id: KmsObjectId) -> Result<()> { + let kind = match self.objects.get(&id).map(|object| &**object) { + Some(KmsObjectData { kind, .. }) => kind, + _ => return Err(Error::new(EINVAL)), + }; + let KmsObjectKind::Framebuffer(_) = **kind else { + return Err(Error::new(EINVAL)); + }; + self.objects.remove(&id).unwrap(); + + Ok(()) + } + + pub fn fb_ids(&self) -> &[KmsObjectId] { + &self.framebuffers + } + + pub fn get_framebuffer( + &self, + id: KmsObjectId, + ) -> Result<&KmsFramebuffer> { + self.get(id) + } } #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] @@ -158,6 +193,7 @@ define_object_kinds! { Connector(Mutex>) = DRM_MODE_OBJECT_CONNECTOR, Encoder(KmsEncoder) = DRM_MODE_OBJECT_ENCODER, Property(KmsProperty) = DRM_MODE_OBJECT_PROPERTY, + Framebuffer(KmsFramebuffer) = DRM_MODE_OBJECT_FB, Blob(KmsBlob) = DRM_MODE_OBJECT_BLOB, } @@ -169,3 +205,14 @@ pub struct KmsCrtc { pub mode: Option, pub driver_data: T, } + +#[derive(Debug)] +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, +} diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 40a847b322..5bd5cfe15d 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -26,7 +26,7 @@ use syscall::schemev2::NewFdFlags; use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EBADF, EINVAL, ENOENT, EOPNOTSUPP}; use crate::kms::connector::KmsConnector; -use crate::kms::objects::{KmsCrtc, KmsObjectId, KmsObjects}; +use crate::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; use crate::kms::properties::KmsPropertyKind; pub mod kms; @@ -42,6 +42,7 @@ pub trait GraphicsAdapter: Sized + Debug { type Crtc: Debug; type Buffer: Buffer; + type Framebuffer: Framebuffer; fn name(&self) -> &'static [u8]; fn desc(&self) -> &'static [u8]; @@ -65,7 +66,9 @@ pub trait GraphicsAdapter: Sized + Debug { fn display_size(&self, display_id: usize) -> (u32, u32); fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer; - fn map_dumb_buffer(&mut self, framebuffer: &Self::Buffer) -> *mut u8; + fn map_dumb_buffer(&mut self, buffer: &Self::Buffer) -> *mut u8; + + fn create_framebuffer(&mut self, buffer: &Self::Buffer) -> Self::Framebuffer; fn set_crtc( &mut self, @@ -73,7 +76,7 @@ pub trait GraphicsAdapter: Sized + Debug { crtc: &Mutex>, connectors: &[KmsObjectId], mode: Option, - framebuffer: Option<&Self::Buffer>, + framebuffer: Option<&objects::KmsFramebuffer>, damage: Damage, ); @@ -86,7 +89,10 @@ pub trait Buffer: Debug { fn height(&self) -> u32; } -#[derive(Debug)] +pub trait Framebuffer: Debug {} + +impl Framebuffer for () {} + pub struct CursorPlane { pub x: i32, pub y: i32, @@ -225,21 +231,29 @@ impl GraphicsScheme { for (display_id, fb) in vt_state.display_fbs.iter().enumerate() { let crtc = self.inner.objects.crtcs().nth(display_id).unwrap(); - let mode = fb.as_ref().map(|fb| { - KmsConnector::<()>::modeinfo_for_size(fb.width(), fb.height()) + crtc.lock().unwrap().fb_id = fb.unwrap_or(KmsObjectId::INVALID); + + let fb = fb.map(|fb| { + self.inner + .objects + .get_framebuffer(fb) + .expect("removed framebuffers should be unset") }); + let mode = + fb.map(|fb| KmsConnector::<()>::modeinfo_for_size(fb.width, fb.height)); + self.inner.adapter.set_crtc( &self.inner.objects, crtc, &[self.inner.objects.connector_ids()[display_id]], mode, - fb.as_deref(), + fb, Damage { x: 0, y: 0, - width: fb.as_deref().map_or(0, |fb| fb.width()), - height: fb.as_deref().map_or(0, |fb| fb.height()), + width: fb.map_or(0, |fb| fb.width), + height: fb.map_or(0, |fb| fb.height), }, ); } @@ -313,7 +327,7 @@ struct GraphicsSchemeInner { } struct VtState { - display_fbs: Vec>>, + display_fbs: Vec>, cursor_plane: CursorPlane, } @@ -454,14 +468,6 @@ impl SchemeSync for GraphicsSchemeInner { id & 0xFF } - fn fb_id(i: u32) -> u32 { - id_index(i) | (1 << 11) - } - - fn fb_handle_id(i: u32) -> u32 { - id_index(i) | (1 << 12) - } - fn plane_id(i: u32) -> u32 { id_index(i) | (1 << 13) } @@ -504,7 +510,6 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), ipc::MODE_CARD_RES => ipc::DrmModeCardRes::with(payload, |mut data| { - let count = self.adapter.display_count(); let conn_ids = self .objects .connector_ids() @@ -523,10 +528,12 @@ impl SchemeSync for GraphicsSchemeInner { .iter() .map(|id| id.0) .collect::>(); - let mut fb_ids = Vec::with_capacity(count); - for i in 0..(count as u32) { - fb_ids.push(fb_id(i)); - } + let fb_ids = self + .objects + .fb_ids() + .iter() + .map(|id| id.0) + .collect::>(); data.set_fb_id_ptr(&fb_ids); data.set_crtc_id_ptr(&crtc_ids); data.set_connector_id_ptr(&conn_ids); @@ -711,18 +718,71 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), ipc::MODE_GET_FB => ipc::DrmModeFbCmd::with(payload, |mut data| { - let i = id_index(data.fb_id()); - let (width, height) = self.adapter.display_size(i as usize); - data.set_width(width); - data.set_height(height); - data.set_pitch(width * 4); //TODO: stride - data.set_bpp(32); - data.set_depth(24); - data.set_handle(fb_handle_id(i)); + let fb = self.objects.get_framebuffer(KmsObjectId(data.fb_id()))?; + + *next_id += 1; + buffers.insert(*next_id, fb.buffer.clone()); + + data.set_width(fb.width); + data.set_height(fb.height); + data.set_pitch(fb.pitch); + data.set_bpp(fb.bpp); + data.set_depth(fb.depth); + data.set_handle(*next_id); Ok(0) }), ipc::MODE_ADD_FB => ipc::DrmModeFbCmd::with(payload, |mut data| { - data.set_fb_id(fb_handle_id(data.handle())); + let buffer = buffers.get(&data.handle()).ok_or(Error::new(EINVAL))?; + + let fb = self.adapter.create_framebuffer(buffer); + + let id = self.objects.add_framebuffer(objects::KmsFramebuffer { + width: data.width(), + height: data.height(), + pitch: data.pitch(), + bpp: data.bpp(), + depth: data.depth(), + buffer: buffer.clone(), + driver_data: fb, + }); + + data.set_fb_id(id.0); + + Ok(0) + }), + ipc::MODE_RM_FB => ipc::StandinForUint::with(payload, |data| { + let fb_id = KmsObjectId(data.inner()); + self.objects.remove_framebuffer(fb_id)?; + + // 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) { + continue; + } + *fb = None; + + if *vt != self.active_vt { + continue; + } + let crtc = self.objects.crtcs().nth(display_id).unwrap(); + crtc.lock().unwrap().fb_id = KmsObjectId::INVALID; + self.adapter.set_crtc( + &self.objects, + crtc, + &[self.objects.connector_ids()[display_id]], + None, + None, + Damage { + x: 0, + y: 0, + width: 0, + height: 0, + }, + ); + } + } + Ok(0) }), ipc::MODE_CREATE_DUMB => ipc::DrmModeCreateDumb::with(payload, |mut data| { @@ -730,10 +790,10 @@ impl SchemeSync for GraphicsSchemeInner { return Err(Error::new(EINVAL)); } - let fb = self.adapter.create_dumb_buffer(data.width(), data.height()); + let buffer = self.adapter.create_dumb_buffer(data.width(), data.height()); *next_id += 1; - buffers.insert(*next_id, Arc::new(fb)); + buffers.insert(*next_id, Arc::new(buffer)); data.set_handle(*next_id as u32); data.set_pitch(data.width() * 4); data.set_size(u64::from(data.width()) * u64::from(data.height()) * 4); @@ -777,8 +837,10 @@ impl SchemeSync for GraphicsSchemeInner { }), ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| { let i = id_index(data.plane_id()); - data.set_crtc_id(self.objects.crtc_ids()[i as usize].0); - data.set_fb_id(fb_id(i)); + 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().fb_id.0); data.set_possible_crtcs(1 << i); data.set_format_type_ptr(&[DRM_FORMAT_ARGB8888]); Ok(0) @@ -833,13 +895,16 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), ipc::MODE_GET_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| { - let i = id_index(data.fb_id()); - let (width, height) = self.adapter.display_size(i as usize); - data.set_width(width); - data.set_height(height); + let fb = self.objects.get_framebuffer(KmsObjectId(data.fb_id()))?; + + *next_id += 1; + buffers.insert(*next_id, fb.buffer.clone()); + + data.set_width(fb.width); + data.set_height(fb.height); data.set_pixel_format(DRM_FORMAT_ARGB8888); - data.set_handles([fb_handle_id(i), 0, 0, 0]); - data.set_pitches([width * 4, 0, 0, 0]); + data.set_handles([*next_id, 0, 0, 0]); + data.set_pitches([fb.width * 4, 0, 0, 0]); data.set_offsets([0; 4]); data.set_modifier([0; 4]); Ok(0) @@ -859,28 +924,30 @@ impl SchemeSync for GraphicsSchemeInner { return Err(Error::new(EINVAL)); }; - let framebuffer = if payload.fb_id == 0 { + let fb = if payload.fb_id == 0 { None - } else if let Some(framebuffer) = buffers.get(&id_index(payload.fb_id)) { - Some(framebuffer) } else { - return Err(Error::new(EINVAL)); + Some(self.objects.get_framebuffer(KmsObjectId(payload.fb_id))?) }; - self.vts.get_mut(vt).unwrap().display_fbs[display_id] = - framebuffer.map(Arc::clone); + self.vts.get_mut(vt).unwrap().display_fbs[display_id] = if payload.fb_id == 0 { + None + } else { + Some(KmsObjectId(payload.fb_id)) + }; if *vt == self.active_vt { - let mode = framebuffer.as_ref().map(|fb| { - KmsConnector::<()>::modeinfo_for_size(fb.width(), fb.height()) - }); + crtc.lock().unwrap().fb_id = KmsObjectId(payload.fb_id); + + let mode = + fb.map(|fb| KmsConnector::<()>::modeinfo_for_size(fb.width, fb.height)); self.adapter.set_crtc( &self.objects, crtc, &[self.objects.connector_ids()[display_id]], mode, - framebuffer.map(|fb| &**fb), + fb, payload.damage, ); } diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index 287aa31dea..448e712e5a 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::KmsConnectorStatus; -use driver_graphics::kms::objects::{KmsCrtc, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter, StandardProperties}; use drm_sys::{drm_mode_modeinfo, DRM_MODE_DPMS_ON}; use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; @@ -25,6 +25,7 @@ impl GraphicsAdapter for Device { type Crtc = (); type Buffer = DumbFb; + type Framebuffer = (); fn name(&self) -> &'static [u8] { b"ihdgd" @@ -95,13 +96,17 @@ impl GraphicsAdapter for Device { framebuffer.ptr.as_ptr().cast::() } + fn create_framebuffer(&mut self, _buffer: &Self::Buffer) -> Self::Framebuffer { + () + } + fn set_crtc( &mut self, objects: &KmsObjects, crtc: &Mutex>, connectors: &[KmsObjectId], mode: Option, - buffer: Option<&Self::Buffer>, + buffer: Option<&objects::KmsFramebuffer>, damage: Damage, ) { crtc.lock().unwrap().mode = mode; @@ -116,7 +121,7 @@ impl GraphicsAdapter for Device { let framebuffer = &mut self.framebuffers[framebuffer_id]; if let Some(buffer) = buffer { - buffer.sync(framebuffer, damage) + 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 { diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 6aa1cfc559..997bea88f4 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::KmsConnectorStatus; -use driver_graphics::kms::objects::{KmsCrtc, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter, StandardProperties}; use drm_sys::{drm_mode_modeinfo, DRM_MODE_DPMS_ON}; use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; @@ -28,6 +28,7 @@ impl GraphicsAdapter for FbAdapter { type Crtc = (); type Buffer = GraphicScreen; + type Framebuffer = (); fn name(&self) -> &'static [u8] { b"vesad" @@ -102,13 +103,17 @@ impl GraphicsAdapter for FbAdapter { framebuffer.ptr.as_ptr().cast::() } + fn create_framebuffer(&mut self, _buffer: &Self::Buffer) -> Self::Framebuffer { + () + } + fn set_crtc( &mut self, objects: &KmsObjects, crtc: &Mutex>, connectors: &[KmsObjectId], mode: Option, - buffer: Option<&Self::Buffer>, + buffer: Option<&objects::KmsFramebuffer>, damage: Damage, ) { crtc.lock().unwrap().mode = mode; @@ -123,7 +128,7 @@ impl GraphicsAdapter for FbAdapter { let framebuffer = &mut self.framebuffers[framebuffer_id]; if let Some(buffer) = buffer { - buffer.sync(framebuffer, damage) + 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 { diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index 8c12e6085d..e2bec4f8d9 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::KmsConnectorStatus; -use driver_graphics::kms::objects::{KmsCrtc, KmsObjectId, KmsObjects}; +use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; use driver_graphics::{ Buffer as DrmBuffer, CursorPlane, GraphicsAdapter, GraphicsScheme, StandardProperties, }; @@ -269,6 +269,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { type Crtc = (); type Buffer = VirtGpuFramebuffer<'a>; + type Framebuffer = (); fn name(&self) -> &'static [u8] { b"virtio-gpud" @@ -414,8 +415,12 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { }) } - fn map_dumb_buffer(&mut self, framebuffer: &Self::Buffer) -> *mut u8 { - framebuffer.sgl.as_ptr() + fn map_dumb_buffer(&mut self, buffer: &Self::Buffer) -> *mut u8 { + buffer.sgl.as_ptr() + } + + fn create_framebuffer(&mut self, _buffer: &Self::Buffer) -> Self::Framebuffer { + () } fn set_crtc( @@ -424,7 +429,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { crtc: &Mutex>, connectors: &[KmsObjectId], mode: Option, - framebuffer: Option<&Self::Buffer>, + framebuffer: Option<&objects::KmsFramebuffer>, damage: Damage, ) { futures::executor::block_on(async { @@ -452,7 +457,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { }; let req = Dma::new(XferToHost2d::new( - framebuffer.id, + framebuffer.buffer.id, GpuRect { x: 0, y: 0, @@ -466,20 +471,20 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { 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.id) { + if self.displays[display_id as usize].active_resource != Some(framebuffer.buffer.id) { let scanout_request = Dma::new(SetScanout::new( display_id, - framebuffer.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.id); + self.displays[display_id as usize].active_resource = Some(framebuffer.buffer.id); } let flush = ResourceFlush::new( - framebuffer.id, + framebuffer.buffer.id, damage.clip(framebuffer.width, framebuffer.height).into(), ); let header = self.send_request(Dma::new(flush).unwrap()).await.unwrap(); From d7974b31438efd6094544fe25f3859751862d670 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 15 Mar 2026 12:24:48 +0100 Subject: [PATCH 2/5] drivers/graphics: Nicer way to define standard properties All standard properties are now pre-allocated at KmsObjects creation and given a fixed object id. --- .../driver-graphics/src/kms/objects.rs | 8 +- .../driver-graphics/src/kms/properties.rs | 80 ++++++++++++++++++- drivers/graphics/driver-graphics/src/lib.rs | 49 ++---------- drivers/graphics/ihdgd/src/device/scheme.rs | 18 ++--- drivers/graphics/vesad/src/scheme.rs | 18 ++--- drivers/graphics/virtio-gpud/src/main.rs | 3 +- drivers/graphics/virtio-gpud/src/scheme.rs | 24 ++---- 7 files changed, 109 insertions(+), 91 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index e2850d64b2..3587a94b71 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -10,7 +10,7 @@ use drm_sys::{ use syscall::{Error, Result, EINVAL}; use crate::kms::connector::{KmsConnector, KmsEncoder}; -use crate::kms::properties::{KmsBlob, KmsProperty}; +use crate::kms::properties::{init_standard_props, KmsBlob, KmsProperty}; use crate::GraphicsAdapter; #[derive(Debug)] @@ -26,7 +26,7 @@ pub struct KmsObjects { impl KmsObjects { pub(crate) fn new() -> Self { - KmsObjects { + let mut objects = KmsObjects { next_id: KmsObjectId(1), connectors: vec![], encoders: vec![], @@ -34,7 +34,9 @@ impl KmsObjects { framebuffers: vec![], objects: HashMap::new(), _marker: PhantomData, - } + }; + init_standard_props(&mut objects); + objects } pub(crate) fn add>>(&mut self, data: U) -> KmsObjectId { diff --git a/drivers/graphics/driver-graphics/src/kms/properties.rs b/drivers/graphics/driver-graphics/src/kms/properties.rs index 5fe606ac41..732d77cec1 100644 --- a/drivers/graphics/driver-graphics/src/kms/properties.rs +++ b/drivers/graphics/driver-graphics/src/kms/properties.rs @@ -2,7 +2,10 @@ use std::ffi::c_char; use std::fmt::Debug; use std::sync::Mutex; -use drm_sys::DRM_PROP_NAME_LEN; +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, +}; use syscall::{Error, Result, EINVAL}; use crate::kms::objects::{KmsObjectId, KmsObjects}; @@ -115,3 +118,78 @@ pub enum KmsPropertyKind { pub struct KmsBlob { data: Vec, } + +macro_rules! define_properties { + ($($prop:ident $($prop_name:literal)?: $prop_type:ident $({$($prop_content:tt)*})? [$($prop_flag:ident)?],)*) => { + $(#[allow(non_upper_case_globals)] pub const $prop: KmsObjectId = KmsObjectId(1 + ${index()});)* + + pub(super) fn init_standard_props(objects: &mut KmsObjects) { + $( + assert_eq!(objects.add_property( + define_properties!(@prop_name $prop $($prop_name)?), + define_properties!(@is_immutable $($prop_flag)?), + define_properties!(@is_atomic $($prop_flag)?), + define_properties!(@prop_kind $prop_type $({$($prop_content)*})?), + ), $prop); + )* + } + }; + (@prop_name $prop:ident $prop_name:literal) => { $prop_name }; + (@prop_name $prop:ident) => { stringify!($prop) }; + (@is_immutable) => { false }; + (@is_immutable immutable) => { true }; + (@is_immutable atomic) => { false }; + (@is_atomic) => { false }; + (@is_atomic immutable) => { false }; + (@is_atomic atomic) => { true }; + (@prop_kind range { $start:expr, $end:expr }) => { + KmsPropertyKind::Range($start, $end) + }; + (@prop_kind enum { $($variant:ident = $value:expr,)* }) => { + KmsPropertyKind::Enum(vec![$((stringify!($variant), $value)),*]) + }; + (@prop_kind blob) => { + KmsPropertyKind::Blob + }; + (@prop_kind object) => { + KmsPropertyKind::Object + }; + (@prop_kind srange { $start:expr, $end:expr }) => { + KmsPropertyKind::SignedRange($start, $end) + }; +} + +define_properties! { + // Connector + Plane + CRTC_ID: object [atomic], + + // Connector + EDID: blob [immutable], + DPMS: enum { + On = u64::from(DRM_MODE_DPMS_ON), + Standby = u64::from(DRM_MODE_DPMS_STANDBY), + Suspend = u64::from(DRM_MODE_DPMS_SUSPEND), + Off = u64::from(DRM_MODE_DPMS_OFF), + } [], + + // CRTC + ACTIVE: range { 0,1 } [atomic], + MODE_ID: blob [atomic], + + // Plane + type_ "type": enum { + Overlay = u64::from(DRM_PLANE_TYPE_OVERLAY), + Primary = u64::from(DRM_PLANE_TYPE_PRIMARY), + Cursor = u64::from(DRM_PLANE_TYPE_CURSOR), + } [immutable], + FB_ID: object [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], + CRTC_H: range { 0, u64::from(u32::MAX) } [atomic], + SRC_X: range { 0, u64::from(u32::MAX) } [atomic], + SRC_Y: range { 0, u64::from(u32::MAX) } [atomic], + SRC_W: range { 0, u64::from(u32::MAX) } [atomic], + SRC_H: range { 0, u64::from(u32::MAX) } [atomic], + FB_DAMAGE_CLIPS: blob [atomic], +} diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 5bd5cfe15d..96aa44affa 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -1,3 +1,4 @@ +#![feature(macro_metavar_expr)] #![feature(slice_as_array)] use std::collections::{BTreeMap, HashMap}; @@ -12,7 +13,6 @@ use std::sync::{Arc, Mutex}; use drm_sys::{ drm_mode_modeinfo, drm_mode_property_enum, DRM_MODE_CURSOR_BO, DRM_MODE_CURSOR_MOVE, - DRM_MODE_DPMS_OFF, DRM_MODE_DPMS_ON, DRM_MODE_DPMS_STANDBY, DRM_MODE_DPMS_SUSPEND, 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_PROP_NAME_LEN, @@ -31,12 +31,6 @@ use crate::kms::properties::KmsPropertyKind; pub mod kms; -#[derive(Debug, Copy, Clone)] -pub struct StandardProperties { - pub edid: KmsObjectId, - pub dpms: KmsObjectId, -} - pub trait GraphicsAdapter: Sized + Debug { type Connector: Debug; type Crtc: Debug; @@ -47,17 +41,12 @@ pub trait GraphicsAdapter: Sized + Debug { fn name(&self) -> &'static [u8]; fn desc(&self) -> &'static [u8]; - fn init(&mut self, objects: &mut KmsObjects, standard_properties: &StandardProperties); + fn init(&mut self, objects: &mut KmsObjects); fn get_cap(&self, cap: u32) -> Result; fn set_client_cap(&self, cap: u32, value: u64) -> Result<()>; - fn probe_connector( - &mut self, - objects: &mut KmsObjects, - standard_properties: &StandardProperties, - id: KmsObjectId, - ); + fn probe_connector(&mut self, objects: &mut KmsObjects, id: KmsObjectId); /// The maximum amount of displays that could be attached. /// @@ -118,24 +107,9 @@ impl GraphicsScheme { ); let mut objects = KmsObjects::new(); - - let edid = objects.add_property("EDID", true, false, KmsPropertyKind::Blob); - let dpms = objects.add_property( - "DPMS", - false, - false, - KmsPropertyKind::Enum(vec![ - ("On", DRM_MODE_DPMS_ON.into()), - ("Standby", DRM_MODE_DPMS_STANDBY.into()), - ("Suspend", DRM_MODE_DPMS_SUSPEND.into()), - ("Off", DRM_MODE_DPMS_OFF.into()), - ]), - ); - let standard_properties = StandardProperties { edid, dpms }; - - adapter.init(&mut objects, &standard_properties); + adapter.init(&mut objects); for connector_id in objects.connector_ids().to_vec() { - adapter.probe_connector(&mut objects, &standard_properties, connector_id) + adapter.probe_connector(&mut objects, connector_id) } let mut inner = GraphicsSchemeInner { @@ -144,7 +118,6 @@ impl GraphicsScheme { disable_graphical_debug, socket, objects, - standard_properties, next_id: 0, handles: BTreeMap::new(), active_vt: 0, @@ -196,10 +169,6 @@ impl GraphicsScheme { (&mut self.inner.adapter, &mut self.inner.objects) } - pub fn standard_properties(&self) -> StandardProperties { - self.inner.standard_properties - } - pub fn handle_vt_events(&mut self) { while let Some(vt_event) = self .inputd_handle @@ -318,7 +287,6 @@ struct GraphicsSchemeInner { disable_graphical_debug: Option, socket: Socket, objects: KmsObjects, - standard_properties: StandardProperties, next_id: usize, handles: BTreeMap>, @@ -599,11 +567,8 @@ impl SchemeSync for GraphicsSchemeInner { }), ipc::MODE_GET_CONNECTOR => ipc::DrmModeGetConnector::with(payload, |mut data| { if data.count_modes() == 0 { - self.adapter.probe_connector( - &mut self.objects, - &self.standard_properties, - KmsObjectId(data.connector_id()), - ); + self.adapter + .probe_connector(&mut self.objects, KmsObjectId(data.connector_id())); } let connector = self .objects diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index 448e712e5a..704bdebba2 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -7,7 +7,8 @@ use std::sync::Mutex; use driver_graphics::kms::connector::KmsConnectorStatus; use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; -use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter, StandardProperties}; +use driver_graphics::kms::properties::DPMS; +use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter}; use drm_sys::{drm_mode_modeinfo, DRM_MODE_DPMS_ON}; use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; use graphics_ipc::v2::Damage; @@ -35,17 +36,13 @@ impl GraphicsAdapter for Device { b"Intel HD Graphics" } - fn init(&mut self, objects: &mut KmsObjects, standard_properties: &StandardProperties) { + fn init(&mut self, objects: &mut KmsObjects) { // FIXME enumerate actual connectors for (framebuffer_id, _) in self.framebuffers.iter().enumerate() { let crtc = objects.add_crtc(()); let connector = objects.add_connector(Connector { framebuffer_id }, &[crtc]); - objects.add_object_property( - connector, - standard_properties.dpms, - DRM_MODE_DPMS_ON.into(), - ); + objects.add_object_property(connector, DPMS, DRM_MODE_DPMS_ON.into()); } } @@ -64,12 +61,7 @@ impl GraphicsAdapter for Device { } } - fn probe_connector( - &mut self, - objects: &mut KmsObjects, - _standard_properties: &StandardProperties, - id: KmsObjectId, - ) { + fn probe_connector(&mut self, objects: &mut KmsObjects, id: KmsObjectId) { let mut connector = objects.get_connector(id).unwrap().lock().unwrap(); let framebuffer = &self.framebuffers[connector.driver_data.framebuffer_id]; connector.connection = KmsConnectorStatus::Connected; diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 997bea88f4..cbb28d6cae 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -5,7 +5,8 @@ use std::sync::Mutex; use driver_graphics::kms::connector::KmsConnectorStatus; use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; -use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter, StandardProperties}; +use driver_graphics::kms::properties::DPMS; +use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter}; use drm_sys::{drm_mode_modeinfo, DRM_MODE_DPMS_ON}; use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; use graphics_ipc::v2::Damage; @@ -38,7 +39,7 @@ impl GraphicsAdapter for FbAdapter { b"VESA" } - fn init(&mut self, objects: &mut KmsObjects, standard_properties: &StandardProperties) { + fn init(&mut self, objects: &mut KmsObjects) { for (framebuffer_id, framebuffer) in self.framebuffers.iter().enumerate() { let crtc = objects.add_crtc(()); @@ -50,11 +51,7 @@ impl GraphicsAdapter for FbAdapter { }, &[crtc], ); - objects.add_object_property( - connector, - standard_properties.dpms, - DRM_MODE_DPMS_ON.into(), - ); + objects.add_object_property(connector, DPMS, DRM_MODE_DPMS_ON.into()); } } @@ -72,12 +69,7 @@ impl GraphicsAdapter for FbAdapter { } } - fn probe_connector( - &mut self, - objects: &mut KmsObjects, - _standard_properties: &StandardProperties, - id: KmsObjectId, - ) { + fn probe_connector(&mut self, objects: &mut KmsObjects, id: KmsObjectId) { let mut connector = objects.get_connector(id).unwrap().lock().unwrap(); let connector = &mut *connector; connector.connection = KmsConnectorStatus::Connected; diff --git a/drivers/graphics/virtio-gpud/src/main.rs b/drivers/graphics/virtio-gpud/src/main.rs index 58e6381189..b99c8e2ee2 100644 --- a/drivers/graphics/virtio-gpud/src/main.rs +++ b/drivers/graphics/virtio-gpud/src/main.rs @@ -586,11 +586,10 @@ fn deamon(deamon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> anyhow: let events = scheme.adapter().config.events_read.get(); if events & VIRTIO_GPU_EVENT_DISPLAY != 0 { - let standard_properties = scheme.standard_properties(); let (adapter, objects) = scheme.adapter_and_kms_objects_mut(); futures::executor::block_on(async { adapter.update_displays().await.unwrap() }); for connector_id in objects.connector_ids().to_vec() { - adapter.probe_connector(objects, &standard_properties, connector_id); + adapter.probe_connector(objects, connector_id); } scheme.notify_displays_changed(); scheme diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index e2bec4f8d9..f335a5746f 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -4,9 +4,8 @@ use std::sync::{Arc, Mutex}; use common::{dma::Dma, sgl}; use driver_graphics::kms::connector::KmsConnectorStatus; use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects}; -use driver_graphics::{ - Buffer as DrmBuffer, CursorPlane, GraphicsAdapter, GraphicsScheme, StandardProperties, -}; +use driver_graphics::kms::properties::{DPMS, EDID}; +use driver_graphics::{Buffer as DrmBuffer, CursorPlane, GraphicsAdapter, GraphicsScheme}; use drm_sys::{drm_mode_modeinfo, DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_MODE_DPMS_ON}; use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT}; use graphics_ipc::v2::Damage; @@ -279,7 +278,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { b"VirtIO GPU" } - fn init(&mut self, objects: &mut KmsObjects, standard_properties: &StandardProperties) { + fn init(&mut self, objects: &mut KmsObjects) { futures::executor::block_on(async { self.update_displays().await.unwrap(); }); @@ -289,13 +288,9 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { let connector = objects.add_connector(VirtGpuConnector { display_id }, &[crtc]); if self.has_edid { - objects.add_object_property(connector, standard_properties.edid, 0); + objects.add_object_property(connector, EDID, 0); } - objects.add_object_property( - connector, - standard_properties.dpms, - DRM_MODE_DPMS_ON.into(), - ); + objects.add_object_property(connector, DPMS, DRM_MODE_DPMS_ON.into()); } } @@ -316,12 +311,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { } } - fn probe_connector( - &mut self, - objects: &mut KmsObjects, - standard_properties: &StandardProperties, - id: KmsObjectId, - ) { + fn probe_connector(&mut self, objects: &mut KmsObjects, id: KmsObjectId) { futures::executor::block_on(async { let mut connector = objects.get_connector(id).unwrap().lock().unwrap(); let display = &self.displays[connector.driver_data.display_id as usize]; @@ -338,7 +328,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { drop(connector); let blob = objects.add_blob(display.edid.clone()); - objects.set_object_property(id, standard_properties.edid, blob.into()); + objects.set_object_property(id, EDID, blob.into()); } else { connector.update_from_size(display.width, display.height); } From 460ae0d57c823f50526556e7ee1fd6a294c69f1b Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 15 Mar 2026 13:01:34 +0100 Subject: [PATCH 3/5] drivers/graphics/console-draw: Fix depth for framebuffer --- drivers/graphics/console-draw/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/graphics/console-draw/src/lib.rs b/drivers/graphics/console-draw/src/lib.rs index 7231f71c36..360922f06a 100644 --- a/drivers/graphics/console-draw/src/lib.rs +++ b/drivers/graphics/console-draw/src/lib.rs @@ -21,7 +21,7 @@ impl V2DisplayMap { pub fn new(display_handle: V2GraphicsHandle, width: u32, height: u32) -> io::Result { let mut buffer = display_handle.create_dumb_buffer((width, height), DrmFourcc::Argb8888, 32)?; - let fb = display_handle.add_framebuffer(&buffer, 24, 32)?; + let fb = display_handle.add_framebuffer(&buffer, 32, 32)?; let map = display_handle.map_dumb_buffer(&mut buffer)?; let map = unsafe { mem::transmute::, DumbMapping<'static>>(map) }; From 93a8179d1ffb5fbea80a3432af741407b9791345 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 15 Mar 2026 13:10:25 +0100 Subject: [PATCH 4/5] drivers/graphics: Remove GraphicsAdapter::display_size It is no longer used. --- drivers/graphics/driver-graphics/src/lib.rs | 1 - drivers/graphics/ihdgd/src/device/scheme.rs | 7 ------- drivers/graphics/vesad/src/scheme.rs | 7 ------- drivers/graphics/virtio-gpud/src/scheme.rs | 7 ------- 4 files changed, 22 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 96aa44affa..7ee07e32b5 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -52,7 +52,6 @@ pub trait GraphicsAdapter: Sized + Debug { /// /// This must be constant for the lifetime of the graphics adapter. fn display_count(&self) -> usize; - fn display_size(&self, display_id: usize) -> (u32, u32); fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer; fn map_dumb_buffer(&mut self, buffer: &Self::Buffer) -> *mut u8; diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index 704bdebba2..f8db5adc44 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -73,13 +73,6 @@ impl GraphicsAdapter for Device { self.framebuffers.len() } - fn display_size(&self, display_id: usize) -> (u32, u32) { - ( - self.framebuffers[display_id].width as u32, - self.framebuffers[display_id].height as u32, - ) - } - fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer { DumbFb::new(width as usize, height as usize) } diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index cbb28d6cae..22966ad441 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -80,13 +80,6 @@ impl GraphicsAdapter for FbAdapter { self.framebuffers.len() } - fn display_size(&self, display_id: usize) -> (u32, u32) { - ( - self.framebuffers[display_id].width as u32, - self.framebuffers[display_id].height as u32, - ) - } - fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer { GraphicScreen::new(width as usize, height as usize) } diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index f335a5746f..d81e492b4d 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -339,13 +339,6 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { self.displays.len() } - fn display_size(&self, display_id: usize) -> (u32, u32) { - ( - self.displays[display_id].width, - self.displays[display_id].height, - ) - } - fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer { futures::executor::block_on(async { let bpp = 32; From e27726e8c3e988580bb5943c9c5e65d0a9b0cb61 Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Sun, 15 Mar 2026 13:30:00 +0100 Subject: [PATCH 5/5] drivers/graphics: Remove GraphicsAdapter::display_count --- drivers/graphics/driver-graphics/src/lib.rs | 17 ++++++----------- drivers/graphics/ihdgd/src/device/scheme.rs | 4 ---- drivers/graphics/vesad/src/scheme.rs | 4 ---- drivers/graphics/virtio-gpud/src/scheme.rs | 4 ---- 4 files changed, 6 insertions(+), 23 deletions(-) diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 7ee07e32b5..82406525ab 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -48,11 +48,6 @@ pub trait GraphicsAdapter: Sized + Debug { fn probe_connector(&mut self, objects: &mut KmsObjects, id: KmsObjectId); - /// The maximum amount of displays that could be attached. - /// - /// This must be constant for the lifetime of the graphics adapter. - fn display_count(&self) -> usize; - fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer; fn map_dumb_buffer(&mut self, buffer: &Self::Buffer) -> *mut u8; @@ -191,7 +186,7 @@ impl GraphicsScheme { self.inner.active_vt = vt_event.vt; let vt_state = GraphicsSchemeInner::get_or_create_vt( - &mut self.inner.adapter, + &self.inner.objects, &mut self.inner.vts, vt_event.vt, ); @@ -314,12 +309,12 @@ enum Handle { impl GraphicsSchemeInner { fn get_or_create_vt<'a>( - adapter: &mut T, + objects: &KmsObjects, vts: &'a mut HashMap>, vt: usize, ) -> &'a mut VtState { vts.entry(vt).or_insert_with(|| VtState { - display_fbs: vec![None; adapter.display_count()], + display_fbs: vec![None; objects.crtc_ids().len()], cursor_plane: CursorPlane { x: 0, y: 0, @@ -367,7 +362,7 @@ impl SchemeSync for GraphicsSchemeInner { .map_err(|_| Error::new(EINVAL))?; // Ensure the VT exists such that the rest of the methods can freely access it. - Self::get_or_create_vt(&mut self.adapter, &mut self.vts, vt); + Self::get_or_create_vt(&self.objects, &mut self.vts, vt); Handle::V2 { vt, @@ -381,7 +376,7 @@ impl SchemeSync for GraphicsSchemeInner { let vt = screen.next().unwrap_or("").parse::().unwrap(); let id = screen.next().unwrap_or("").parse::().unwrap_or(0); - if id >= self.adapter.display_count() { + if id >= self.objects.crtc_ids().len() { return Err(Error::new(EINVAL)); } @@ -791,7 +786,7 @@ impl SchemeSync for GraphicsSchemeInner { Ok(0) }), ipc::MODE_GET_PLANE_RES => ipc::DrmModeGetPlaneRes::with(payload, |mut data| { - let count = self.adapter.display_count(); + 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)); diff --git a/drivers/graphics/ihdgd/src/device/scheme.rs b/drivers/graphics/ihdgd/src/device/scheme.rs index f8db5adc44..52cbb218d2 100644 --- a/drivers/graphics/ihdgd/src/device/scheme.rs +++ b/drivers/graphics/ihdgd/src/device/scheme.rs @@ -69,10 +69,6 @@ impl GraphicsAdapter for Device { // FIXME fetch EDID } - fn display_count(&self) -> usize { - self.framebuffers.len() - } - fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer { DumbFb::new(width as usize, height as usize) } diff --git a/drivers/graphics/vesad/src/scheme.rs b/drivers/graphics/vesad/src/scheme.rs index 22966ad441..45c828f2ac 100644 --- a/drivers/graphics/vesad/src/scheme.rs +++ b/drivers/graphics/vesad/src/scheme.rs @@ -76,10 +76,6 @@ impl GraphicsAdapter for FbAdapter { connector.update_from_size(connector.driver_data.width, connector.driver_data.height); } - fn display_count(&self) -> usize { - self.framebuffers.len() - } - fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer { GraphicScreen::new(width as usize, height as usize) } diff --git a/drivers/graphics/virtio-gpud/src/scheme.rs b/drivers/graphics/virtio-gpud/src/scheme.rs index d81e492b4d..8265846d61 100644 --- a/drivers/graphics/virtio-gpud/src/scheme.rs +++ b/drivers/graphics/virtio-gpud/src/scheme.rs @@ -335,10 +335,6 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> { }); } - fn display_count(&self) -> usize { - self.displays.len() - } - fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer { futures::executor::block_on(async { let bpp = 32;