Merge branch 'gpu_drm41' into 'main'

Support planes in the drm interface

See merge request redox-os/base!266
This commit is contained in:
Jeremy Soller
2026-05-14 08:29:00 -06:00
7 changed files with 385 additions and 98 deletions
@@ -6,7 +6,7 @@ use std::sync::{Arc, Mutex};
use drm_fourcc::DrmFourcc;
use drm_sys::{
drm_mode_modeinfo, DRM_MODE_OBJECT_BLOB, DRM_MODE_OBJECT_CONNECTOR, DRM_MODE_OBJECT_CRTC,
DRM_MODE_OBJECT_ENCODER, DRM_MODE_OBJECT_FB, DRM_MODE_OBJECT_PROPERTY,
DRM_MODE_OBJECT_ENCODER, DRM_MODE_OBJECT_FB, DRM_MODE_OBJECT_PLANE, DRM_MODE_OBJECT_PROPERTY,
};
use syscall::{Error, Result, ENOENT};
@@ -22,6 +22,7 @@ pub struct KmsObjects<T: GraphicsAdapter> {
pub(super) connectors: Vec<KmsObjectId>,
pub(super) encoders: Vec<KmsObjectId>,
crtcs: Vec<KmsObjectId>,
planes: Vec<KmsObjectId>,
framebuffers: Vec<KmsObjectId>,
pub(super) objects: HashMap<KmsObjectId, KmsObject<T>>,
_marker: PhantomData<T>,
@@ -34,6 +35,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
connectors: vec![],
encoders: vec![],
crtcs: vec![],
planes: vec![],
framebuffers: vec![],
objects: HashMap::new(),
_marker: PhantomData,
@@ -80,14 +82,19 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
&mut self,
driver_data: T::Crtc,
driver_data_state: <T::Crtc as KmsCrtcDriver>::State,
) -> KmsObjectId {
plane_data: T::Plane,
plane_data_state: <T::Plane as KmsPlaneDriver>::State,
) -> (KmsObjectId, KmsObjectId) {
let primary_plane =
self.add_plane(&[], KmsPlaneType::Primary, plane_data, plane_data_state);
let crtc_index = self.crtcs.len() as u32;
let id = self.add(Mutex::new(KmsCrtc {
crtc_index,
gamma_size: 0,
properties: KmsCrtc::base_properties(),
primary_plane,
state: KmsCrtcState {
fb_id: None,
mode: None,
driver_data: driver_data_state,
},
@@ -95,7 +102,13 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
}));
self.crtcs.push(id);
id
self.get_plane(primary_plane)
.unwrap()
.lock()
.unwrap()
.possible_crtcs = 1 << crtc_index;
(id, primary_plane)
}
pub fn crtc_ids(&self) -> &[KmsObjectId] {
@@ -112,6 +125,60 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
self.get(id)
}
pub fn add_plane(
&mut self,
crtcs: &[KmsObjectId],
plane_type: KmsPlaneType,
driver_data: T::Plane,
driver_data_state: <T::Plane as KmsPlaneDriver>::State,
) -> KmsObjectId {
let mut possible_crtcs = 0u32;
for &crtc in crtcs {
possible_crtcs |= 1 << self.get_crtc(crtc).unwrap().lock().unwrap().crtc_index
}
let plane_index = self.planes.len() as u32;
let id = self.add(Mutex::new(KmsPlane {
plane_index,
possible_crtcs,
plane_type,
state: KmsPlaneState {
fb_id: None,
crtc_id: None,
src_rect: KmsRect {
x: 0u32,
y: 0,
width: 0,
height: 0,
},
crtc_rect: KmsRect {
x: 0i32,
y: 0,
width: 0,
height: 0,
},
driver_data: driver_data_state,
},
driver_data,
}));
self.planes.push(id);
id
}
pub fn plane_ids(&self) -> &[KmsObjectId] {
&self.planes
}
pub fn planes(&self) -> impl Iterator<Item = &Mutex<KmsPlane<T>>> + use<'_, T> {
self.planes
.iter()
.map(|&id| self.get::<Mutex<KmsPlane<T>>>(id).unwrap())
}
pub fn get_plane(&self, id: KmsObjectId) -> Result<&Mutex<KmsPlane<T>>> {
self.get(id)
}
pub fn add_framebuffer(&mut self, fb: KmsFramebuffer<T>) -> KmsObjectId {
let id = self.add(fb);
self.framebuffers.push(id);
@@ -188,6 +255,7 @@ define_object_kinds! { <T>
Connector(Mutex<KmsConnector<T>>) = DRM_MODE_OBJECT_CONNECTOR,
Encoder(KmsEncoder) = DRM_MODE_OBJECT_ENCODER,
Property(KmsProperty) = DRM_MODE_OBJECT_PROPERTY,
Plane(Mutex<KmsPlane<T>>) = DRM_MODE_OBJECT_PLANE,
Framebuffer(KmsFramebuffer<T>) = DRM_MODE_OBJECT_FB,
Blob(KmsBlob) = DRM_MODE_OBJECT_BLOB,
}
@@ -205,13 +273,13 @@ pub struct KmsCrtc<T: GraphicsAdapter> {
pub crtc_index: u32,
pub gamma_size: u32,
pub properties: Vec<KmsPropertyData<Self>>,
pub primary_plane: KmsObjectId,
pub state: KmsCrtcState<T>,
pub driver_data: T::Crtc,
}
#[derive(Debug)]
pub struct KmsCrtcState<T: GraphicsAdapter> {
pub fb_id: Option<KmsObjectId>,
pub mode: Option<drm_mode_modeinfo>,
pub driver_data: <T::Crtc as KmsCrtcDriver>::State,
}
@@ -219,7 +287,6 @@ pub struct KmsCrtcState<T: GraphicsAdapter> {
impl<T: GraphicsAdapter> Clone for KmsCrtcState<T> {
fn clone(&self) -> Self {
Self {
fb_id: self.fb_id.clone(),
mode: self.mode.clone(),
driver_data: self.driver_data.clone(),
}
@@ -232,6 +299,59 @@ define_object_props!(object, KmsCrtc<T: GraphicsAdapter> {
}
});
pub trait KmsPlaneDriver: Debug {
type State: Clone + Debug;
}
impl KmsPlaneDriver for () {
type State = ();
}
#[derive(Debug)]
pub struct KmsPlane<T: GraphicsAdapter> {
pub plane_index: u32,
pub possible_crtcs: u32,
pub plane_type: KmsPlaneType,
pub state: KmsPlaneState<T>,
pub driver_data: T::Plane,
}
#[derive(Debug)]
pub struct KmsPlaneState<T: GraphicsAdapter> {
pub fb_id: Option<KmsObjectId>,
pub crtc_id: Option<KmsObjectId>,
pub src_rect: KmsRect<u32>,
pub crtc_rect: KmsRect<i32>,
pub driver_data: <T::Plane as KmsPlaneDriver>::State,
}
impl<T: GraphicsAdapter> Clone for KmsPlaneState<T> {
fn clone(&self) -> Self {
Self {
fb_id: self.fb_id.clone(),
crtc_id: self.crtc_id.clone(),
src_rect: self.src_rect.clone(),
crtc_rect: self.crtc_rect.clone(),
driver_data: self.driver_data.clone(),
}
}
}
#[derive(Debug, PartialEq)]
pub enum KmsPlaneType {
Primary,
Overlay,
Cursor,
}
#[derive(Debug, Clone)]
pub struct KmsRect<T> {
pub x: T,
pub y: T,
pub width: u32,
pub height: u32,
}
#[derive(Debug)]
pub struct KmsFramebuffer<T: GraphicsAdapter> {
pub width: u32,
@@ -70,6 +70,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
.unzip())
}
KmsObject::Encoder(_)
| KmsObject::Plane(_)
| KmsObject::Property(_)
| KmsObject::Framebuffer(_)
| KmsObject::Blob(_) => Ok((vec![], vec![])),
+156 -69
View File
@@ -24,7 +24,10 @@ use syscall::schemev2::NewFdFlags;
use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EINVAL, ENOENT, ENXIO, EOPNOTSUPP};
use crate::kms::connector::{KmsConnectorDriver, KmsConnectorState};
use crate::kms::objects::{self, KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects};
use crate::kms::objects::{
self, KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneDriver,
KmsPlaneState, KmsRect,
};
use crate::kms::properties::KmsPropertyKind;
pub mod kms;
@@ -82,6 +85,7 @@ impl Damage {
pub trait GraphicsAdapter: Sized + Debug {
type Connector: KmsConnectorDriver;
type Crtc: KmsCrtcDriver;
type Plane: KmsPlaneDriver;
type Buffer: Buffer;
type Framebuffer: Framebuffer;
@@ -107,6 +111,13 @@ pub trait GraphicsAdapter: Sized + Debug {
objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self>>,
new_state: KmsCrtcState<Self>,
) -> syscall::Result<()>;
fn set_plane(
&mut self,
objects: &KmsObjects<Self>,
plane: &Mutex<KmsPlane<Self>>,
new_plane_state: KmsPlaneState<Self>,
damage: Damage,
) -> syscall::Result<()>;
@@ -277,6 +288,7 @@ struct GraphicsSchemeInner<T: GraphicsAdapter> {
struct VtState<T: GraphicsAdapter> {
connector_state: Vec<KmsConnectorState<T>>,
crtc_state: Vec<KmsCrtcState<T>>,
plane_state: Vec<KmsPlaneState<T>>,
cursor_plane: Option<CursorPlane<T::Buffer>>,
}
@@ -306,6 +318,10 @@ impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
.crtcs()
.map(|crtc| crtc.lock().unwrap().state.clone())
.collect(),
plane_state: objects
.planes()
.map(|plane| plane.lock().unwrap().state.clone())
.collect(),
cursor_plane: adapter.has_cursor_plane().then(|| CursorPlane {
x: 0,
y: 0,
@@ -348,24 +364,8 @@ impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
let crtc = self.objects.get_crtc(crtc_id).unwrap();
let connector_id = self.objects.connector_ids()[crtc_idx];
let fb = crtc_state.fb_id.map(|fb_id| {
self.objects
.get_framebuffer(fb_id)
.expect("removed framebuffers should be unset")
});
self.adapter
.set_crtc(
&self.objects,
crtc,
crtc_state.clone(),
Damage {
x: 0,
y: 0,
width: fb.map_or(0, |fb| fb.width),
height: fb.map_or(0, |fb| fb.height),
},
)
.set_crtc(&self.objects, crtc, crtc_state.clone())
.unwrap();
self.objects
@@ -377,6 +377,31 @@ impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
.crtc_id = crtc_id;
}
for (plane_idx, plane_state) in vt_state.plane_state.iter().enumerate() {
let plane_id = self.objects.plane_ids()[plane_idx];
let plane = self.objects.get_plane(plane_id).unwrap();
let fb = plane_state.fb_id.map(|fb_id| {
self.objects
.get_framebuffer(fb_id)
.expect("removed framebuffers should be unset")
});
self.adapter
.set_plane(
&self.objects,
plane,
plane_state.clone(),
Damage {
x: 0,
y: 0,
width: fb.map_or(0, |fb| fb.width),
height: fb.map_or(0, |fb| fb.height),
},
)
.unwrap();
}
if let Some(cursor_plane) = &vt_state.cursor_plane {
self.adapter.handle_cursor(cursor_plane, true);
}
@@ -460,14 +485,6 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
) -> Result<usize> {
use redox_ioctl::drm as ipc;
fn id_index(id: u32) -> u32 {
id & 0xFF
}
fn plane_id(i: u32) -> u32 {
id_index(i) | (1 << 13)
}
match self.handles.get_mut(id)? {
Handle::SchemeRoot => return Err(Error::new(EOPNOTSUPP)),
Handle::V2 {
@@ -575,7 +592,17 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
.lock()
.unwrap();
// Don't touch set_connectors, that is only used by MODE_SET_CRTC
data.set_fb_id(crtc.state.fb_id.unwrap_or(KmsObjectId::INVALID).0);
data.set_fb_id(
self.objects
.get_plane(crtc.primary_plane)
.unwrap()
.lock()
.unwrap()
.state
.fb_id
.unwrap_or(KmsObjectId::INVALID)
.0,
);
// FIXME fill x and y with the data from the primary plane
data.set_x(0);
data.set_y(0);
@@ -590,7 +617,8 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
Ok(0)
}),
ipc::MODE_SET_CRTC => ipc::DrmModeCrtc::with(payload, |data| {
let crtc = self.objects.get_crtc(KmsObjectId(data.crtc_id()))?;
let crtc_id = KmsObjectId(data.crtc_id());
let crtc = self.objects.get_crtc(crtc_id)?;
let connector_ids: Vec<KmsObjectId> = data
.set_connectors_ptr()
.iter()
@@ -607,14 +635,21 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
} else {
None
};
let mut new_state = crtc.lock().unwrap().state.clone();
new_state.fb_id = fb_id;
new_state.mode = mode;
let primary_plane_id = crtc.lock().unwrap().primary_plane;
let plane = self.objects.get_plane(primary_plane_id)?;
let mut new_crtc_state = crtc.lock().unwrap().state.clone();
new_crtc_state.mode = mode;
let mut new_plane_state = plane.lock().unwrap().state.clone();
new_plane_state.fb_id = fb_id;
new_plane_state.crtc_id = Some(crtc_id);
if *vt == self.active_vt {
self.adapter.set_crtc(
self.adapter
.set_crtc(&self.objects, crtc, new_crtc_state.clone())?;
self.adapter.set_plane(
&self.objects,
crtc,
new_state.clone(),
plane,
new_plane_state.clone(),
Damage {
x: data.x(),
y: data.y(),
@@ -622,18 +657,21 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
height: mode.map_or(0, |m| m.vdisplay as u32),
},
)?;
for connector in connector_ids {
self.objects
.get_connector(connector)?
.lock()
.unwrap()
.state
.crtc_id = KmsObjectId(data.crtc_id());
.crtc_id = crtc_id
}
}
crtc.lock().unwrap().state = new_crtc_state.clone();
plane.lock().unwrap().state = new_plane_state.clone();
self.vts.get_mut(vt).unwrap().crtc_state
[crtc.lock().unwrap().crtc_index as usize] = new_state;
[crtc.lock().unwrap().crtc_index as usize] = new_crtc_state;
self.vts.get_mut(vt).unwrap().plane_state
[plane.lock().unwrap().plane_index as usize] = new_plane_state;
Ok(0)
}),
ipc::MODE_CURSOR => ipc::DrmModeCursor::with(payload, |data| {
@@ -821,21 +859,21 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
// Disable planes that use this framebuffer.
for (vt, vt_data) in &mut self.vts {
for (crtc_idx, crtc_state) in vt_data.crtc_state.iter_mut().enumerate() {
if crtc_state.fb_id != Some(fb_id) {
for (plane_idx, plane_state) in vt_data.plane_state.iter_mut().enumerate() {
if plane_state.fb_id != Some(fb_id) {
continue;
}
crtc_state.fb_id = None;
plane_state.fb_id = None;
if *vt != self.active_vt {
continue;
}
let crtc = self.objects.crtcs().nth(crtc_idx).unwrap();
let plane = self.objects.planes().nth(plane_idx).unwrap();
self.adapter
.set_crtc(
.set_plane(
&self.objects,
crtc,
crtc_state.clone(),
plane,
plane_state.clone(),
Damage {
x: 0,
y: 0,
@@ -870,10 +908,11 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
});
if *vt == self.active_vt {
for crtc in self.objects.crtcs() {
let state = crtc.lock().unwrap().state.clone();
for plane in self.objects.planes() {
let state = plane.lock().unwrap().state.clone();
if state.fb_id == Some(KmsObjectId(data.fb_id())) {
self.adapter.set_crtc(&self.objects, crtc, state, damage)?;
self.adapter
.set_plane(&self.objects, plane, state, damage)?;
}
}
}
@@ -921,14 +960,79 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
Ok(0)
}),
ipc::MODE_GET_PLANE_RES => ipc::DrmModeGetPlaneRes::with(payload, |mut data| {
let count = self.objects.crtc_ids().len();
let mut ids = Vec::with_capacity(count);
for i in 0..(count as u32) {
ids.push(plane_id(i));
}
let ids = self
.objects
.plane_ids()
.iter()
.map(|id| id.0)
.collect::<Vec<_>>();
data.set_plane_id_ptr(&ids);
Ok(0)
}),
ipc::MODE_SET_PLANE => ipc::DrmModeSetPlane::with(payload, |data| {
let plane_id = KmsObjectId(data.plane_id());
let plane = self.objects.get_plane(plane_id)?;
let crtc_id = KmsObjectId(data.crtc_id());
let crtc_index = self.objects.get_crtc(crtc_id)?.lock().unwrap().crtc_index;
let mut new_state = {
let plane = plane.lock().unwrap();
if plane.possible_crtcs & (1 << crtc_index) == 0 {
return Err(Error::new(EINVAL));
}
plane.state.clone()
};
let fb_id = if data.fb_id() != 0 {
KmsObjectId(data.fb_id())
} else {
KmsObjectId::INVALID
};
new_state.fb_id = Some(fb_id);
new_state.crtc_id = Some(crtc_id);
new_state.src_rect = KmsRect {
x: data.src_x(),
y: data.src_y(),
width: data.src_w(),
height: data.src_h(),
};
new_state.crtc_rect = KmsRect {
x: data.crtc_x() as i32,
y: data.crtc_y() as i32,
width: data.crtc_w(),
height: data.crtc_h(),
};
if *vt == self.active_vt {
self.adapter.set_plane(
&self.objects,
plane,
new_state.clone(),
Damage {
x: 0,
y: 0,
width: 0,
height: 0,
},
)?;
}
self.vts.get_mut(vt).unwrap().plane_state
[plane.lock().unwrap().plane_index as usize] = new_state;
Ok(0)
}),
ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| {
let plane = self
.objects
.get_plane(KmsObjectId(data.plane_id()))
.unwrap()
.lock()
.unwrap();
data.set_crtc_id(plane.state.crtc_id.map_or(0, |id| id.0));
data.set_fb_id(plane.state.fb_id.unwrap_or(KmsObjectId::INVALID).0);
data.set_possible_crtcs(plane.possible_crtcs);
data.set_format_type_ptr(&[DrmFourcc::Argb8888 as u32]);
Ok(0)
}),
ipc::MODE_ADD_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| {
// FIXME handle multi-plane framebuffers
@@ -950,23 +1054,6 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
Ok(0)
}),
ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| {
let i = id_index(data.plane_id());
let crtc_id = self.objects.crtc_ids()[i as usize];
let crtc = self.objects.get_crtc(crtc_id).unwrap();
data.set_crtc_id(crtc_id.0);
data.set_fb_id(
crtc.lock()
.unwrap()
.state
.fb_id
.unwrap_or(KmsObjectId::INVALID)
.0,
);
data.set_possible_crtcs(1 << i);
data.set_format_type_ptr(&[DrmFourcc::Argb8888 as u32]);
Ok(0)
}),
ipc::MODE_OBJ_GET_PROPERTIES => {
ipc::DrmModeObjGetProperties::with(payload, |mut data| {
// FIXME remove once all drm objects are materialized in self.objects
+15 -4
View File
@@ -449,17 +449,28 @@ impl Device {
}
fn add_kms_pipe(objects: &mut KmsObjects<Self>, pipe_idx: usize, fb: KmsFramebuffer<Self>) {
let crtc_id = objects.add_crtc(Crtc { pipe_idx }, ());
let (crtc_id, primary_plane_id) = objects.add_crtc(
Crtc { pipe_idx },
(),
scheme::Plane {
pipe_idx,
plane_idx: 0,
},
(),
);
let (width, height) = (fb.width, fb.height);
let fb_id = objects.add_framebuffer(fb);
let connector_id = objects.add_connector((), (), &[crtc_id]);
let mut connector = objects.get_connector(connector_id).unwrap().lock().unwrap();
connector.connection = KmsConnectorStatus::Connected;
connector.update_from_size(fb.width, fb.height);
connector.update_from_size(width, height);
drop(connector);
let fb_id = objects.add_framebuffer(fb);
objects
.get_crtc(crtc_id)
.get_plane(primary_plane_id)
.unwrap()
.lock()
.unwrap()
+35 -7
View File
@@ -2,7 +2,8 @@ use std::sync::Mutex;
use driver_graphics::kms::connector::KmsConnectorStatus;
use driver_graphics::kms::objects::{
KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects,
KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneDriver,
KmsPlaneState,
};
use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter};
use drm_sys::{
@@ -19,10 +20,20 @@ pub struct Crtc {
pub pipe_idx: usize,
}
#[derive(Debug)]
pub struct Plane {
pub pipe_idx: usize,
pub plane_idx: usize,
}
impl KmsCrtcDriver for Crtc {
type State = ();
}
impl KmsPlaneDriver for Plane {
type State = ();
}
impl Buffer for GpuBuffer {
fn size(&self) -> usize {
self.size as usize
@@ -32,6 +43,7 @@ impl Buffer for GpuBuffer {
impl GraphicsAdapter for Device {
type Connector = ();
type Crtc = Crtc;
type Plane = Plane;
type Buffer = GpuBuffer;
type Framebuffer = ();
@@ -89,20 +101,36 @@ impl GraphicsAdapter for Device {
fn set_crtc(
&mut self,
objects: &KmsObjects<Self>,
_objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self>>,
state: KmsCrtcState<Self>,
_damage: Damage,
) -> syscall::Result<()> {
let mut crtc = crtc.lock().unwrap();
let fb = state
crtc.state = state;
Ok(())
}
fn set_plane(
&mut self,
objects: &KmsObjects<Self>,
plane: &Mutex<KmsPlane<Self>>,
new_plane_state: KmsPlaneState<Self>,
_damage: Damage,
) -> syscall::Result<()> {
let mut plane = plane.lock().unwrap();
let buffer = new_plane_state
.fb_id
.map(|fb_id| objects.get_framebuffer(fb_id))
.transpose()?;
crtc.state = state;
if let Some(primary_plane) = self.pipes[crtc.driver_data.pipe_idx].planes.first_mut() {
primary_plane.set_framebuffer(fb);
plane.state = new_plane_state;
if let Some(plane_hw) = self.pipes[plane.driver_data.pipe_idx]
.planes
.get_mut(plane.driver_data.plane_idx)
{
plane_hw.set_framebuffer(buffer);
}
Ok(())
+26 -6
View File
@@ -4,7 +4,9 @@ use std::ptr::{self, NonNull};
use std::sync::Mutex;
use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus};
use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects};
use driver_graphics::kms::objects::{
KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneState,
};
use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter};
use drm_sys::{
DRM_CAP_DUMB_BUFFER, DRM_CAP_DUMB_PREFERRED_DEPTH, DRM_CAP_DUMB_PREFER_SHADOW,
@@ -31,6 +33,7 @@ impl KmsConnectorDriver for Connector {
impl GraphicsAdapter for FbAdapter {
type Connector = Connector;
type Crtc = ();
type Plane = ();
type Buffer = GraphicScreen;
type Framebuffer = ();
@@ -45,7 +48,7 @@ impl GraphicsAdapter for FbAdapter {
fn init(&mut self, objects: &mut KmsObjects<Self>) {
for (framebuffer_id, framebuffer) in self.framebuffers.iter().enumerate() {
let crtc = objects.add_crtc((), ());
let (crtc, _primary_plane_id) = objects.add_crtc((), (), (), ());
objects.add_connector(
Connector {
@@ -103,17 +106,34 @@ impl GraphicsAdapter for FbAdapter {
fn set_crtc(
&mut self,
objects: &KmsObjects<Self>,
_objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self>>,
state: KmsCrtcState<Self>,
damage: Damage,
) -> syscall::Result<()> {
let mut crtc = crtc.lock().unwrap();
let buffer = state
crtc.state = state;
Ok(())
}
fn set_plane(
&mut self,
objects: &KmsObjects<Self>,
plane: &Mutex<KmsPlane<Self>>,
new_plane_state: KmsPlaneState<Self>,
damage: Damage,
) -> syscall::Result<()> {
let Some(crtc_id) = new_plane_state.crtc_id else {
return Ok(());
};
let crtc = objects.get_crtc(crtc_id).unwrap().lock().unwrap();
let mut plane = plane.lock().unwrap();
let buffer = new_plane_state
.fb_id
.map(|fb_id| objects.get_framebuffer(fb_id))
.transpose()?;
crtc.state = state;
plane.state = new_plane_state;
for connector in objects.connectors() {
let connector = connector.lock().unwrap();
+26 -6
View File
@@ -3,7 +3,9 @@ use std::sync::{Arc, Mutex};
use common::{dma::Dma, sgl};
use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus};
use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects};
use driver_graphics::kms::objects::{
KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects, KmsPlane, KmsPlaneState,
};
use driver_graphics::{Buffer as DrmBuffer, CursorPlane, Damage, GraphicsAdapter, GraphicsScheme};
use drm_sys::{
DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_CAP_DUMB_BUFFER, DRM_CAP_DUMB_PREFERRED_DEPTH,
@@ -341,6 +343,7 @@ impl<'a> VirtGpuAdapter<'a> {
impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
type Connector = VirtGpuConnector;
type Crtc = ();
type Plane = ();
type Buffer = VirtGpuFramebuffer<'a>;
type Framebuffer = ();
@@ -359,7 +362,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
});
for display_id in 0..self.config.num_scanouts.get() {
let crtc = objects.add_crtc((), ());
let (crtc, _primary_plane_id) = objects.add_crtc((), (), (), ());
objects.add_connector(VirtGpuConnector { display_id }, (), &[crtc]);
}
@@ -424,18 +427,35 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
fn set_crtc(
&mut self,
objects: &KmsObjects<Self>,
_objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self>>,
state: KmsCrtcState<Self>,
) -> syscall::Result<()> {
let mut crtc = crtc.lock().unwrap();
crtc.state = state;
Ok(())
}
fn set_plane(
&mut self,
objects: &KmsObjects<Self>,
plane: &Mutex<KmsPlane<Self>>,
new_plane_state: KmsPlaneState<Self>,
damage: Damage,
) -> syscall::Result<()> {
futures::executor::block_on(async {
let mut crtc = crtc.lock().unwrap();
let framebuffer = state
let Some(crtc_id) = new_plane_state.crtc_id else {
return Ok(());
};
let crtc = objects.get_crtc(crtc_id).unwrap().lock().unwrap();
let mut plane = plane.lock().unwrap();
let framebuffer = new_plane_state
.fb_id
.map(|fb_id| objects.get_framebuffer(fb_id))
.transpose()?;
crtc.state = state;
plane.state = new_plane_state;
for connector in objects.connectors() {
let connector = connector.lock().unwrap();