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:
Jeremy Soller
2026-03-14 07:19:11 -06:00
7 changed files with 280 additions and 86 deletions
Generated
+1 -1
View File
@@ -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,
}
+130 -44
View File
@@ -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,
);
+28 -6
View File
@@ -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");
}
}
+37 -10
View File
@@ -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");
}
}
+30 -20
View File
@@ -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);
}