Merge branch 'gpu_drm19' into 'main'
drivers/graphics: Refcount all DRM objects See merge request redox-os/base!162
This commit is contained in:
+28
-30
@@ -1,5 +1,6 @@
|
||||
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,
|
||||
@@ -7,76 +8,73 @@ use drm_sys::{
|
||||
};
|
||||
use syscall::Result;
|
||||
|
||||
use crate::objects::{DrmObject, DrmObjectId, DrmObjects};
|
||||
use crate::kms::objects::{KmsObject, KmsObjectId, KmsObjects};
|
||||
use crate::GraphicsAdapter;
|
||||
|
||||
impl<T: GraphicsAdapter> DrmObjects<T> {
|
||||
pub fn add_connector(&mut self, driver_data: T::Connector) -> DrmObjectId {
|
||||
let encoder_id = self.add(DrmEncoder {
|
||||
crtc_id: DrmObjectId::INVALID,
|
||||
impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
pub fn add_connector(&mut self, driver_data: T::Connector) -> KmsObjectId {
|
||||
let encoder_id = self.add(KmsEncoder {
|
||||
crtc_id: KmsObjectId::INVALID,
|
||||
possible_crtcs: 0,
|
||||
possible_clones: 1 << self.encoders.len(),
|
||||
});
|
||||
self.encoders.push(encoder_id);
|
||||
|
||||
let connector_id = self.add(DrmConnector {
|
||||
let connector_id = self.add(Mutex::new(KmsConnector {
|
||||
encoder_id,
|
||||
modes: vec![],
|
||||
connector_type: DRM_MODE_CONNECTOR_Unknown,
|
||||
connector_type_id: self.connectors.len() as u32, // FIXME maybe pick unique id within connector type?
|
||||
connection: DrmConnectorStatus::Unknown,
|
||||
connection: KmsConnectorStatus::Unknown,
|
||||
mm_width: 0,
|
||||
mm_height: 0,
|
||||
subpixel: DrmSubpixelOrder::Unknown,
|
||||
driver_data,
|
||||
});
|
||||
}));
|
||||
self.connectors.push(connector_id);
|
||||
|
||||
connector_id
|
||||
}
|
||||
|
||||
pub fn connector_ids(&self) -> &[DrmObjectId] {
|
||||
pub fn connector_ids(&self) -> &[KmsObjectId] {
|
||||
&self.connectors
|
||||
}
|
||||
|
||||
pub fn connectors(&self) -> impl Iterator<Item = &DrmConnector<T::Connector>> + use<'_, T> {
|
||||
self.connectors.iter().map(|&id| self.get(id).unwrap())
|
||||
pub fn connectors(
|
||||
&self,
|
||||
) -> impl Iterator<Item = &Mutex<KmsConnector<T::Connector>>> + use<'_, T> {
|
||||
self.connectors
|
||||
.iter()
|
||||
.map(|&id| self.get_connector(id).unwrap())
|
||||
}
|
||||
|
||||
pub fn get_connector(&self, id: DrmObjectId) -> Result<&DrmConnector<T::Connector>> {
|
||||
pub fn get_connector(&self, id: KmsObjectId) -> Result<&Mutex<KmsConnector<T::Connector>>> {
|
||||
self.get(id)
|
||||
}
|
||||
|
||||
pub fn get_connector_mut(
|
||||
&mut self,
|
||||
id: DrmObjectId,
|
||||
) -> Result<&mut DrmConnector<T::Connector>> {
|
||||
self.get_mut(id)
|
||||
}
|
||||
|
||||
pub fn encoder_ids(&self) -> &[DrmObjectId] {
|
||||
pub fn encoder_ids(&self) -> &[KmsObjectId] {
|
||||
&self.encoders
|
||||
}
|
||||
|
||||
pub fn get_encoder(&self, id: DrmObjectId) -> Result<&DrmEncoder> {
|
||||
pub fn get_encoder(&self, id: KmsObjectId) -> Result<&KmsEncoder> {
|
||||
self.get(id)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DrmConnector<T: Debug + 'static> {
|
||||
pub encoder_id: DrmObjectId,
|
||||
pub struct KmsConnector<T: Debug + 'static> {
|
||||
pub encoder_id: KmsObjectId,
|
||||
pub modes: Vec<drm_mode_modeinfo>,
|
||||
pub connector_type: u32,
|
||||
pub connector_type_id: u32,
|
||||
pub connection: DrmConnectorStatus,
|
||||
pub connection: KmsConnectorStatus,
|
||||
pub mm_width: u32,
|
||||
pub mm_height: u32,
|
||||
pub subpixel: DrmSubpixelOrder,
|
||||
pub driver_data: T,
|
||||
}
|
||||
|
||||
impl<T: Debug + 'static> DrmConnector<T> {
|
||||
impl<T: Debug + 'static> KmsConnector<T> {
|
||||
pub fn update_from_size(&mut self, width: u32, height: u32) {
|
||||
self.modes = vec![Self::modeinfo_for_size(width, height)];
|
||||
}
|
||||
@@ -160,7 +158,7 @@ impl<T: Debug + 'static> DrmConnector<T> {
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[repr(u32)]
|
||||
pub enum DrmConnectorStatus {
|
||||
pub enum KmsConnectorStatus {
|
||||
Disconnected = 0,
|
||||
Connected = 1,
|
||||
Unknown = 2,
|
||||
@@ -177,7 +175,7 @@ pub enum DrmSubpixelOrder {
|
||||
None,
|
||||
}
|
||||
|
||||
impl<T: Debug + 'static> DrmObject for DrmConnector<T> {
|
||||
impl<T: Debug + 'static> KmsObject for Mutex<KmsConnector<T>> {
|
||||
fn object_type(&self) -> u32 {
|
||||
DRM_MODE_OBJECT_CONNECTOR
|
||||
}
|
||||
@@ -185,13 +183,13 @@ impl<T: Debug + 'static> DrmObject for DrmConnector<T> {
|
||||
|
||||
// FIXME can we represent connector and encoder using a single struct?
|
||||
#[derive(Debug)]
|
||||
pub struct DrmEncoder {
|
||||
pub crtc_id: DrmObjectId,
|
||||
pub struct KmsEncoder {
|
||||
pub crtc_id: KmsObjectId,
|
||||
pub possible_crtcs: u32,
|
||||
pub possible_clones: u32,
|
||||
}
|
||||
|
||||
impl DrmObject for DrmEncoder {
|
||||
impl KmsObject for KmsEncoder {
|
||||
fn object_type(&self) -> u32 {
|
||||
DRM_MODE_OBJECT_ENCODER
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
pub mod connector;
|
||||
pub mod objects;
|
||||
pub mod properties;
|
||||
@@ -0,0 +1,81 @@
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
use std::marker::PhantomData;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use syscall::{Error, Result, EINVAL};
|
||||
|
||||
use crate::GraphicsAdapter;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct KmsObjects<T: GraphicsAdapter> {
|
||||
next_id: KmsObjectId,
|
||||
pub(crate) connectors: Vec<KmsObjectId>,
|
||||
pub(crate) encoders: Vec<KmsObjectId>,
|
||||
pub(crate) objects: HashMap<KmsObjectId, Arc<KmsObjectData>>,
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
pub(crate) fn new() -> Self {
|
||||
KmsObjects {
|
||||
next_id: KmsObjectId(1),
|
||||
connectors: vec![],
|
||||
encoders: vec![],
|
||||
objects: HashMap::new(),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn add<U: KmsObject>(&mut self, data: U) -> KmsObjectId {
|
||||
let id = self.next_id;
|
||||
self.objects.insert(
|
||||
id,
|
||||
Arc::new(KmsObjectData {
|
||||
kind: Box::new(data),
|
||||
properties: Mutex::new(vec![]),
|
||||
}),
|
||||
);
|
||||
self.next_id.0 += 1;
|
||||
|
||||
id
|
||||
}
|
||||
|
||||
pub(crate) fn get<U: KmsObject>(&self, id: KmsObjectId) -> Result<&U> {
|
||||
let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?;
|
||||
if let Some(object) = (&*object.kind as &dyn Any).downcast_ref::<U>() {
|
||||
Ok(object)
|
||||
} else {
|
||||
Err(Error::new(EINVAL))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn object_type(&self, id: KmsObjectId) -> Result<u32> {
|
||||
let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?;
|
||||
Ok(object.kind.object_type())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct KmsObjectId(pub(crate) u32);
|
||||
|
||||
impl KmsObjectId {
|
||||
pub const INVALID: KmsObjectId = KmsObjectId(0);
|
||||
}
|
||||
|
||||
impl From<KmsObjectId> for u64 {
|
||||
fn from(value: KmsObjectId) -> Self {
|
||||
value.0.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct KmsObjectData {
|
||||
kind: Box<dyn KmsObject + 'static>,
|
||||
pub(crate) properties: Mutex<Vec<(KmsObjectId, u64)>>,
|
||||
}
|
||||
|
||||
pub trait KmsObject: Any + Debug {
|
||||
fn object_type(&self) -> u32;
|
||||
}
|
||||
+31
-27
@@ -1,27 +1,28 @@
|
||||
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 syscall::{Error, Result, EINVAL};
|
||||
|
||||
use crate::objects::{DrmObject, DrmObjectId, DrmObjects};
|
||||
use crate::kms::objects::{KmsObject, KmsObjectId, KmsObjects};
|
||||
use crate::GraphicsAdapter;
|
||||
|
||||
impl<T: GraphicsAdapter> DrmObjects<T> {
|
||||
impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
pub fn add_property(
|
||||
&mut self,
|
||||
name: &str,
|
||||
immutable: bool,
|
||||
atomic: bool,
|
||||
kind: DrmPropertyKind,
|
||||
) -> DrmObjectId {
|
||||
kind: KmsPropertyKind,
|
||||
) -> KmsObjectId {
|
||||
if name.len() > DRM_PROP_NAME_LEN as usize {
|
||||
panic!("Property name {name} is too long");
|
||||
}
|
||||
|
||||
match &kind {
|
||||
DrmPropertyKind::Range(start, end) => assert!(start < end),
|
||||
DrmPropertyKind::Enum(variants) => {
|
||||
KmsPropertyKind::Range(start, end) => assert!(start < end),
|
||||
KmsPropertyKind::Enum(variants) => {
|
||||
// FIXME check duplicate variant numbers
|
||||
for (variant_name, _) in variants {
|
||||
if variant_name.len() > DRM_PROP_NAME_LEN as usize {
|
||||
@@ -29,8 +30,8 @@ impl<T: GraphicsAdapter> DrmObjects<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
DrmPropertyKind::Blob => {}
|
||||
DrmPropertyKind::Bitmask(bitmask_flags) => {
|
||||
KmsPropertyKind::Blob => {}
|
||||
KmsPropertyKind::Bitmask(bitmask_flags) => {
|
||||
// FIXME check overlapping flag numbers
|
||||
for (flag_name, _) in bitmask_flags {
|
||||
if flag_name.len() > DRM_PROP_NAME_LEN as usize {
|
||||
@@ -38,8 +39,8 @@ impl<T: GraphicsAdapter> DrmObjects<T> {
|
||||
}
|
||||
}
|
||||
}
|
||||
DrmPropertyKind::Object => {}
|
||||
DrmPropertyKind::SignedRange(start, end) => assert!(start < end),
|
||||
KmsPropertyKind::Object => {}
|
||||
KmsPropertyKind::SignedRange(start, end) => assert!(start < end),
|
||||
}
|
||||
|
||||
let mut name_bytes = [0; DRM_PROP_NAME_LEN as usize];
|
||||
@@ -47,7 +48,7 @@ impl<T: GraphicsAdapter> DrmObjects<T> {
|
||||
*to = from as c_char;
|
||||
}
|
||||
|
||||
self.add(DrmProperty {
|
||||
self.add(KmsProperty {
|
||||
name: name_bytes,
|
||||
immutable,
|
||||
atomic,
|
||||
@@ -55,50 +56,53 @@ impl<T: GraphicsAdapter> DrmObjects<T> {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_property(&self, id: DrmObjectId) -> Result<&DrmProperty> {
|
||||
pub fn get_property(&self, id: KmsObjectId) -> Result<&KmsProperty> {
|
||||
self.get(id)
|
||||
}
|
||||
|
||||
pub fn add_object_property(&mut self, object: DrmObjectId, property: DrmObjectId, value: u64) {
|
||||
pub fn add_object_property(&mut self, object: KmsObjectId, property: KmsObjectId, value: u64) {
|
||||
let object = self.objects.get_mut(&object).unwrap();
|
||||
// FIXME validate property uniqueness and value
|
||||
object.properties.push((property, value));
|
||||
object.properties.lock().unwrap().push((property, value));
|
||||
}
|
||||
|
||||
pub fn set_object_property(&mut self, object: DrmObjectId, property: DrmObjectId, value: u64) {
|
||||
pub fn set_object_property(&mut self, object: KmsObjectId, property: KmsObjectId, value: u64) {
|
||||
let object = self.objects.get_mut(&object).unwrap();
|
||||
// FIXME validate property existence and value
|
||||
for (prop, val) in object.properties.iter_mut() {
|
||||
for (prop, val) in object.properties.lock().unwrap().iter_mut() {
|
||||
if *prop == property {
|
||||
*val = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_object_properties(&self, id: DrmObjectId) -> Result<&[(DrmObjectId, u64)]> {
|
||||
pub fn get_object_properties(
|
||||
&self,
|
||||
id: KmsObjectId,
|
||||
) -> Result<&Mutex<Vec<(KmsObjectId, u64)>>> {
|
||||
let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?;
|
||||
Ok(&object.properties)
|
||||
}
|
||||
|
||||
pub fn add_blob(&mut self, data: Vec<u8>) -> DrmObjectId {
|
||||
self.add(DrmBlob { data })
|
||||
pub fn add_blob(&mut self, data: Vec<u8>) -> KmsObjectId {
|
||||
self.add(KmsBlob { data })
|
||||
}
|
||||
|
||||
pub fn get_blob(&self, id: DrmObjectId) -> Result<&[u8]> {
|
||||
Ok(&self.get::<DrmBlob>(id)?.data)
|
||||
pub fn get_blob(&self, id: KmsObjectId) -> Result<&[u8]> {
|
||||
Ok(&self.get::<KmsBlob>(id)?.data)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DrmProperty {
|
||||
pub struct KmsProperty {
|
||||
pub name: [c_char; DRM_PROP_NAME_LEN as usize],
|
||||
pub immutable: bool,
|
||||
pub atomic: bool,
|
||||
pub kind: DrmPropertyKind,
|
||||
pub kind: KmsPropertyKind,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum DrmPropertyKind {
|
||||
pub enum KmsPropertyKind {
|
||||
Range(u64, u64),
|
||||
Enum(Vec<(&'static str, u64)>),
|
||||
Blob,
|
||||
@@ -107,18 +111,18 @@ pub enum DrmPropertyKind {
|
||||
SignedRange(i64, i64),
|
||||
}
|
||||
|
||||
impl DrmObject for DrmProperty {
|
||||
impl KmsObject for KmsProperty {
|
||||
fn object_type(&self) -> u32 {
|
||||
DRM_MODE_OBJECT_PROPERTY
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DrmBlob {
|
||||
pub struct KmsBlob {
|
||||
data: Vec<u8>,
|
||||
}
|
||||
|
||||
impl DrmObject for DrmBlob {
|
||||
impl KmsObject for KmsBlob {
|
||||
fn object_type(&self) -> u32 {
|
||||
DRM_MODE_OBJECT_BLOB
|
||||
}
|
||||
@@ -24,17 +24,15 @@ 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::objects::{DrmObjectId, DrmObjects};
|
||||
use crate::properties::DrmPropertyKind;
|
||||
use crate::kms::objects::{KmsObjectId, KmsObjects};
|
||||
use crate::kms::properties::KmsPropertyKind;
|
||||
|
||||
pub mod connector;
|
||||
pub mod objects;
|
||||
pub mod properties;
|
||||
pub mod kms;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct StandardProperties {
|
||||
pub edid: DrmObjectId,
|
||||
pub dpms: DrmObjectId,
|
||||
pub edid: KmsObjectId,
|
||||
pub dpms: KmsObjectId,
|
||||
}
|
||||
|
||||
pub trait GraphicsAdapter: Sized + Debug {
|
||||
@@ -45,16 +43,16 @@ pub trait GraphicsAdapter: Sized + Debug {
|
||||
fn name(&self) -> &'static [u8];
|
||||
fn desc(&self) -> &'static [u8];
|
||||
|
||||
fn init(&mut self, objects: &mut DrmObjects<Self>, standard_properties: &StandardProperties);
|
||||
fn init(&mut self, objects: &mut KmsObjects<Self>, standard_properties: &StandardProperties);
|
||||
|
||||
fn get_cap(&self, cap: u32) -> Result<u64>;
|
||||
fn set_client_cap(&self, cap: u32, value: u64) -> Result<()>;
|
||||
|
||||
fn probe_connector(
|
||||
&mut self,
|
||||
objects: &mut DrmObjects<Self>,
|
||||
objects: &mut KmsObjects<Self>,
|
||||
standard_properties: &StandardProperties,
|
||||
id: DrmObjectId,
|
||||
id: KmsObjectId,
|
||||
);
|
||||
|
||||
/// The maximum amount of displays that could be attached.
|
||||
@@ -77,7 +75,7 @@ pub trait GraphicsAdapter: Sized + Debug {
|
||||
fn handle_cursor(&mut self, cursor: Option<&CursorPlane<Self::Buffer>>, dirty_fb: bool);
|
||||
}
|
||||
|
||||
pub trait Buffer {
|
||||
pub trait Buffer: Debug {
|
||||
fn width(&self) -> u32;
|
||||
fn height(&self) -> u32;
|
||||
}
|
||||
@@ -107,14 +105,14 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
|
||||
.expect("vesad: Failed to open /scheme/debug/disable-graphical-debug"),
|
||||
);
|
||||
|
||||
let mut objects = DrmObjects::new();
|
||||
let mut objects = KmsObjects::new();
|
||||
|
||||
let edid = objects.add_property("EDID", true, false, DrmPropertyKind::Blob);
|
||||
let edid = objects.add_property("EDID", true, false, KmsPropertyKind::Blob);
|
||||
let dpms = objects.add_property(
|
||||
"DPMS",
|
||||
false,
|
||||
false,
|
||||
DrmPropertyKind::Enum(vec![
|
||||
KmsPropertyKind::Enum(vec![
|
||||
("On", DRM_MODE_DPMS_ON.into()),
|
||||
("Standby", DRM_MODE_DPMS_STANDBY.into()),
|
||||
("Suspend", DRM_MODE_DPMS_SUSPEND.into()),
|
||||
@@ -174,15 +172,15 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
|
||||
&mut self.inner.adapter
|
||||
}
|
||||
|
||||
pub fn objects(&self) -> &DrmObjects<T> {
|
||||
pub fn kms_objects(&self) -> &KmsObjects<T> {
|
||||
&self.inner.objects
|
||||
}
|
||||
|
||||
pub fn objects_mut(&mut self) -> &mut DrmObjects<T> {
|
||||
pub fn kms_objects_mut(&mut self) -> &mut KmsObjects<T> {
|
||||
&mut self.inner.objects
|
||||
}
|
||||
|
||||
pub fn adapter_and_objects_mut(&mut self) -> (&mut T, &mut DrmObjects<T>) {
|
||||
pub fn adapter_and_kms_objects_mut(&mut self) -> (&mut T, &mut KmsObjects<T>) {
|
||||
(&mut self.inner.adapter, &mut self.inner.objects)
|
||||
}
|
||||
|
||||
@@ -290,7 +288,7 @@ struct GraphicsSchemeInner<T: GraphicsAdapter> {
|
||||
scheme_name: String,
|
||||
disable_graphical_debug: Option<File>,
|
||||
socket: Socket,
|
||||
objects: DrmObjects<T>,
|
||||
objects: KmsObjects<T>,
|
||||
standard_properties: StandardProperties,
|
||||
next_id: usize,
|
||||
handles: BTreeMap<usize, Handle<T>>,
|
||||
@@ -593,7 +591,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_GET_ENCODER => ipc::DrmModeGetEncoder::with(payload, |mut data| {
|
||||
let encoder = self.objects.get_encoder(DrmObjectId(data.encoder_id()))?;
|
||||
let encoder = self.objects.get_encoder(KmsObjectId(data.encoder_id()))?;
|
||||
data.set_crtc_id(encoder.crtc_id.0);
|
||||
data.set_possible_crtcs(encoder.possible_crtcs);
|
||||
data.set_possible_clones(encoder.possible_clones);
|
||||
@@ -604,17 +602,21 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
self.adapter.probe_connector(
|
||||
&mut self.objects,
|
||||
&self.standard_properties,
|
||||
DrmObjectId(data.connector_id()),
|
||||
KmsObjectId(data.connector_id()),
|
||||
);
|
||||
}
|
||||
let connector = self
|
||||
.objects
|
||||
.get_connector(DrmObjectId(data.connector_id()))?;
|
||||
.get_connector(KmsObjectId(data.connector_id()))?
|
||||
.lock()
|
||||
.unwrap();
|
||||
data.set_encoders_ptr(&[connector.encoder_id.0]);
|
||||
data.set_modes_ptr(&connector.modes);
|
||||
let props = self
|
||||
.objects
|
||||
.get_object_properties(DrmObjectId(data.connector_id()))?;
|
||||
.get_object_properties(KmsObjectId(data.connector_id()))?
|
||||
.lock()
|
||||
.unwrap();
|
||||
data.set_props_ptr(&props.iter().map(|&(id, _)| id.0).collect::<Vec<_>>());
|
||||
data.set_prop_values_ptr(
|
||||
&props.iter().map(|&(_, value)| value).collect::<Vec<_>>(),
|
||||
@@ -628,7 +630,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_GET_PROPERTY => ipc::DrmModeGetProperty::with(payload, |mut data| {
|
||||
let property = self.objects.get_property(DrmObjectId(data.prop_id()))?;
|
||||
let property = self.objects.get_property(KmsObjectId(data.prop_id()))?;
|
||||
data.set_name(property.name);
|
||||
let mut flags = 0;
|
||||
if property.immutable {
|
||||
@@ -638,12 +640,12 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
flags |= DRM_MODE_PROP_ATOMIC;
|
||||
}
|
||||
match &property.kind {
|
||||
&DrmPropertyKind::Range(start, end) => {
|
||||
&KmsPropertyKind::Range(start, end) => {
|
||||
data.set_flags(flags | DRM_MODE_PROP_RANGE);
|
||||
data.set_values_ptr(&[start, end]);
|
||||
data.set_enum_blob_ptr(&[]);
|
||||
}
|
||||
DrmPropertyKind::Enum(variants) => {
|
||||
KmsPropertyKind::Enum(variants) => {
|
||||
data.set_flags(flags | DRM_MODE_PROP_ENUM);
|
||||
data.set_values_ptr(
|
||||
&variants.iter().map(|&(_, value)| value).collect::<Vec<_>>(),
|
||||
@@ -666,12 +668,12 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
DrmPropertyKind::Blob => {
|
||||
KmsPropertyKind::Blob => {
|
||||
data.set_flags(flags | DRM_MODE_PROP_BLOB);
|
||||
data.set_values_ptr(&[]);
|
||||
data.set_enum_blob_ptr(&[]);
|
||||
}
|
||||
DrmPropertyKind::Bitmask(bitmask_flags) => {
|
||||
KmsPropertyKind::Bitmask(bitmask_flags) => {
|
||||
data.set_flags(flags | DRM_MODE_PROP_BITMASK);
|
||||
data.set_values_ptr(
|
||||
&bitmask_flags
|
||||
@@ -697,12 +699,12 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
DrmPropertyKind::Object => {
|
||||
KmsPropertyKind::Object => {
|
||||
data.set_flags(flags | DRM_MODE_PROP_OBJECT);
|
||||
data.set_values_ptr(&[]);
|
||||
data.set_enum_blob_ptr(&[]);
|
||||
}
|
||||
&DrmPropertyKind::SignedRange(start, end) => {
|
||||
&KmsPropertyKind::SignedRange(start, end) => {
|
||||
data.set_flags(flags | DRM_MODE_PROP_SIGNED_RANGE);
|
||||
data.set_values_ptr(&[start as u64, end as u64]);
|
||||
data.set_enum_blob_ptr(&[]);
|
||||
@@ -711,7 +713,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_GET_PROP_BLOB => ipc::DrmModeGetBlob::with(payload, |mut data| {
|
||||
let blob = self.objects.get_blob(DrmObjectId(data.blob_id()))?;
|
||||
let blob = self.objects.get_blob(KmsObjectId(data.blob_id()))?;
|
||||
data.set_data(&blob);
|
||||
Ok(0)
|
||||
}),
|
||||
@@ -800,12 +802,14 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
|
||||
let props = self
|
||||
.objects
|
||||
.get_object_properties(DrmObjectId(data.obj_id()))?;
|
||||
.get_object_properties(KmsObjectId(data.obj_id()))?
|
||||
.lock()
|
||||
.unwrap();
|
||||
data.set_props_ptr(&props.iter().map(|&(id, _)| id.0).collect::<Vec<_>>());
|
||||
data.set_prop_values_ptr(
|
||||
&props.iter().map(|&(_, value)| value).collect::<Vec<_>>(),
|
||||
);
|
||||
data.set_obj_type(self.objects.object_type(DrmObjectId(data.obj_id()))?);
|
||||
data.set_obj_type(self.objects.object_type(KmsObjectId(data.obj_id()))?);
|
||||
Ok(0)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
use std::any::Any;
|
||||
use std::collections::HashMap;
|
||||
use std::fmt::Debug;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use syscall::{Error, Result, EINVAL};
|
||||
|
||||
use crate::GraphicsAdapter;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DrmObjects<T: GraphicsAdapter> {
|
||||
next_id: DrmObjectId,
|
||||
pub(crate) connectors: Vec<DrmObjectId>,
|
||||
pub(crate) encoders: Vec<DrmObjectId>,
|
||||
pub(crate) objects: HashMap<DrmObjectId, DrmObjectData>,
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: GraphicsAdapter> DrmObjects<T> {
|
||||
pub(crate) fn new() -> Self {
|
||||
DrmObjects {
|
||||
next_id: DrmObjectId(1),
|
||||
connectors: vec![],
|
||||
encoders: vec![],
|
||||
objects: HashMap::new(),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn add<U: DrmObject>(&mut self, data: U) -> DrmObjectId {
|
||||
let id = self.next_id;
|
||||
self.objects.insert(
|
||||
id,
|
||||
DrmObjectData {
|
||||
kind: Box::new(data),
|
||||
properties: vec![],
|
||||
},
|
||||
);
|
||||
self.next_id.0 += 1;
|
||||
|
||||
id
|
||||
}
|
||||
|
||||
pub(crate) fn get<U: DrmObject>(&self, id: DrmObjectId) -> Result<&U> {
|
||||
let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?;
|
||||
if let Some(object) = (&*object.kind as &dyn Any).downcast_ref::<U>() {
|
||||
Ok(object)
|
||||
} else {
|
||||
Err(Error::new(EINVAL))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_mut<U: DrmObject>(&mut self, id: DrmObjectId) -> Result<&mut U> {
|
||||
let object = self.objects.get_mut(&id).ok_or(Error::new(EINVAL))?;
|
||||
if let Some(object) = (&mut *object.kind as &mut dyn Any).downcast_mut::<U>() {
|
||||
Ok(object)
|
||||
} else {
|
||||
Err(Error::new(EINVAL))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn object_type(&self, id: DrmObjectId) -> Result<u32> {
|
||||
let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?;
|
||||
Ok(object.kind.object_type())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct DrmObjectId(pub(crate) u32);
|
||||
|
||||
impl DrmObjectId {
|
||||
pub const INVALID: DrmObjectId = DrmObjectId(0);
|
||||
}
|
||||
|
||||
impl From<DrmObjectId> for u64 {
|
||||
fn from(value: DrmObjectId) -> Self {
|
||||
value.0.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) struct DrmObjectData {
|
||||
kind: Box<dyn DrmObject + 'static>,
|
||||
pub(crate) properties: Vec<(DrmObjectId, u64)>,
|
||||
}
|
||||
|
||||
pub trait DrmObject: Any + Debug {
|
||||
fn object_type(&self) -> u32;
|
||||
}
|
||||
@@ -4,8 +4,8 @@ use std::alloc::{self, Layout};
|
||||
use std::convert::TryInto;
|
||||
use std::ptr::{self, NonNull};
|
||||
|
||||
use driver_graphics::connector::DrmConnectorStatus;
|
||||
use driver_graphics::objects::{DrmObjectId, DrmObjects};
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{KmsObjectId, KmsObjects};
|
||||
use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter, StandardProperties};
|
||||
use drm_sys::DRM_MODE_DPMS_ON;
|
||||
use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
|
||||
@@ -32,7 +32,7 @@ impl GraphicsAdapter for Device {
|
||||
b"Intel HD Graphics"
|
||||
}
|
||||
|
||||
fn init(&mut self, objects: &mut DrmObjects<Self>, standard_properties: &StandardProperties) {
|
||||
fn init(&mut self, objects: &mut KmsObjects<Self>, standard_properties: &StandardProperties) {
|
||||
// FIXME enumerate actual connectors
|
||||
for (framebuffer_id, _) in self.framebuffers.iter().enumerate() {
|
||||
let connector = objects.add_connector(Connector { framebuffer_id });
|
||||
@@ -61,13 +61,13 @@ impl GraphicsAdapter for Device {
|
||||
|
||||
fn probe_connector(
|
||||
&mut self,
|
||||
objects: &mut DrmObjects<Self>,
|
||||
objects: &mut KmsObjects<Self>,
|
||||
_standard_properties: &StandardProperties,
|
||||
id: DrmObjectId,
|
||||
id: KmsObjectId,
|
||||
) {
|
||||
let connector = objects.get_connector_mut(id).unwrap();
|
||||
let mut connector = objects.get_connector(id).unwrap().lock().unwrap();
|
||||
let framebuffer = &self.framebuffers[connector.driver_data.framebuffer_id];
|
||||
connector.connection = DrmConnectorStatus::Connected;
|
||||
connector.connection = KmsConnectorStatus::Connected;
|
||||
connector.update_from_size(framebuffer.width as u32, framebuffer.height as u32);
|
||||
// FIXME fetch EDID
|
||||
}
|
||||
@@ -146,6 +146,7 @@ impl DeviceFb {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct DumbFb {
|
||||
width: usize,
|
||||
height: usize,
|
||||
|
||||
@@ -2,8 +2,8 @@ use std::alloc::{self, Layout};
|
||||
use std::convert::TryInto;
|
||||
use std::ptr::{self, NonNull};
|
||||
|
||||
use driver_graphics::connector::DrmConnectorStatus;
|
||||
use driver_graphics::objects::{DrmObjectId, DrmObjects};
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{KmsObjectId, KmsObjects};
|
||||
use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter, StandardProperties};
|
||||
use drm_sys::DRM_MODE_DPMS_ON;
|
||||
use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
|
||||
@@ -34,7 +34,7 @@ impl GraphicsAdapter for FbAdapter {
|
||||
b"VESA"
|
||||
}
|
||||
|
||||
fn init(&mut self, objects: &mut DrmObjects<Self>, standard_properties: &StandardProperties) {
|
||||
fn init(&mut self, objects: &mut KmsObjects<Self>, standard_properties: &StandardProperties) {
|
||||
for framebuffer in &self.framebuffers {
|
||||
let connector = objects.add_connector(Connector {
|
||||
width: framebuffer.width as u32,
|
||||
@@ -64,12 +64,13 @@ impl GraphicsAdapter for FbAdapter {
|
||||
|
||||
fn probe_connector(
|
||||
&mut self,
|
||||
objects: &mut DrmObjects<Self>,
|
||||
objects: &mut KmsObjects<Self>,
|
||||
_standard_properties: &StandardProperties,
|
||||
id: DrmObjectId,
|
||||
id: KmsObjectId,
|
||||
) {
|
||||
let connector = objects.get_connector_mut(id).unwrap();
|
||||
connector.connection = DrmConnectorStatus::Connected;
|
||||
let mut connector = objects.get_connector(id).unwrap().lock().unwrap();
|
||||
let connector = &mut *connector;
|
||||
connector.connection = KmsConnectorStatus::Connected;
|
||||
connector.update_from_size(connector.driver_data.width, connector.driver_data.height);
|
||||
}
|
||||
|
||||
@@ -178,6 +179,7 @@ impl FrameBuffer {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GraphicScreen {
|
||||
width: usize,
|
||||
height: usize,
|
||||
|
||||
@@ -587,7 +587,7 @@ fn deamon(deamon: daemon::Daemon, mut pcid_handle: PciFunctionHandle) -> anyhow:
|
||||
|
||||
if events & VIRTIO_GPU_EVENT_DISPLAY != 0 {
|
||||
let standard_properties = scheme.standard_properties();
|
||||
let (adapter, objects) = scheme.adapter_and_objects_mut();
|
||||
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);
|
||||
|
||||
@@ -2,8 +2,8 @@ use std::fmt;
|
||||
use std::sync::Arc;
|
||||
|
||||
use common::{dma::Dma, sgl};
|
||||
use driver_graphics::connector::DrmConnectorStatus;
|
||||
use driver_graphics::objects::{DrmObjectId, DrmObjects};
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{KmsObjectId, KmsObjects};
|
||||
use driver_graphics::{
|
||||
Buffer as DrmBuffer, CursorPlane, GraphicsAdapter, GraphicsScheme, StandardProperties,
|
||||
};
|
||||
@@ -42,6 +42,17 @@ pub struct VirtGpuFramebuffer<'a> {
|
||||
height: u32,
|
||||
}
|
||||
|
||||
impl<'a> fmt::Debug for VirtGpuFramebuffer<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("VirtGpuFramebuffer")
|
||||
.field("id", &self.id)
|
||||
.field("sgl", &self.sgl)
|
||||
.field("width", &self.width)
|
||||
.field("height", &self.height)
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
impl DrmBuffer for VirtGpuFramebuffer<'_> {
|
||||
fn width(&self) -> u32 {
|
||||
self.width
|
||||
@@ -266,7 +277,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
b"VirtIO GPU"
|
||||
}
|
||||
|
||||
fn init(&mut self, objects: &mut DrmObjects<Self>, standard_properties: &StandardProperties) {
|
||||
fn init(&mut self, objects: &mut KmsObjects<Self>, standard_properties: &StandardProperties) {
|
||||
futures::executor::block_on(async {
|
||||
self.update_displays().await.unwrap();
|
||||
});
|
||||
@@ -303,23 +314,25 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
|
||||
fn probe_connector(
|
||||
&mut self,
|
||||
objects: &mut DrmObjects<Self>,
|
||||
objects: &mut KmsObjects<Self>,
|
||||
standard_properties: &StandardProperties,
|
||||
id: DrmObjectId,
|
||||
id: KmsObjectId,
|
||||
) {
|
||||
futures::executor::block_on(async {
|
||||
let connector = objects.get_connector_mut(id).unwrap();
|
||||
let mut connector = objects.get_connector(id).unwrap().lock().unwrap();
|
||||
let display = &self.displays[connector.driver_data.display_id as usize];
|
||||
|
||||
connector.connection = if display.enabled {
|
||||
DrmConnectorStatus::Connected
|
||||
KmsConnectorStatus::Connected
|
||||
} else {
|
||||
DrmConnectorStatus::Disconnected
|
||||
KmsConnectorStatus::Disconnected
|
||||
};
|
||||
|
||||
if self.has_edid {
|
||||
connector.update_from_edid(&display.edid);
|
||||
|
||||
drop(connector);
|
||||
|
||||
let blob = objects.add_blob(display.edid.clone());
|
||||
objects.set_object_property(id, standard_properties.edid, blob.into());
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user