drivers/graphics: Split out state modified during atomic mode setting
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user