drivers/graphics: Split out state modified during atomic mode setting

This commit is contained in:
bjorn3
2026-03-19 23:39:32 +01:00
parent 5b88dadc4f
commit eaa390156d
7 changed files with 97 additions and 43 deletions
@@ -16,6 +16,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
pub fn add_connector(
&mut self,
driver_data: T::Connector,
driver_data_state: <T::Connector as KmsConnectorDriver>::State,
crtcs: &[KmsObjectId],
) -> KmsObjectId {
let mut possible_crtcs = 0;
@@ -40,9 +41,12 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
mm_height: 0,
subpixel: DrmSubpixelOrder::Unknown,
properties: KmsConnector::base_properties(),
dpms: KmsDpms::Off,
edid: KmsObjectId::INVALID,
crtc_id: KmsObjectId::INVALID,
state: KmsConnectorState {
dpms: KmsDpms::On,
crtc_id: KmsObjectId::INVALID,
driver_data: driver_data_state,
},
driver_data,
}));
self.connectors.push(connector_id);
@@ -75,8 +79,16 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
}
}
pub trait KmsConnectorDriver: Debug {
type State: Clone + Debug;
}
impl KmsConnectorDriver for () {
type State = ();
}
#[derive(Debug)]
pub struct KmsConnector<T> {
pub struct KmsConnector<T: KmsConnectorDriver> {
pub encoder_id: KmsObjectId,
pub modes: Vec<drm_mode_modeinfo>,
pub connector_type: u32,
@@ -86,25 +98,31 @@ pub struct KmsConnector<T> {
pub mm_height: u32,
pub subpixel: DrmSubpixelOrder,
pub properties: Vec<KmsPropertyData<Self>>,
pub dpms: KmsDpms,
pub edid: KmsObjectId,
pub state: KmsConnectorState<T::State>,
pub driver_data: T,
}
#[derive(Debug, Clone)]
pub struct KmsConnectorState<T> {
pub dpms: KmsDpms,
pub crtc_id: KmsObjectId,
pub driver_data: T,
}
define_object_props!(object, KmsConnector<T> {
define_object_props!(object, KmsConnector<T: KmsConnectorDriver> {
EDID {
get => u64::from(object.edid.0),
}
DPMS {
get => object.dpms as u64,
get => object.state.dpms as u64,
}
CRTC_ID {
get => u64::from(object.crtc_id.0),
get => u64::from(object.state.crtc_id.0),
}
});
impl<T> KmsConnector<T> {
impl<T: KmsConnectorDriver> KmsConnector<T> {
pub fn update_from_size(&mut self, width: u32, height: u32) {
self.modes = vec![Self::modeinfo_for_size(width, height)];
}
@@ -66,14 +66,21 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
Ok(object.object_type())
}
pub fn add_crtc(&mut self, driver_data: T::Crtc) -> KmsObjectId {
pub fn add_crtc(
&mut self,
driver_data: T::Crtc,
driver_data_state: <T::Crtc as KmsCrtcDriver>::State,
) -> 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,
properties: KmsCrtc::base_properties(),
state: KmsCrtcState {
fb_id: KmsObjectId::INVALID,
mode: None,
driver_data: driver_data_state,
},
driver_data,
}));
self.crtcs.push(id);
@@ -188,17 +195,31 @@ define_object_kinds! { <T>
Blob(KmsBlob) = DRM_MODE_OBJECT_BLOB,
}
pub trait KmsCrtcDriver: Debug {
type State: Clone + Debug;
}
impl KmsCrtcDriver for () {
type State = ();
}
#[derive(Debug)]
pub struct KmsCrtc<T> {
pub struct KmsCrtc<T: KmsCrtcDriver> {
pub crtc_index: u32,
pub fb_id: KmsObjectId,
pub gamma_size: u32,
pub mode: Option<drm_mode_modeinfo>,
pub properties: Vec<KmsPropertyData<Self>>,
pub state: KmsCrtcState<T::State>,
pub driver_data: T,
}
define_object_props!(object, KmsCrtc<T> {});
#[derive(Debug, Clone)]
pub struct KmsCrtcState<T> {
pub fb_id: KmsObjectId,
pub mode: Option<drm_mode_modeinfo>,
pub driver_data: T,
}
define_object_props!(object, KmsCrtc<T: KmsCrtcDriver> {});
#[derive(Debug)]
pub struct KmsFramebuffer<T, Buf> {
@@ -223,12 +223,12 @@ define_properties! {
}
macro_rules! define_object_props {
($object:ident, $obj:ident$(<$($T:ident),*>)? { $(
($object:ident, $obj:ident$(<$($T:ident$(: $bound:ident)?),*>)? { $(
$prop:ident {
get => $get:expr,
}
)* }) => {
impl$(<$($T),*>)? $obj$(<$($T),*>)? {
impl$(<$($T$(: $bound)?),*>)? $obj$(<$($T),*>)? {
pub(super) fn base_properties() -> Vec<KmsPropertyData<Self>> {
vec![$(KmsPropertyData {
id: $prop,
+14 -12
View File
@@ -21,8 +21,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::connector::KmsConnector;
use crate::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
use crate::kms::connector::{KmsConnector, KmsConnectorDriver};
use crate::kms::objects::{self, KmsCrtc, KmsCrtcDriver, KmsObjectId, KmsObjects};
use crate::kms::properties::KmsPropertyKind;
pub mod kms;
@@ -78,8 +78,8 @@ impl Damage {
}
pub trait GraphicsAdapter: Sized + Debug {
type Connector: Debug;
type Crtc: Debug;
type Connector: KmsConnectorDriver;
type Crtc: KmsCrtcDriver;
type Buffer: Buffer;
type Framebuffer: Framebuffer;
@@ -241,7 +241,7 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
let crtc = self.inner.objects.get_crtc(crtc_id).unwrap();
let connector_id = self.inner.objects.connector_ids()[display_id];
crtc.lock().unwrap().fb_id = fb.unwrap_or(KmsObjectId::INVALID);
crtc.lock().unwrap().state.fb_id = fb.unwrap_or(KmsObjectId::INVALID);
let fb = fb.map(|fb| {
self.inner
@@ -272,6 +272,7 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
.unwrap()
.lock()
.unwrap()
.state
.crtc_id = crtc_id;
}
@@ -538,12 +539,12 @@ 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.fb_id.0);
data.set_fb_id(crtc.state.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(crtc.gamma_size);
if let Some(mode) = crtc.mode {
if let Some(mode) = crtc.state.mode {
data.set_mode_valid(1);
data.set_mode(mode);
} else {
@@ -584,13 +585,14 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
height: mode.map_or(0, |m| m.vdisplay as u32),
},
);
crtc.lock().unwrap().fb_id = KmsObjectId(data.fb_id());
crtc.lock().unwrap().state.fb_id = KmsObjectId(data.fb_id());
for connector in connector_ids {
self.objects
.get_connector(connector)?
.lock()
.unwrap()
.state
.crtc_id = KmsObjectId(data.crtc_id());
}
}
@@ -780,7 +782,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
continue;
}
let crtc = self.objects.crtcs().nth(display_id).unwrap();
crtc.lock().unwrap().fb_id = KmsObjectId::INVALID;
crtc.lock().unwrap().state.fb_id = KmsObjectId::INVALID;
self.adapter.set_crtc(
&self.objects,
crtc,
@@ -820,8 +822,8 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
if *vt == self.active_vt {
for crtc in self.objects.crtcs() {
if crtc.lock().unwrap().fb_id == KmsObjectId(data.fb_id()) {
let mode = crtc.lock().unwrap().mode;
if crtc.lock().unwrap().state.fb_id == KmsObjectId(data.fb_id()) {
let mode = crtc.lock().unwrap().state.mode;
self.adapter
.set_crtc(&self.objects, crtc, mode, Some(fb), damage);
}
@@ -885,7 +887,7 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
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().fb_id.0);
data.set_fb_id(crtc.lock().unwrap().state.fb_id.0);
data.set_possible_crtcs(1 << i);
data.set_format_type_ptr(&[DrmFourcc::Argb8888 as u32]);
Ok(0)
+9 -5
View File
@@ -5,7 +5,7 @@ use std::convert::TryInto;
use std::ptr::{self, NonNull};
use std::sync::Mutex;
use driver_graphics::kms::connector::KmsConnectorStatus;
use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus};
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter};
use drm_sys::{drm_mode_modeinfo, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
@@ -18,6 +18,10 @@ pub struct Connector {
framebuffer_id: usize,
}
impl KmsConnectorDriver for Connector {
type State = ();
}
impl GraphicsAdapter for Device {
type Connector = Connector;
type Crtc = ();
@@ -36,9 +40,9 @@ impl GraphicsAdapter for Device {
fn init(&mut self, objects: &mut KmsObjects<Self>) {
// FIXME enumerate actual connectors
for (framebuffer_id, _) in self.framebuffers.iter().enumerate() {
let crtc = objects.add_crtc(());
let crtc = objects.add_crtc((), ());
objects.add_connector(Connector { framebuffer_id }, &[crtc]);
objects.add_connector(Connector { framebuffer_id }, (), &[crtc]);
}
}
@@ -86,12 +90,12 @@ impl GraphicsAdapter for Device {
damage: Damage,
) {
let mut crtc = crtc.lock().unwrap();
crtc.mode = mode;
crtc.state.mode = mode;
for connector in objects.connectors() {
let connector = connector.lock().unwrap();
if connector.crtc_id != objects.crtc_ids()[crtc.crtc_index as usize] {
if connector.state.crtc_id != objects.crtc_ids()[crtc.crtc_index as usize] {
continue;
}
+9 -4
View File
@@ -3,7 +3,7 @@ use std::convert::TryInto;
use std::ptr::{self, NonNull};
use std::sync::Mutex;
use driver_graphics::kms::connector::KmsConnectorStatus;
use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus};
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
use driver_graphics::{Buffer, CursorPlane, Damage, GraphicsAdapter};
use drm_sys::{drm_mode_modeinfo, DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
@@ -21,6 +21,10 @@ pub struct Connector {
framebuffer_id: usize,
}
impl KmsConnectorDriver for Connector {
type State = ();
}
impl GraphicsAdapter for FbAdapter {
type Connector = Connector;
type Crtc = ();
@@ -38,7 +42,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 = objects.add_crtc((), ());
objects.add_connector(
Connector {
@@ -46,6 +50,7 @@ impl GraphicsAdapter for FbAdapter {
height: framebuffer.height as u32,
framebuffer_id,
},
(),
&[crtc],
);
}
@@ -93,12 +98,12 @@ impl GraphicsAdapter for FbAdapter {
damage: Damage,
) {
let mut crtc = crtc.lock().unwrap();
crtc.mode = mode;
crtc.state.mode = mode;
for connector in objects.connectors() {
let connector = connector.lock().unwrap();
if connector.crtc_id != objects.crtc_ids()[crtc.crtc_index as usize] {
if connector.state.crtc_id != objects.crtc_ids()[crtc.crtc_index as usize] {
continue;
}
+9 -5
View File
@@ -2,7 +2,7 @@ use std::fmt;
use std::sync::{Arc, Mutex};
use common::{dma::Dma, sgl};
use driver_graphics::kms::connector::KmsConnectorStatus;
use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus};
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
use driver_graphics::{Buffer as DrmBuffer, CursorPlane, Damage, GraphicsAdapter, GraphicsScheme};
use drm_sys::{
@@ -33,6 +33,10 @@ pub struct VirtGpuConnector {
display_id: u32,
}
impl KmsConnectorDriver for VirtGpuConnector {
type State = ();
}
pub struct VirtGpuFramebuffer<'a> {
queue: Arc<Queue<'a>>,
id: ResourceId,
@@ -284,9 +288,9 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
});
for display_id in 0..self.config.num_scanouts.get() {
let crtc = objects.add_crtc(());
let crtc = objects.add_crtc((), ());
objects.add_connector(VirtGpuConnector { display_id }, &[crtc]);
objects.add_connector(VirtGpuConnector { display_id }, (), &[crtc]);
}
}
@@ -408,12 +412,12 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
) {
futures::executor::block_on(async {
let mut crtc = crtc.lock().unwrap();
crtc.mode = mode;
crtc.state.mode = mode;
for connector in objects.connectors() {
let connector = connector.lock().unwrap();
if connector.crtc_id != objects.crtc_ids()[crtc.crtc_index as usize] {
if connector.state.crtc_id != objects.crtc_ids()[crtc.crtc_index as usize] {
continue;
}