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] 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); }