Merge branch 'gpu_drm41' into 'main'
Support planes in the drm interface See merge request redox-os/base!266
This commit is contained in:
@@ -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![])),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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(())
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user