diff --git a/drivers/graphics/driver-graphics/src/kms/connector.rs b/drivers/graphics/driver-graphics/src/kms/connector.rs index bc63ac4d5d..248d9a3b3f 100644 --- a/drivers/graphics/driver-graphics/src/kms/connector.rs +++ b/drivers/graphics/driver-graphics/src/kms/connector.rs @@ -2,13 +2,10 @@ use std::ffi::c_char; use std::fmt::Debug; use std::sync::Mutex; -use drm_sys::{ - drm_mode_modeinfo, DRM_MODE_CONNECTOR_Unknown, DRM_MODE_OBJECT_CONNECTOR, - DRM_MODE_OBJECT_ENCODER, DRM_MODE_TYPE_PREFERRED, -}; +use drm_sys::{drm_mode_modeinfo, DRM_MODE_CONNECTOR_Unknown, DRM_MODE_TYPE_PREFERRED}; use syscall::Result; -use crate::kms::objects::{KmsObject, KmsObjectId, KmsObjects}; +use crate::kms::objects::{KmsObjectId, KmsObjects}; use crate::GraphicsAdapter; impl KmsObjects { @@ -62,7 +59,7 @@ impl KmsObjects { } #[derive(Debug)] -pub struct KmsConnector { +pub struct KmsConnector { pub encoder_id: KmsObjectId, pub modes: Vec, pub connector_type: u32, @@ -74,7 +71,7 @@ pub struct KmsConnector { pub driver_data: T, } -impl KmsConnector { +impl KmsConnector { pub fn update_from_size(&mut self, width: u32, height: u32) { self.modes = vec![Self::modeinfo_for_size(width, height)]; } @@ -175,12 +172,6 @@ pub enum DrmSubpixelOrder { None, } -impl KmsObject for Mutex> { - fn object_type(&self) -> u32 { - DRM_MODE_OBJECT_CONNECTOR - } -} - // FIXME can we represent connector and encoder using a single struct? #[derive(Debug)] pub struct KmsEncoder { @@ -188,9 +179,3 @@ pub struct KmsEncoder { pub possible_crtcs: u32, pub possible_clones: u32, } - -impl KmsObject for KmsEncoder { - fn object_type(&self) -> u32 { - DRM_MODE_OBJECT_ENCODER - } -} diff --git a/drivers/graphics/driver-graphics/src/kms/objects.rs b/drivers/graphics/driver-graphics/src/kms/objects.rs index 2ee80276f4..8c5506a24d 100644 --- a/drivers/graphics/driver-graphics/src/kms/objects.rs +++ b/drivers/graphics/driver-graphics/src/kms/objects.rs @@ -1,11 +1,16 @@ -use std::any::Any; use std::collections::HashMap; use std::fmt::Debug; use std::marker::PhantomData; use std::sync::{Arc, Mutex}; +use drm_sys::{ + DRM_MODE_OBJECT_BLOB, DRM_MODE_OBJECT_CONNECTOR, DRM_MODE_OBJECT_ENCODER, + DRM_MODE_OBJECT_PROPERTY, +}; use syscall::{Error, Result, EINVAL}; +use crate::kms::connector::{KmsConnector, KmsEncoder}; +use crate::kms::properties::{KmsBlob, KmsProperty}; use crate::GraphicsAdapter; #[derive(Debug)] @@ -13,7 +18,7 @@ pub struct KmsObjects { next_id: KmsObjectId, pub(crate) connectors: Vec, pub(crate) encoders: Vec, - pub(crate) objects: HashMap>, + pub(crate) objects: HashMap>>, _marker: PhantomData, } @@ -28,12 +33,12 @@ impl KmsObjects { } } - pub(crate) fn add(&mut self, data: U) -> KmsObjectId { + pub(crate) fn add>>(&mut self, data: U) -> KmsObjectId { let id = self.next_id; self.objects.insert( id, Arc::new(KmsObjectData { - kind: Box::new(data), + kind: Box::new(data.into()), properties: Mutex::new(vec![]), }), ); @@ -42,9 +47,12 @@ impl KmsObjects { id } - pub(crate) fn get(&self, id: KmsObjectId) -> Result<&U> { + pub(crate) fn get<'a, U: 'a>(&'a self, id: KmsObjectId) -> Result<&'a U> + where + &'a U: TryFrom<&'a KmsObjectKind>, + { let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?; - if let Some(object) = (&*object.kind as &dyn Any).downcast_ref::() { + if let Ok(object) = (&*object.kind).try_into() { Ok(object) } else { Err(Error::new(EINVAL)) @@ -71,11 +79,53 @@ impl From for u64 { } #[derive(Debug)] -pub(crate) struct KmsObjectData { - kind: Box, +pub(crate) struct KmsObjectData { + kind: Box>, pub(crate) properties: Mutex>, } -pub trait KmsObject: Any + Debug { - fn object_type(&self) -> u32; +macro_rules! define_object_kinds { + (<$T:ident> $( + $variant:ident($data:ty) = $type:ident, + )*) => { + #[derive(Debug)] + pub(crate) enum KmsObjectKind<$T: GraphicsAdapter> { + $($variant($data),)* + } + + impl<$T: GraphicsAdapter> KmsObjectKind<$T> { + fn object_type(&self) -> u32 { + match self { + $(Self::$variant(_) => $type,)* + } + } + } + + + $( + impl<$T: GraphicsAdapter> From<$data> for KmsObjectKind<$T> { + fn from(value: $data) -> Self { + Self::$variant(value) + } + } + + impl<'a, $T: GraphicsAdapter> TryFrom<&'a KmsObjectKind<$T>> for &'a $data { + type Error = (); + + fn try_from(value: &'a KmsObjectKind) -> Result { + match value { + KmsObjectKind::$variant(data) => Ok(data), + _ => Err(()), + } + } + } + )* + }; +} + +define_object_kinds! { + Connector(Mutex>) = DRM_MODE_OBJECT_CONNECTOR, + Encoder(KmsEncoder) = DRM_MODE_OBJECT_ENCODER, + Property(KmsProperty) = DRM_MODE_OBJECT_PROPERTY, + Blob(KmsBlob) = DRM_MODE_OBJECT_BLOB, } diff --git a/drivers/graphics/driver-graphics/src/kms/properties.rs b/drivers/graphics/driver-graphics/src/kms/properties.rs index ac88b34bd2..5fe606ac41 100644 --- a/drivers/graphics/driver-graphics/src/kms/properties.rs +++ b/drivers/graphics/driver-graphics/src/kms/properties.rs @@ -2,10 +2,10 @@ use std::ffi::c_char; use std::fmt::Debug; use std::sync::Mutex; -use drm_sys::{DRM_MODE_OBJECT_BLOB, DRM_MODE_OBJECT_PROPERTY, DRM_PROP_NAME_LEN}; +use drm_sys::DRM_PROP_NAME_LEN; use syscall::{Error, Result, EINVAL}; -use crate::kms::objects::{KmsObject, KmsObjectId, KmsObjects}; +use crate::kms::objects::{KmsObjectId, KmsObjects}; use crate::GraphicsAdapter; impl KmsObjects { @@ -111,19 +111,7 @@ pub enum KmsPropertyKind { SignedRange(i64, i64), } -impl KmsObject for KmsProperty { - fn object_type(&self) -> u32 { - DRM_MODE_OBJECT_PROPERTY - } -} - #[derive(Debug)] pub struct KmsBlob { data: Vec, } - -impl KmsObject for KmsBlob { - fn object_type(&self) -> u32 { - DRM_MODE_OBJECT_BLOB - } -} diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 3266368b0f..0565fa8f55 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -36,7 +36,7 @@ pub struct StandardProperties { } pub trait GraphicsAdapter: Sized + Debug { - type Connector: Debug + 'static; + type Connector: Debug; type Buffer: Buffer;