Merge branch 'gpu_drm13' into 'main'
Introduce read-only CRTC objects and support proper cursor ioctls See merge request redox-os/base!166
This commit is contained in:
Generated
+1
-1
@@ -1793,7 +1793,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "redox-ioctl"
|
||||
version = "0.1.0"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#f278abbb205803aeb17b022ac6ca20cce88b2843"
|
||||
source = "git+https://gitlab.redox-os.org/redox-os/relibc.git#266bf56554403ac36425113af06ea9ea273ce820"
|
||||
dependencies = [
|
||||
"drm-sys",
|
||||
"redox_syscall 0.7.3",
|
||||
|
||||
@@ -9,10 +9,19 @@ use crate::kms::objects::{KmsObjectId, KmsObjects};
|
||||
use crate::GraphicsAdapter;
|
||||
|
||||
impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
pub fn add_connector(&mut self, driver_data: T::Connector) -> KmsObjectId {
|
||||
pub fn add_connector(
|
||||
&mut self,
|
||||
driver_data: T::Connector,
|
||||
crtcs: &[KmsObjectId],
|
||||
) -> KmsObjectId {
|
||||
let mut possible_crtcs = 0;
|
||||
for &crtc in crtcs {
|
||||
possible_crtcs = 1 << self.get_crtc(crtc).unwrap().lock().unwrap().crtc_index;
|
||||
}
|
||||
|
||||
let encoder_id = self.add(KmsEncoder {
|
||||
crtc_id: KmsObjectId::INVALID,
|
||||
possible_crtcs: 0,
|
||||
possible_crtcs: possible_crtcs,
|
||||
possible_clones: 1 << self.encoders.len(),
|
||||
});
|
||||
self.encoders.push(encoder_id);
|
||||
@@ -118,7 +127,7 @@ impl<T: Debug> KmsConnector<T> {
|
||||
// FIXME update the EDID property
|
||||
}
|
||||
|
||||
fn modeinfo_for_size(width: u32, height: u32) -> drm_mode_modeinfo {
|
||||
pub(crate) fn modeinfo_for_size(width: u32, height: u32) -> drm_mode_modeinfo {
|
||||
let mut modeinfo = drm_mode_modeinfo {
|
||||
// The actual visible display size
|
||||
hdisplay: width as u16,
|
||||
|
||||
@@ -4,8 +4,8 @@ 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,
|
||||
drm_mode_modeinfo, DRM_MODE_OBJECT_BLOB, DRM_MODE_OBJECT_CONNECTOR, DRM_MODE_OBJECT_CRTC,
|
||||
DRM_MODE_OBJECT_ENCODER, DRM_MODE_OBJECT_PROPERTY,
|
||||
};
|
||||
use syscall::{Error, Result, EINVAL};
|
||||
|
||||
@@ -18,6 +18,7 @@ pub struct KmsObjects<T: GraphicsAdapter> {
|
||||
next_id: KmsObjectId,
|
||||
pub(crate) connectors: Vec<KmsObjectId>,
|
||||
pub(crate) encoders: Vec<KmsObjectId>,
|
||||
crtcs: Vec<KmsObjectId>,
|
||||
pub(crate) objects: HashMap<KmsObjectId, Arc<KmsObjectData<T>>>,
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
@@ -28,6 +29,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
next_id: KmsObjectId(1),
|
||||
connectors: vec![],
|
||||
encoders: vec![],
|
||||
crtcs: vec![],
|
||||
objects: HashMap::new(),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
@@ -63,6 +65,34 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?;
|
||||
Ok(object.kind.object_type())
|
||||
}
|
||||
|
||||
pub fn add_crtc(&mut self, driver_data: T::Crtc) -> KmsObjectId {
|
||||
let crtc_index = self.crtcs.len() as u32;
|
||||
let id = self.add(Mutex::new(KmsCrtc {
|
||||
crtc_index,
|
||||
fb_id: KmsObjectId::INVALID,
|
||||
gamma_size: 0,
|
||||
mode: None,
|
||||
driver_data,
|
||||
}));
|
||||
self.crtcs.push(id);
|
||||
|
||||
id
|
||||
}
|
||||
|
||||
pub fn crtc_ids(&self) -> &[KmsObjectId] {
|
||||
&self.crtcs
|
||||
}
|
||||
|
||||
pub fn crtcs(&self) -> impl Iterator<Item = &Mutex<KmsCrtc<T::Crtc>>> + use<'_, T> {
|
||||
self.crtcs
|
||||
.iter()
|
||||
.map(|&id| self.get::<Mutex<KmsCrtc<T::Crtc>>>(id).unwrap())
|
||||
}
|
||||
|
||||
pub fn get_crtc(&self, id: KmsObjectId) -> Result<&Mutex<KmsCrtc<T::Crtc>>> {
|
||||
self.get(id)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
@@ -124,8 +154,18 @@ macro_rules! define_object_kinds {
|
||||
}
|
||||
|
||||
define_object_kinds! { <T>
|
||||
Crtc(Mutex<KmsCrtc<T::Crtc>>) = DRM_MODE_OBJECT_CRTC,
|
||||
Connector(Mutex<KmsConnector<T::Connector>>) = DRM_MODE_OBJECT_CONNECTOR,
|
||||
Encoder(KmsEncoder) = DRM_MODE_OBJECT_ENCODER,
|
||||
Property(KmsProperty) = DRM_MODE_OBJECT_PROPERTY,
|
||||
Blob(KmsBlob) = DRM_MODE_OBJECT_BLOB,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct KmsCrtc<T> {
|
||||
pub crtc_index: u32,
|
||||
pub fb_id: KmsObjectId,
|
||||
pub gamma_size: u32,
|
||||
pub mode: Option<drm_mode_modeinfo>,
|
||||
pub driver_data: T,
|
||||
}
|
||||
|
||||
@@ -8,13 +8,14 @@ use std::io::{self, Write};
|
||||
use std::mem;
|
||||
use std::mem::transmute;
|
||||
use std::os::fd::BorrowedFd;
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use drm_sys::{
|
||||
drm_mode_property_enum, 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,
|
||||
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,
|
||||
};
|
||||
use graphics_ipc::v2::Damage;
|
||||
use inputd::{DisplayHandle, VtEventKind};
|
||||
@@ -24,7 +25,8 @@ 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::kms::objects::{KmsObjectId, KmsObjects};
|
||||
use crate::kms::connector::KmsConnector;
|
||||
use crate::kms::objects::{KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use crate::kms::properties::KmsPropertyKind;
|
||||
|
||||
pub mod kms;
|
||||
@@ -37,6 +39,7 @@ pub struct StandardProperties {
|
||||
|
||||
pub trait GraphicsAdapter: Sized + Debug {
|
||||
type Connector: Debug;
|
||||
type Crtc: Debug;
|
||||
|
||||
type Buffer: Buffer;
|
||||
|
||||
@@ -64,15 +67,18 @@ pub trait GraphicsAdapter: Sized + Debug {
|
||||
fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer;
|
||||
fn map_dumb_buffer(&mut self, framebuffer: &Self::Buffer) -> *mut u8;
|
||||
|
||||
fn update_plane(
|
||||
fn set_crtc(
|
||||
&mut self,
|
||||
display_id: usize,
|
||||
objects: &KmsObjects<Self>,
|
||||
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
|
||||
connectors: &[KmsObjectId],
|
||||
mode: Option<drm_mode_modeinfo>,
|
||||
framebuffer: Option<&Self::Buffer>,
|
||||
damage: Damage,
|
||||
);
|
||||
|
||||
fn hw_cursor_size(&self) -> Option<(u32, u32)>;
|
||||
fn handle_cursor(&mut self, cursor: Option<&CursorPlane<Self::Buffer>>, dirty_fb: bool);
|
||||
fn handle_cursor(&mut self, cursor: &CursorPlane<Self::Buffer>, dirty_fb: bool);
|
||||
}
|
||||
|
||||
pub trait Buffer: Debug {
|
||||
@@ -86,7 +92,7 @@ pub struct CursorPlane<C: Buffer> {
|
||||
pub y: i32,
|
||||
pub hot_x: i32,
|
||||
pub hot_y: i32,
|
||||
pub framebuffer: C,
|
||||
pub framebuffer: Option<Arc<C>>,
|
||||
}
|
||||
|
||||
pub struct GraphicsScheme<T: GraphicsAdapter> {
|
||||
@@ -217,8 +223,17 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
|
||||
);
|
||||
|
||||
for (display_id, fb) in vt_state.display_fbs.iter().enumerate() {
|
||||
self.inner.adapter.update_plane(
|
||||
display_id,
|
||||
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())
|
||||
});
|
||||
|
||||
self.inner.adapter.set_crtc(
|
||||
&self.inner.objects,
|
||||
crtc,
|
||||
&[self.inner.objects.connector_ids()[display_id]],
|
||||
mode,
|
||||
fb.as_deref(),
|
||||
Damage {
|
||||
x: 0,
|
||||
@@ -232,7 +247,7 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
|
||||
if self.inner.adapter.hw_cursor_size().is_some() {
|
||||
self.inner
|
||||
.adapter
|
||||
.handle_cursor(vt_state.cursor_plane.as_ref(), true);
|
||||
.handle_cursor(&vt_state.cursor_plane, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,7 +314,7 @@ struct GraphicsSchemeInner<T: GraphicsAdapter> {
|
||||
|
||||
struct VtState<T: GraphicsAdapter> {
|
||||
display_fbs: Vec<Option<Arc<T::Buffer>>>,
|
||||
cursor_plane: Option<CursorPlane<T::Buffer>>,
|
||||
cursor_plane: CursorPlane<T::Buffer>,
|
||||
}
|
||||
|
||||
enum Handle<T: GraphicsAdapter> {
|
||||
@@ -324,7 +339,13 @@ impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
|
||||
) -> &'a mut VtState<T> {
|
||||
vts.entry(vt).or_insert_with(|| VtState {
|
||||
display_fbs: vec![None; adapter.display_count()],
|
||||
cursor_plane: None,
|
||||
cursor_plane: CursorPlane {
|
||||
x: 0,
|
||||
y: 0,
|
||||
hot_x: 0,
|
||||
hot_y: 0,
|
||||
framebuffer: None,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -339,13 +360,7 @@ impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
|
||||
let cursor_plane = vt_state.cursor_plane.get_or_insert_with(|| CursorPlane {
|
||||
x: 0,
|
||||
y: 0,
|
||||
hot_x: 0,
|
||||
hot_y: 0,
|
||||
framebuffer: self.adapter.create_dumb_buffer(width, height),
|
||||
});
|
||||
let cursor_plane = &mut vt_state.cursor_plane;
|
||||
|
||||
cursor_plane.x = cursor_damage.x;
|
||||
cursor_plane.y = cursor_damage.y;
|
||||
@@ -355,7 +370,7 @@ impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.adapter.handle_cursor(Some(cursor_plane), false);
|
||||
self.adapter.handle_cursor(cursor_plane, false);
|
||||
} else {
|
||||
cursor_plane.hot_x = cursor_damage.hot_x;
|
||||
cursor_plane.hot_y = cursor_damage.hot_y;
|
||||
@@ -363,7 +378,10 @@ impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
|
||||
let w: i32 = cursor_damage.width;
|
||||
let h: i32 = cursor_damage.height;
|
||||
let cursor_image = cursor_damage.cursor_img_bytes;
|
||||
let cursor_ptr = self.adapter.map_dumb_buffer(&cursor_plane.framebuffer);
|
||||
let framebuffer = cursor_plane
|
||||
.framebuffer
|
||||
.get_or_insert_with(|| Arc::new(self.adapter.create_dumb_buffer(width, height)));
|
||||
let cursor_ptr = self.adapter.map_dumb_buffer(framebuffer);
|
||||
|
||||
//Clear previous image from backing storage
|
||||
unsafe {
|
||||
@@ -388,7 +406,7 @@ impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
self.adapter.handle_cursor(Some(cursor_plane), true);
|
||||
self.adapter.handle_cursor(cursor_plane, true);
|
||||
}
|
||||
|
||||
return Ok(());
|
||||
@@ -495,10 +513,6 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
id & 0xFF
|
||||
}
|
||||
|
||||
fn crtc_id(i: u32) -> u32 {
|
||||
id_index(i) | (1 << 10)
|
||||
}
|
||||
|
||||
fn fb_id(i: u32) -> u32 {
|
||||
id_index(i) | (1 << 11)
|
||||
}
|
||||
@@ -556,7 +570,12 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
.iter()
|
||||
.map(|id| id.0)
|
||||
.collect::<Vec<_>>();
|
||||
let mut crtc_ids = Vec::with_capacity(count);
|
||||
let crtc_ids = self
|
||||
.objects
|
||||
.crtc_ids()
|
||||
.iter()
|
||||
.map(|id| id.0)
|
||||
.collect::<Vec<_>>();
|
||||
let enc_ids = self
|
||||
.objects
|
||||
.encoder_ids()
|
||||
@@ -565,7 +584,6 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
.collect::<Vec<_>>();
|
||||
let mut fb_ids = Vec::with_capacity(count);
|
||||
for i in 0..(count as u32) {
|
||||
crtc_ids.push(crtc_id(i));
|
||||
fb_ids.push(fb_id(i));
|
||||
}
|
||||
data.set_fb_id_ptr(&fb_ids);
|
||||
@@ -579,15 +597,49 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_GET_CRTC => ipc::DrmModeCrtc::with(payload, |mut data| {
|
||||
let i = id_index(data.crtc_id());
|
||||
//TOOD: connectors
|
||||
data.set_fb_id(fb_id(i));
|
||||
let crtc = self
|
||||
.objects
|
||||
.get_crtc(KmsObjectId(data.crtc_id()))?
|
||||
.lock()
|
||||
.unwrap();
|
||||
// Don't touch set_connectors, that is only used by MODE_SET_CRTC
|
||||
data.set_fb_id(crtc.fb_id.0);
|
||||
// FIXME fill x and y with the data from the primary plane
|
||||
data.set_x(0);
|
||||
data.set_y(0);
|
||||
data.set_gamma_size(0);
|
||||
data.set_mode_valid(0);
|
||||
//TODO: mode
|
||||
data.set_mode(Default::default());
|
||||
data.set_gamma_size(crtc.gamma_size);
|
||||
if let Some(mode) = crtc.mode {
|
||||
data.set_mode_valid(1);
|
||||
data.set_mode(mode);
|
||||
} else {
|
||||
data.set_mode_valid(0);
|
||||
data.set_mode(Default::default());
|
||||
}
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_CURSOR => ipc::DrmModeCursor::with(payload, |data| {
|
||||
let vt_state = self.vts.get_mut(vt).unwrap();
|
||||
|
||||
let cursor_plane = &mut vt_state.cursor_plane;
|
||||
|
||||
let update_buffer = data.flags() & DRM_MODE_CURSOR_BO != 0;
|
||||
if update_buffer {
|
||||
cursor_plane.framebuffer = if data.handle() == 0 {
|
||||
None
|
||||
} else if let Some(buffer) = fbs.get(&id_index(data.handle())) {
|
||||
Some(buffer.clone())
|
||||
} else {
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
}
|
||||
|
||||
if data.flags() & DRM_MODE_CURSOR_MOVE != 0 {
|
||||
cursor_plane.x = data.x();
|
||||
cursor_plane.y = data.y();
|
||||
}
|
||||
|
||||
self.adapter.handle_cursor(cursor_plane, update_buffer);
|
||||
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_GET_ENCODER => ipc::DrmModeGetEncoder::with(payload, |mut data| {
|
||||
@@ -785,7 +837,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
}),
|
||||
ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| {
|
||||
let i = id_index(data.plane_id());
|
||||
data.set_crtc_id(crtc_id(i));
|
||||
data.set_crtc_id(self.objects.crtc_ids()[i as usize].0);
|
||||
data.set_fb_id(fb_id(i));
|
||||
data.set_possible_crtcs(1 << i);
|
||||
data.set_format_type_ptr(&[DRM_FORMAT_ARGB8888]);
|
||||
@@ -794,7 +846,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
ipc::MODE_OBJ_GET_PROPERTIES => {
|
||||
ipc::DrmModeObjGetProperties::with(payload, |mut data| {
|
||||
// FIXME remove once all drm objects are materialized in self.objects
|
||||
if data.obj_id() >= 1 << 10 {
|
||||
if data.obj_id() >= 1 << 11 {
|
||||
data.set_props_ptr(&[]);
|
||||
data.set_prop_values_ptr(&[]);
|
||||
return Ok(0);
|
||||
@@ -813,6 +865,33 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
Ok(0)
|
||||
})
|
||||
}
|
||||
ipc::MODE_CURSOR2 => ipc::DrmModeCursor2::with(payload, |data| {
|
||||
let vt_state = self.vts.get_mut(vt).unwrap();
|
||||
|
||||
let cursor_plane = &mut vt_state.cursor_plane;
|
||||
|
||||
let update_buffer = data.flags() & DRM_MODE_CURSOR_BO != 0;
|
||||
if update_buffer {
|
||||
cursor_plane.framebuffer = if data.handle() == 0 {
|
||||
None
|
||||
} else if let Some(buffer) = fbs.get(&id_index(data.handle())) {
|
||||
Some(buffer.clone())
|
||||
} else {
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
cursor_plane.hot_x = data.hot_x();
|
||||
cursor_plane.hot_y = data.hot_y();
|
||||
}
|
||||
|
||||
if data.flags() & DRM_MODE_CURSOR_MOVE != 0 {
|
||||
cursor_plane.x = data.x();
|
||||
cursor_plane.y = data.y();
|
||||
}
|
||||
|
||||
self.adapter.handle_cursor(cursor_plane, update_buffer);
|
||||
|
||||
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);
|
||||
@@ -836,9 +915,9 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
};
|
||||
|
||||
let display_id = payload.display_id;
|
||||
if display_id >= self.adapter.display_count() {
|
||||
let Some(crtc) = self.objects.crtcs().nth(display_id) else {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
};
|
||||
|
||||
let framebuffer = if payload.fb_id == 0 {
|
||||
None
|
||||
@@ -852,8 +931,15 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
framebuffer.map(Arc::clone);
|
||||
|
||||
if *vt == self.active_vt {
|
||||
self.adapter.update_plane(
|
||||
display_id,
|
||||
let mode = framebuffer.as_ref().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),
|
||||
payload.damage,
|
||||
);
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
use std::alloc::{self, Layout};
|
||||
use std::convert::TryInto;
|
||||
use std::ptr::{self, NonNull};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{KmsObjectId, KmsObjects};
|
||||
use driver_graphics::kms::objects::{KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter, StandardProperties};
|
||||
use drm_sys::DRM_MODE_DPMS_ON;
|
||||
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;
|
||||
use syscall::{error::EINVAL, PAGE_SIZE};
|
||||
@@ -21,6 +22,7 @@ pub struct Connector {
|
||||
|
||||
impl GraphicsAdapter for Device {
|
||||
type Connector = Connector;
|
||||
type Crtc = ();
|
||||
|
||||
type Buffer = DumbFb;
|
||||
|
||||
@@ -35,7 +37,9 @@ impl GraphicsAdapter for Device {
|
||||
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 });
|
||||
let crtc = objects.add_crtc(());
|
||||
|
||||
let connector = objects.add_connector(Connector { framebuffer_id }, &[crtc]);
|
||||
objects.add_object_property(
|
||||
connector,
|
||||
standard_properties.dpms,
|
||||
@@ -91,8 +95,26 @@ impl GraphicsAdapter for Device {
|
||||
framebuffer.ptr.as_ptr().cast::<u8>()
|
||||
}
|
||||
|
||||
fn update_plane(&mut self, display_id: usize, buffer: Option<&Self::Buffer>, damage: Damage) {
|
||||
let framebuffer = &mut self.framebuffers[display_id];
|
||||
fn set_crtc(
|
||||
&mut self,
|
||||
objects: &KmsObjects<Self>,
|
||||
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
|
||||
connectors: &[KmsObjectId],
|
||||
mode: Option<drm_mode_modeinfo>,
|
||||
buffer: Option<&Self::Buffer>,
|
||||
damage: Damage,
|
||||
) {
|
||||
crtc.lock().unwrap().mode = mode;
|
||||
|
||||
let framebuffer_id = objects
|
||||
.get_connector(connectors[0])
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.driver_data
|
||||
.framebuffer_id;
|
||||
|
||||
let framebuffer = &mut self.framebuffers[framebuffer_id];
|
||||
if let Some(buffer) = buffer {
|
||||
buffer.sync(framebuffer, damage)
|
||||
} else {
|
||||
@@ -113,7 +135,7 @@ impl GraphicsAdapter for Device {
|
||||
None
|
||||
}
|
||||
|
||||
fn handle_cursor(&mut self, _cursor: Option<&CursorPlane<Self::Buffer>>, _dirty_fb: bool) {
|
||||
fn handle_cursor(&mut self, _cursor: &CursorPlane<Self::Buffer>, _dirty_fb: bool) {
|
||||
unimplemented!("ihdgd does not support this function");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
use std::alloc::{self, Layout};
|
||||
use std::convert::TryInto;
|
||||
use std::ptr::{self, NonNull};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{KmsObjectId, KmsObjects};
|
||||
use driver_graphics::kms::objects::{KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter, StandardProperties};
|
||||
use drm_sys::DRM_MODE_DPMS_ON;
|
||||
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;
|
||||
use syscall::{EINVAL, PAGE_SIZE};
|
||||
@@ -19,10 +20,12 @@ pub struct FbAdapter {
|
||||
pub struct Connector {
|
||||
width: u32,
|
||||
height: u32,
|
||||
framebuffer_id: usize,
|
||||
}
|
||||
|
||||
impl GraphicsAdapter for FbAdapter {
|
||||
type Connector = Connector;
|
||||
type Crtc = ();
|
||||
|
||||
type Buffer = GraphicScreen;
|
||||
|
||||
@@ -35,11 +38,17 @@ impl GraphicsAdapter for FbAdapter {
|
||||
}
|
||||
|
||||
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,
|
||||
height: framebuffer.height as u32,
|
||||
});
|
||||
for (framebuffer_id, framebuffer) in self.framebuffers.iter().enumerate() {
|
||||
let crtc = objects.add_crtc(());
|
||||
|
||||
let connector = objects.add_connector(
|
||||
Connector {
|
||||
width: framebuffer.width as u32,
|
||||
height: framebuffer.height as u32,
|
||||
framebuffer_id,
|
||||
},
|
||||
&[crtc],
|
||||
);
|
||||
objects.add_object_property(
|
||||
connector,
|
||||
standard_properties.dpms,
|
||||
@@ -93,8 +102,26 @@ impl GraphicsAdapter for FbAdapter {
|
||||
framebuffer.ptr.as_ptr().cast::<u8>()
|
||||
}
|
||||
|
||||
fn update_plane(&mut self, display_id: usize, buffer: Option<&Self::Buffer>, damage: Damage) {
|
||||
let framebuffer = &mut self.framebuffers[display_id];
|
||||
fn set_crtc(
|
||||
&mut self,
|
||||
objects: &KmsObjects<Self>,
|
||||
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
|
||||
connectors: &[KmsObjectId],
|
||||
mode: Option<drm_mode_modeinfo>,
|
||||
buffer: Option<&Self::Buffer>,
|
||||
damage: Damage,
|
||||
) {
|
||||
crtc.lock().unwrap().mode = mode;
|
||||
|
||||
let framebuffer_id = objects
|
||||
.get_connector(connectors[0])
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.driver_data
|
||||
.framebuffer_id;
|
||||
let framebuffer = &mut self.framebuffers[framebuffer_id];
|
||||
|
||||
if let Some(buffer) = buffer {
|
||||
buffer.sync(framebuffer, damage)
|
||||
} else {
|
||||
@@ -115,7 +142,7 @@ impl GraphicsAdapter for FbAdapter {
|
||||
None
|
||||
}
|
||||
|
||||
fn handle_cursor(&mut self, _cursor: Option<&CursorPlane<Self::Buffer>>, _dirty_fb: bool) {
|
||||
fn handle_cursor(&mut self, _cursor: &CursorPlane<Self::Buffer>, _dirty_fb: bool) {
|
||||
unimplemented!("Vesad does not support this function");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use common::{dma::Dma, sgl};
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{KmsObjectId, KmsObjects};
|
||||
use driver_graphics::kms::objects::{KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::{
|
||||
Buffer as DrmBuffer, CursorPlane, GraphicsAdapter, GraphicsScheme, StandardProperties,
|
||||
};
|
||||
use drm_sys::{DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_MODE_DPMS_ON};
|
||||
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;
|
||||
|
||||
@@ -266,6 +266,7 @@ impl VirtGpuAdapter<'_> {
|
||||
|
||||
impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
type Connector = VirtGpuConnector;
|
||||
type Crtc = ();
|
||||
|
||||
type Buffer = VirtGpuFramebuffer<'a>;
|
||||
|
||||
@@ -283,7 +284,9 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
});
|
||||
|
||||
for display_id in 0..self.config.num_scanouts.get() {
|
||||
let connector = objects.add_connector(VirtGpuConnector { display_id });
|
||||
let crtc = objects.add_crtc(());
|
||||
|
||||
let connector = objects.add_connector(VirtGpuConnector { display_id }, &[crtc]);
|
||||
if self.has_edid {
|
||||
objects.add_object_property(connector, standard_properties.edid, 0);
|
||||
}
|
||||
@@ -415,23 +418,36 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
framebuffer.sgl.as_ptr()
|
||||
}
|
||||
|
||||
fn update_plane(
|
||||
fn set_crtc(
|
||||
&mut self,
|
||||
display_id: usize,
|
||||
objects: &KmsObjects<Self>,
|
||||
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
|
||||
connectors: &[KmsObjectId],
|
||||
mode: Option<drm_mode_modeinfo>,
|
||||
framebuffer: Option<&Self::Buffer>,
|
||||
damage: Damage,
|
||||
) {
|
||||
futures::executor::block_on(async {
|
||||
crtc.lock().unwrap().mode = mode;
|
||||
|
||||
let display_id = objects
|
||||
.get_connector(connectors[0])
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap()
|
||||
.driver_data
|
||||
.display_id;
|
||||
|
||||
let Some(framebuffer) = framebuffer else {
|
||||
let scanout_request = Dma::new(SetScanout::new(
|
||||
display_id as u32,
|
||||
display_id,
|
||||
ResourceId::NONE,
|
||||
GpuRect::new(0, 0, 0, 0),
|
||||
))
|
||||
.unwrap();
|
||||
let header = self.send_request(scanout_request).await.unwrap();
|
||||
assert_eq!(header.ty, CommandTy::RespOkNodata);
|
||||
self.displays[display_id].active_resource = None;
|
||||
self.displays[display_id as usize].active_resource = None;
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -450,16 +466,16 @@ 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].active_resource != Some(framebuffer.id) {
|
||||
if self.displays[display_id as usize].active_resource != Some(framebuffer.id) {
|
||||
let scanout_request = Dma::new(SetScanout::new(
|
||||
display_id as u32,
|
||||
display_id,
|
||||
framebuffer.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].active_resource = Some(framebuffer.id);
|
||||
self.displays[display_id as usize].active_resource = Some(framebuffer.id);
|
||||
}
|
||||
|
||||
let flush = ResourceFlush::new(
|
||||
@@ -475,16 +491,10 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
Some((64, 64))
|
||||
}
|
||||
|
||||
fn handle_cursor(&mut self, cursor: Option<&CursorPlane<Self::Buffer>>, dirty_fb: bool) {
|
||||
if let Some(cursor) = cursor {
|
||||
fn handle_cursor(&mut self, cursor: &CursorPlane<Self::Buffer>, dirty_fb: bool) {
|
||||
if let Some(buffer) = &cursor.framebuffer {
|
||||
if dirty_fb {
|
||||
self.update_cursor(
|
||||
&cursor.framebuffer,
|
||||
cursor.x,
|
||||
cursor.y,
|
||||
cursor.hot_x,
|
||||
cursor.hot_y,
|
||||
);
|
||||
self.update_cursor(buffer, cursor.x, cursor.y, cursor.hot_x, cursor.hot_y);
|
||||
} else {
|
||||
self.move_cursor(cursor.x, cursor.y);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user