172 lines
4.8 KiB
Rust
172 lines
4.8 KiB
Rust
use std::collections::HashMap;
|
|
|
|
use drm_sys::drm_mode_modeinfo;
|
|
use syscall::{Error, Result, EINVAL};
|
|
|
|
use crate::GraphicsAdapter;
|
|
|
|
pub struct DrmObjects<T: GraphicsAdapter> {
|
|
next_id: DrmObjectId,
|
|
objects: HashMap<DrmObjectId, DrmObject<T>>,
|
|
}
|
|
|
|
impl<T: GraphicsAdapter> DrmObjects<T> {
|
|
pub(crate) fn new() -> Self {
|
|
DrmObjects {
|
|
next_id: DrmObjectId(1),
|
|
objects: HashMap::new(),
|
|
}
|
|
}
|
|
|
|
pub fn add_connector(&mut self, connector: DrmConnector<T>) -> DrmObjectId {
|
|
let connector_id = self.next_id;
|
|
self.objects.insert(
|
|
connector_id,
|
|
DrmObject {
|
|
kind: DrmObjectKind::Connector(connector),
|
|
},
|
|
);
|
|
self.next_id.0 += 1;
|
|
|
|
let encoder_id = self.next_id;
|
|
self.objects.insert(
|
|
encoder_id,
|
|
DrmObject {
|
|
kind: DrmObjectKind::Encoder(DrmEncoder {
|
|
crtc_id: DrmObjectId::INVALID,
|
|
possible_crtcs: 0,
|
|
possible_clones: 0,
|
|
}),
|
|
},
|
|
);
|
|
self.next_id.0 += 1;
|
|
|
|
// Attach encoder to connector
|
|
self.get_connector_mut(connector_id).unwrap().encoder_id = encoder_id;
|
|
|
|
connector_id
|
|
}
|
|
|
|
pub fn connector_ids(&self) -> impl Iterator<Item = DrmObjectId> + use<'_, T> {
|
|
self.objects
|
|
.iter()
|
|
.filter_map(|(&id, object)| match object.kind {
|
|
DrmObjectKind::Connector(_) => Some(id),
|
|
_ => None,
|
|
})
|
|
}
|
|
|
|
pub fn connectors(&self) -> impl Iterator<Item = &DrmConnector<T>> + use<'_, T> {
|
|
self.objects
|
|
.values()
|
|
.filter_map(|object| match &object.kind {
|
|
DrmObjectKind::Connector(connector) => Some(connector),
|
|
_ => None,
|
|
})
|
|
}
|
|
|
|
pub fn connectors_mut(&mut self) -> impl Iterator<Item = &mut DrmConnector<T>> + use<'_, T> {
|
|
self.objects
|
|
.values_mut()
|
|
.filter_map(|object| match &mut object.kind {
|
|
DrmObjectKind::Connector(connector) => Some(connector),
|
|
_ => None,
|
|
})
|
|
}
|
|
|
|
pub fn get_connector(&self, id: DrmObjectId) -> Result<&DrmConnector<T>> {
|
|
let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?;
|
|
match &object.kind {
|
|
DrmObjectKind::Connector(drm_connector) => Ok(drm_connector),
|
|
_ => Err(Error::new(EINVAL)),
|
|
}
|
|
}
|
|
|
|
pub fn get_connector_mut(&mut self, id: DrmObjectId) -> Result<&mut DrmConnector<T>> {
|
|
let object = self.objects.get_mut(&id).ok_or(Error::new(EINVAL))?;
|
|
match &mut object.kind {
|
|
DrmObjectKind::Connector(drm_connector) => Ok(drm_connector),
|
|
_ => Err(Error::new(EINVAL)),
|
|
}
|
|
}
|
|
|
|
pub fn encoder_ids(&self) -> impl Iterator<Item = DrmObjectId> + use<'_, T> {
|
|
self.objects
|
|
.iter()
|
|
.filter_map(|(&id, object)| match object.kind {
|
|
DrmObjectKind::Encoder(_) => Some(id),
|
|
_ => None,
|
|
})
|
|
}
|
|
|
|
pub fn get_encoder(&self, id: DrmObjectId) -> Result<&DrmEncoder> {
|
|
let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?;
|
|
match &object.kind {
|
|
DrmObjectKind::Encoder(drm_encoder) => Ok(drm_encoder),
|
|
_ => Err(Error::new(EINVAL)),
|
|
}
|
|
}
|
|
|
|
pub fn get_encoder_mut(&mut self, id: DrmObjectId) -> Result<&mut DrmEncoder> {
|
|
let object = self.objects.get_mut(&id).ok_or(Error::new(EINVAL))?;
|
|
match &mut object.kind {
|
|
DrmObjectKind::Encoder(drm_encoder) => Ok(drm_encoder),
|
|
_ => Err(Error::new(EINVAL)),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
|
pub struct DrmObjectId(pub(crate) u32);
|
|
|
|
impl DrmObjectId {
|
|
pub const INVALID: DrmObjectId = DrmObjectId(0);
|
|
}
|
|
|
|
struct DrmObject<T: GraphicsAdapter> {
|
|
kind: DrmObjectKind<T>,
|
|
}
|
|
|
|
enum DrmObjectKind<T: GraphicsAdapter> {
|
|
Connector(DrmConnector<T>),
|
|
Encoder(DrmEncoder),
|
|
}
|
|
|
|
pub struct DrmConnector<T: GraphicsAdapter> {
|
|
pub modes: Vec<drm_mode_modeinfo>,
|
|
pub encoder_id: DrmObjectId,
|
|
pub connector_type: u32,
|
|
pub connector_type_id: u32,
|
|
pub connection: DrmConnectorStatus,
|
|
pub mm_width: u32,
|
|
pub mm_height: u32,
|
|
pub subpixel: DrmSubpixelOrder,
|
|
pub driver_data: T::Connector,
|
|
}
|
|
|
|
#[derive(Copy, Clone)]
|
|
#[repr(u32)]
|
|
pub enum DrmConnectorStatus {
|
|
Disconnected = 0,
|
|
Connected = 1,
|
|
Unknown = 2,
|
|
}
|
|
|
|
#[derive(Copy, Clone)]
|
|
#[repr(u32)]
|
|
pub enum DrmSubpixelOrder {
|
|
Unknown = 0,
|
|
HorizontalRGB,
|
|
HorizontalBGR,
|
|
VerticalRGB,
|
|
VerticalBGR,
|
|
None,
|
|
}
|
|
|
|
// FIXME can we represent connector and encoder using a single struct?
|
|
pub struct DrmEncoder {
|
|
pub crtc_id: DrmObjectId,
|
|
pub possible_crtcs: u32,
|
|
pub possible_clones: u32,
|
|
}
|