drivers/graphics: Make everything work

This commit is contained in:
bjorn3
2026-05-14 15:49:57 +02:00
parent ab8bfb9d5d
commit 0ee128ad8d
6 changed files with 96 additions and 74 deletions
@@ -84,13 +84,9 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
driver_data_state: <T::Crtc as KmsCrtcDriver>::State,
plane_data: T::Plane,
plane_data_state: <T::Plane as KmsPlaneDriver>::State,
) -> KmsObjectId {
let primary_plane = self.add_plane(
&[],
KmsPlaneType::Primary,
plane_data,
plane_data_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 {
@@ -99,7 +95,6 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
properties: KmsCrtc::base_properties(),
primary_plane,
state: KmsCrtcState {
fb_id: None,
mode: None,
driver_data: driver_data_state,
},
@@ -107,9 +102,13 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
}));
self.crtcs.push(id);
self.get_plane(primary_plane).unwrap().lock().unwrap().possible_crtcs = 1 << crtc_index;
self.get_plane(primary_plane)
.unwrap()
.lock()
.unwrap()
.possible_crtcs = 1 << crtc_index;
id
(id, primary_plane)
}
pub fn crtc_ids(&self) -> &[KmsObjectId] {
@@ -155,7 +154,9 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
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 {
@@ -186,6 +187,12 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
&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)
}
@@ -273,7 +280,6 @@ pub struct KmsCrtc<T: GraphicsAdapter> {
#[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,
}
@@ -281,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(),
}
@@ -314,6 +319,7 @@ impl KmsPlaneDriver for () {
#[derive(Debug)]
pub struct KmsPlane<T: GraphicsAdapter> {
pub plane_index: u32,
pub possible_crtcs: u32,
pub plane_type: KmsPlaneType,
pub state: KmsPlaneState<T>,
+58 -45
View File
@@ -112,13 +112,11 @@ pub trait GraphicsAdapter: Sized + Debug {
objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self>>,
new_state: KmsCrtcState<Self>,
damage: Damage,
) -> syscall::Result<()>;
fn set_plane(
&mut self,
objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self>>,
plane: &Mutex<KmsPlane<Self>>,
new_plane_state: KmsPlaneState<Self>,
damage: Damage,
@@ -291,6 +289,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>>,
}
@@ -320,6 +319,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,
@@ -362,24 +365,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
@@ -391,6 +378,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);
}
@@ -581,7 +593,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);
@@ -623,20 +645,10 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
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.objects,
crtc,
new_crtc_state.clone(),
Damage {
x: 0,
y: 0,
width: 0,
height: 0,
},
)?;
self.adapter
.set_crtc(&self.objects, crtc, new_crtc_state.clone())?;
self.adapter.set_plane(
&self.objects,
crtc,
plane,
new_plane_state.clone(),
Damage {
@@ -659,6 +671,8 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
plane.lock().unwrap().state = new_plane_state.clone();
self.vts.get_mut(vt).unwrap().crtc_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| {
@@ -846,21 +860,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,
@@ -895,10 +909,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)?;
}
}
}
@@ -960,8 +975,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
let plane_mutex = self.objects.get_plane(plane_id)?;
let crtc_id = KmsObjectId(data.crtc_id());
let crtc = self.objects.get_crtc(crtc_id)?;
let crtc_index = crtc.lock().unwrap().crtc_index;
let crtc_index = self.objects.get_crtc(crtc_id)?.lock().unwrap().crtc_index;
let new_state;
{
@@ -996,7 +1010,6 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
if *vt == self.active_vt {
self.adapter.set_plane(
&self.objects,
crtc,
plane_mutex,
new_state,
Damage {
+2 -2
View File
@@ -449,7 +449,7 @@ 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 }, (), (), ());
let (width, height) = (fb.width, fb.height);
@@ -462,7 +462,7 @@ impl Device {
drop(connector);
objects
.get_crtc(crtc_id)
.get_plane(primary_plane_id)
.unwrap()
.lock()
.unwrap()
+6 -5
View File
@@ -100,10 +100,9 @@ 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();
crtc.state = state;
@@ -113,12 +112,14 @@ impl GraphicsAdapter for Device {
fn set_plane(
&mut self,
objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self>>,
plane: &Mutex<KmsPlane<Self>>,
new_plane_state: KmsPlaneState<Self>,
damage: Damage,
_damage: Damage,
) -> syscall::Result<()> {
let crtc = crtc.lock().unwrap();
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
+6 -5
View File
@@ -49,7 +49,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 {
@@ -107,10 +107,9 @@ 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();
crtc.state = state;
@@ -120,12 +119,14 @@ impl GraphicsAdapter for FbAdapter {
fn set_plane(
&mut self,
objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self>>,
plane: &Mutex<KmsPlane<Self>>,
new_plane_state: KmsPlaneState<Self>,
damage: Damage,
) -> syscall::Result<()> {
let mut crtc = crtc.lock().unwrap();
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
+6 -5
View File
@@ -363,7 +363,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]);
}
@@ -428,10 +428,9 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
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();
crtc.state = state;
@@ -441,13 +440,15 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
fn set_plane(
&mut self,
objects: &KmsObjects<Self>,
crtc: &Mutex<KmsCrtc<Self>>,
plane: &Mutex<KmsPlane<Self>>,
new_plane_state: KmsPlaneState<Self>,
damage: Damage,
) -> syscall::Result<()> {
futures::executor::block_on(async {
let crtc = crtc.lock().unwrap();
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();
// fb_id now in plane state