Merge branch 'gpu_drm31' into 'main'
Some more preparations for atomic modesetting See merge request redox-os/base!187
This commit is contained in:
@@ -58,15 +58,13 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
&self.connectors
|
||||
}
|
||||
|
||||
pub fn connectors(
|
||||
&self,
|
||||
) -> impl Iterator<Item = &Mutex<KmsConnector<T::Connector>>> + use<'_, T> {
|
||||
pub fn connectors(&self) -> impl Iterator<Item = &Mutex<KmsConnector<T>>> + use<'_, T> {
|
||||
self.connectors
|
||||
.iter()
|
||||
.map(|&id| self.get_connector(id).unwrap())
|
||||
}
|
||||
|
||||
pub fn get_connector(&self, id: KmsObjectId) -> Result<&Mutex<KmsConnector<T::Connector>>> {
|
||||
pub fn get_connector(&self, id: KmsObjectId) -> Result<&Mutex<KmsConnector<T>>> {
|
||||
self.get(id)
|
||||
}
|
||||
|
||||
@@ -88,7 +86,7 @@ impl KmsConnectorDriver for () {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct KmsConnector<T: KmsConnectorDriver> {
|
||||
pub struct KmsConnector<T: GraphicsAdapter> {
|
||||
pub encoder_id: KmsObjectId,
|
||||
pub modes: Vec<drm_mode_modeinfo>,
|
||||
pub connector_type: u32,
|
||||
@@ -99,18 +97,28 @@ pub struct KmsConnector<T: KmsConnectorDriver> {
|
||||
pub subpixel: DrmSubpixelOrder,
|
||||
pub properties: Vec<KmsPropertyData<Self>>,
|
||||
pub edid: KmsObjectId,
|
||||
pub state: KmsConnectorState<T::State>,
|
||||
pub driver_data: T,
|
||||
pub state: KmsConnectorState<T>,
|
||||
pub driver_data: T::Connector,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct KmsConnectorState<T> {
|
||||
#[derive(Debug)]
|
||||
pub struct KmsConnectorState<T: GraphicsAdapter> {
|
||||
pub dpms: KmsDpms,
|
||||
pub crtc_id: KmsObjectId,
|
||||
pub driver_data: T,
|
||||
pub driver_data: <T::Connector as KmsConnectorDriver>::State,
|
||||
}
|
||||
|
||||
define_object_props!(object, KmsConnector<T: KmsConnectorDriver> {
|
||||
impl<T: GraphicsAdapter> Clone for KmsConnectorState<T> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
dpms: self.dpms.clone(),
|
||||
crtc_id: self.crtc_id.clone(),
|
||||
driver_data: self.driver_data.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_object_props!(object, KmsConnector<T: GraphicsAdapter> {
|
||||
EDID {
|
||||
get => u64::from(object.edid.0),
|
||||
}
|
||||
@@ -122,9 +130,9 @@ define_object_props!(object, KmsConnector<T: KmsConnectorDriver> {
|
||||
}
|
||||
});
|
||||
|
||||
impl<T: KmsConnectorDriver> KmsConnector<T> {
|
||||
impl<T: GraphicsAdapter> KmsConnector<T> {
|
||||
pub fn update_from_size(&mut self, width: u32, height: u32) {
|
||||
self.modes = vec![Self::modeinfo_for_size(width, height)];
|
||||
self.modes = vec![modeinfo_for_size(width, height)];
|
||||
}
|
||||
|
||||
pub fn update_from_edid(&mut self, edid: &[u8]) {
|
||||
@@ -151,7 +159,7 @@ impl<T: KmsConnectorDriver> KmsConnector<T> {
|
||||
match descriptor {
|
||||
edid::Descriptor::DetailedTiming(detailed_timing) => {
|
||||
// FIXME extract full information
|
||||
Some(Self::modeinfo_for_size(
|
||||
Some(modeinfo_for_size(
|
||||
u32::from(detailed_timing.horizontal_active_pixels),
|
||||
u32::from(detailed_timing.vertical_active_lines),
|
||||
))
|
||||
@@ -168,40 +176,40 @@ impl<T: KmsConnectorDriver> KmsConnector<T> {
|
||||
|
||||
// FIXME update the EDID property
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn modeinfo_for_size(width: u32, height: u32) -> drm_mode_modeinfo {
|
||||
let mut modeinfo = drm_mode_modeinfo {
|
||||
// The actual visible display size
|
||||
hdisplay: width as u16,
|
||||
vdisplay: height as u16,
|
||||
pub(crate) fn modeinfo_for_size(width: u32, height: u32) -> drm_mode_modeinfo {
|
||||
let mut modeinfo = drm_mode_modeinfo {
|
||||
// The actual visible display size
|
||||
hdisplay: width as u16,
|
||||
vdisplay: height as u16,
|
||||
|
||||
// These are used to calculate the refresh rate
|
||||
clock: 60 * width * height / 1000,
|
||||
htotal: width as u16,
|
||||
vtotal: height as u16,
|
||||
vscan: 0,
|
||||
vrefresh: 60,
|
||||
// These are used to calculate the refresh rate
|
||||
clock: 60 * width * height / 1000,
|
||||
htotal: width as u16,
|
||||
vtotal: height as u16,
|
||||
vscan: 0,
|
||||
vrefresh: 60,
|
||||
|
||||
type_: drm_sys::DRM_MODE_TYPE_PREFERRED | drm_sys::DRM_MODE_TYPE_DRIVER,
|
||||
name: [0; 32],
|
||||
type_: drm_sys::DRM_MODE_TYPE_PREFERRED | drm_sys::DRM_MODE_TYPE_DRIVER,
|
||||
name: [0; 32],
|
||||
|
||||
// These only matter when modesetting physical display adapters. For
|
||||
// those we should be able to parse the EDID blob.
|
||||
hsync_start: width as u16,
|
||||
hsync_end: width as u16,
|
||||
hskew: 0,
|
||||
vsync_start: height as u16,
|
||||
vsync_end: height as u16,
|
||||
flags: 0,
|
||||
};
|
||||
// These only matter when modesetting physical display adapters. For
|
||||
// those we should be able to parse the EDID blob.
|
||||
hsync_start: width as u16,
|
||||
hsync_end: width as u16,
|
||||
hskew: 0,
|
||||
vsync_start: height as u16,
|
||||
vsync_end: height as u16,
|
||||
flags: 0,
|
||||
};
|
||||
|
||||
let name = format!("{width}x{height}").into_bytes();
|
||||
for (to, from) in modeinfo.name.iter_mut().zip(name) {
|
||||
*to = from as c_char;
|
||||
}
|
||||
|
||||
modeinfo
|
||||
let name = format!("{width}x{height}").into_bytes();
|
||||
for (to, from) in modeinfo.name.iter_mut().zip(name) {
|
||||
*to = from as c_char;
|
||||
}
|
||||
|
||||
modeinfo
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
||||
@@ -22,7 +22,7 @@ pub struct KmsObjects<T: GraphicsAdapter> {
|
||||
pub(crate) encoders: Vec<KmsObjectId>,
|
||||
crtcs: Vec<KmsObjectId>,
|
||||
framebuffers: Vec<KmsObjectId>,
|
||||
pub(crate) objects: HashMap<KmsObjectId, Arc<KmsObject<T>>>,
|
||||
pub(crate) objects: HashMap<KmsObjectId, KmsObject<T>>,
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
|
||||
pub(crate) fn add<U: Into<KmsObject<T>>>(&mut self, data: U) -> KmsObjectId {
|
||||
let id = self.next_id;
|
||||
self.objects.insert(id, Arc::new(data.into()));
|
||||
self.objects.insert(id, data.into());
|
||||
self.next_id.0 += 1;
|
||||
|
||||
id
|
||||
@@ -54,7 +54,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
&'a U: TryFrom<&'a KmsObject<T>>,
|
||||
{
|
||||
let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?;
|
||||
if let Ok(object) = (&**object).try_into() {
|
||||
if let Ok(object) = object.try_into() {
|
||||
Ok(object)
|
||||
} else {
|
||||
Err(Error::new(EINVAL))
|
||||
@@ -77,7 +77,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
gamma_size: 0,
|
||||
properties: KmsCrtc::base_properties(),
|
||||
state: KmsCrtcState {
|
||||
fb_id: KmsObjectId::INVALID,
|
||||
fb_id: None,
|
||||
mode: None,
|
||||
driver_data: driver_data_state,
|
||||
},
|
||||
@@ -92,27 +92,24 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
&self.crtcs
|
||||
}
|
||||
|
||||
pub fn crtcs(&self) -> impl Iterator<Item = &Mutex<KmsCrtc<T::Crtc>>> + use<'_, T> {
|
||||
pub fn crtcs(&self) -> impl Iterator<Item = &Mutex<KmsCrtc<T>>> + use<'_, T> {
|
||||
self.crtcs
|
||||
.iter()
|
||||
.map(|&id| self.get::<Mutex<KmsCrtc<T::Crtc>>>(id).unwrap())
|
||||
.map(|&id| self.get::<Mutex<KmsCrtc<T>>>(id).unwrap())
|
||||
}
|
||||
|
||||
pub fn get_crtc(&self, id: KmsObjectId) -> Result<&Mutex<KmsCrtc<T::Crtc>>> {
|
||||
pub fn get_crtc(&self, id: KmsObjectId) -> Result<&Mutex<KmsCrtc<T>>> {
|
||||
self.get(id)
|
||||
}
|
||||
|
||||
pub fn add_framebuffer(
|
||||
&mut self,
|
||||
fb: KmsFramebuffer<T::Framebuffer, T::Buffer>,
|
||||
) -> KmsObjectId {
|
||||
pub fn add_framebuffer(&mut self, fb: KmsFramebuffer<T>) -> KmsObjectId {
|
||||
let id = self.add(fb);
|
||||
self.framebuffers.push(id);
|
||||
id
|
||||
}
|
||||
|
||||
pub fn remove_framebuffer(&mut self, id: KmsObjectId) -> Result<()> {
|
||||
let Some(object) = self.objects.get(&id).map(|object| &**object) else {
|
||||
let Some(object) = self.objects.get(&id) else {
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
let KmsObject::Framebuffer(_) = object else {
|
||||
@@ -127,10 +124,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
&self.framebuffers
|
||||
}
|
||||
|
||||
pub fn get_framebuffer(
|
||||
&self,
|
||||
id: KmsObjectId,
|
||||
) -> Result<&KmsFramebuffer<T::Framebuffer, T::Buffer>> {
|
||||
pub fn get_framebuffer(&self, id: KmsObjectId) -> Result<&KmsFramebuffer<T>> {
|
||||
self.get(id)
|
||||
}
|
||||
}
|
||||
@@ -187,11 +181,11 @@ macro_rules! define_object_kinds {
|
||||
}
|
||||
|
||||
define_object_kinds! { <T>
|
||||
Crtc(Mutex<KmsCrtc<T::Crtc>>) = DRM_MODE_OBJECT_CRTC,
|
||||
Connector(Mutex<KmsConnector<T::Connector>>) = DRM_MODE_OBJECT_CONNECTOR,
|
||||
Crtc(Mutex<KmsCrtc<T>>) = DRM_MODE_OBJECT_CRTC,
|
||||
Connector(Mutex<KmsConnector<T>>) = DRM_MODE_OBJECT_CONNECTOR,
|
||||
Encoder(KmsEncoder) = DRM_MODE_OBJECT_ENCODER,
|
||||
Property(KmsProperty) = DRM_MODE_OBJECT_PROPERTY,
|
||||
Framebuffer(KmsFramebuffer<T::Framebuffer, T::Buffer>) = DRM_MODE_OBJECT_FB,
|
||||
Framebuffer(KmsFramebuffer<T>) = DRM_MODE_OBJECT_FB,
|
||||
Blob(KmsBlob) = DRM_MODE_OBJECT_BLOB,
|
||||
}
|
||||
|
||||
@@ -204,30 +198,40 @@ impl KmsCrtcDriver for () {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct KmsCrtc<T: KmsCrtcDriver> {
|
||||
pub struct KmsCrtc<T: GraphicsAdapter> {
|
||||
pub crtc_index: u32,
|
||||
pub gamma_size: u32,
|
||||
pub properties: Vec<KmsPropertyData<Self>>,
|
||||
pub state: KmsCrtcState<T::State>,
|
||||
pub driver_data: T,
|
||||
pub state: KmsCrtcState<T>,
|
||||
pub driver_data: T::Crtc,
|
||||
}
|
||||
|
||||
#[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> {
|
||||
pub struct KmsCrtcState<T: GraphicsAdapter> {
|
||||
pub fb_id: Option<KmsObjectId>,
|
||||
pub mode: Option<drm_mode_modeinfo>,
|
||||
pub driver_data: <T::Crtc as KmsCrtcDriver>::State,
|
||||
}
|
||||
|
||||
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(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
define_object_props!(object, KmsCrtc<T: GraphicsAdapter> {});
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct KmsFramebuffer<T: GraphicsAdapter> {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
pub pitch: u32,
|
||||
pub bpp: u32,
|
||||
pub depth: u32,
|
||||
pub buffer: Arc<Buf>,
|
||||
pub driver_data: T,
|
||||
pub buffer: Arc<T::Buffer>,
|
||||
pub driver_data: T::Framebuffer,
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
|
||||
pub fn get_object_properties_data(&self, id: KmsObjectId) -> Result<(Vec<u32>, Vec<u64>)> {
|
||||
let object = self.objects.get(&id).ok_or(Error::new(EINVAL))?;
|
||||
match &**object {
|
||||
match object {
|
||||
KmsObject::Crtc(crtc) => {
|
||||
let crtc = crtc.lock().unwrap();
|
||||
let props = &crtc.properties;
|
||||
|
||||
@@ -10,9 +10,9 @@ use std::{cmp, mem};
|
||||
|
||||
use drm_fourcc::DrmFourcc;
|
||||
use drm_sys::{
|
||||
drm_mode_modeinfo, drm_mode_property_enum, DRM_MODE_CURSOR_BO, DRM_MODE_CURSOR_MOVE,
|
||||
DRM_MODE_PROP_ATOMIC, DRM_MODE_PROP_BITMASK, DRM_MODE_PROP_BLOB, DRM_MODE_PROP_ENUM,
|
||||
DRM_MODE_PROP_IMMUTABLE, DRM_MODE_PROP_OBJECT, DRM_MODE_PROP_RANGE, DRM_MODE_PROP_SIGNED_RANGE,
|
||||
drm_mode_property_enum, DRM_MODE_CURSOR_BO, DRM_MODE_CURSOR_MOVE, DRM_MODE_PROP_ATOMIC,
|
||||
DRM_MODE_PROP_BITMASK, DRM_MODE_PROP_BLOB, DRM_MODE_PROP_ENUM, DRM_MODE_PROP_IMMUTABLE,
|
||||
DRM_MODE_PROP_OBJECT, DRM_MODE_PROP_RANGE, DRM_MODE_PROP_SIGNED_RANGE,
|
||||
};
|
||||
use inputd::{DisplayHandle, VtEventKind};
|
||||
use libredox::Fd;
|
||||
@@ -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, KmsConnectorDriver};
|
||||
use crate::kms::objects::{self, KmsCrtc, KmsCrtcDriver, KmsObjectId, KmsObjects};
|
||||
use crate::kms::connector::{KmsConnectorDriver, KmsConnectorState};
|
||||
use crate::kms::objects::{self, KmsCrtc, KmsCrtcDriver, KmsCrtcState, KmsObjectId, KmsObjects};
|
||||
use crate::kms::properties::KmsPropertyKind;
|
||||
|
||||
pub mod kms;
|
||||
@@ -102,11 +102,10 @@ pub trait GraphicsAdapter: Sized + Debug {
|
||||
fn set_crtc(
|
||||
&mut self,
|
||||
objects: &KmsObjects<Self>,
|
||||
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
|
||||
mode: Option<drm_mode_modeinfo>,
|
||||
framebuffer: Option<&objects::KmsFramebuffer<Self::Framebuffer, Self::Buffer>>,
|
||||
crtc: &Mutex<KmsCrtc<Self>>,
|
||||
new_state: KmsCrtcState<Self>,
|
||||
damage: Damage,
|
||||
);
|
||||
) -> syscall::Result<()>;
|
||||
|
||||
fn hw_cursor_size(&self) -> Option<(u32, u32)>;
|
||||
fn handle_cursor(&mut self, cursor: &CursorPlane<Self::Buffer>, dirty_fb: bool);
|
||||
@@ -236,35 +235,46 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
|
||||
vt_event.vt,
|
||||
);
|
||||
|
||||
for (display_id, fb) in vt_state.display_fbs.iter().enumerate() {
|
||||
let crtc_id = self.inner.objects.crtc_ids()[display_id];
|
||||
for (connector_idx, connector_state) in
|
||||
vt_state.connector_state.iter().enumerate()
|
||||
{
|
||||
let connector_id = self.inner.objects.connector_ids()[connector_idx];
|
||||
let mut connector = self
|
||||
.inner
|
||||
.objects
|
||||
.get_connector(connector_id)
|
||||
.unwrap()
|
||||
.lock()
|
||||
.unwrap();
|
||||
connector.state = connector_state.clone();
|
||||
}
|
||||
|
||||
for (crtc_idx, crtc_state) in vt_state.crtc_state.iter().enumerate() {
|
||||
let crtc_id = self.inner.objects.crtc_ids()[crtc_idx];
|
||||
let crtc = self.inner.objects.get_crtc(crtc_id).unwrap();
|
||||
let connector_id = self.inner.objects.connector_ids()[display_id];
|
||||
let connector_id = self.inner.objects.connector_ids()[crtc_idx];
|
||||
|
||||
crtc.lock().unwrap().state.fb_id = fb.unwrap_or(KmsObjectId::INVALID);
|
||||
|
||||
let fb = fb.map(|fb| {
|
||||
let fb = crtc_state.fb_id.map(|fb_id| {
|
||||
self.inner
|
||||
.objects
|
||||
.get_framebuffer(fb)
|
||||
.get_framebuffer(fb_id)
|
||||
.expect("removed framebuffers should be unset")
|
||||
});
|
||||
|
||||
let mode =
|
||||
fb.map(|fb| KmsConnector::<()>::modeinfo_for_size(fb.width, fb.height));
|
||||
|
||||
self.inner.adapter.set_crtc(
|
||||
&self.inner.objects,
|
||||
crtc,
|
||||
mode,
|
||||
fb,
|
||||
Damage {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: fb.map_or(0, |fb| fb.width),
|
||||
height: fb.map_or(0, |fb| fb.height),
|
||||
},
|
||||
);
|
||||
self.inner
|
||||
.adapter
|
||||
.set_crtc(
|
||||
&self.inner.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),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
self.inner
|
||||
.objects
|
||||
@@ -344,7 +354,8 @@ struct GraphicsSchemeInner<T: GraphicsAdapter> {
|
||||
}
|
||||
|
||||
struct VtState<T: GraphicsAdapter> {
|
||||
display_fbs: Vec<Option<KmsObjectId>>,
|
||||
connector_state: Vec<KmsConnectorState<T>>,
|
||||
crtc_state: Vec<KmsCrtcState<T>>,
|
||||
cursor_plane: CursorPlane<T::Buffer>,
|
||||
}
|
||||
|
||||
@@ -364,7 +375,14 @@ impl<T: GraphicsAdapter> GraphicsSchemeInner<T> {
|
||||
vt: usize,
|
||||
) -> &'a mut VtState<T> {
|
||||
vts.entry(vt).or_insert_with(|| VtState {
|
||||
display_fbs: vec![None; objects.crtc_ids().len()],
|
||||
connector_state: objects
|
||||
.connectors()
|
||||
.map(|connector| connector.lock().unwrap().state.clone())
|
||||
.collect(),
|
||||
crtc_state: objects
|
||||
.crtcs()
|
||||
.map(|crtc| crtc.lock().unwrap().state.clone())
|
||||
.collect(),
|
||||
cursor_plane: CursorPlane {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -539,7 +557,7 @@ 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.0);
|
||||
data.set_fb_id(crtc.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);
|
||||
@@ -555,15 +573,14 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
}),
|
||||
ipc::MODE_SET_CRTC => ipc::DrmModeCrtc::with(payload, |data| {
|
||||
let crtc = self.objects.get_crtc(KmsObjectId(data.crtc_id()))?;
|
||||
let display_id = crtc.lock().unwrap().crtc_index as usize;
|
||||
let connector_ids: Vec<KmsObjectId> = data
|
||||
.set_connectors_ptr()
|
||||
.iter()
|
||||
.take(data.count_connectors() as usize)
|
||||
.map(|&id| KmsObjectId(id))
|
||||
.collect();
|
||||
let fb = if data.fb_id() != 0 {
|
||||
Some(self.objects.get_framebuffer(KmsObjectId(data.fb_id()))?)
|
||||
let fb_id = if data.fb_id() != 0 {
|
||||
Some(KmsObjectId(data.fb_id()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
@@ -572,20 +589,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;
|
||||
if *vt == self.active_vt {
|
||||
self.adapter.set_crtc(
|
||||
&self.objects,
|
||||
crtc,
|
||||
mode,
|
||||
fb.as_deref(),
|
||||
new_state.clone(),
|
||||
Damage {
|
||||
x: data.x(),
|
||||
y: data.y(),
|
||||
width: mode.map_or(0, |m| m.hdisplay as u32),
|
||||
height: mode.map_or(0, |m| m.vdisplay as u32),
|
||||
},
|
||||
);
|
||||
crtc.lock().unwrap().state.fb_id = KmsObjectId(data.fb_id());
|
||||
)?;
|
||||
|
||||
for connector in connector_ids {
|
||||
self.objects
|
||||
@@ -596,11 +614,8 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
.crtc_id = KmsObjectId(data.crtc_id());
|
||||
}
|
||||
}
|
||||
self.vts.get_mut(vt).unwrap().display_fbs[display_id] = if data.fb_id() != 0 {
|
||||
Some(KmsObjectId(data.fb_id()))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
self.vts.get_mut(vt).unwrap().crtc_state
|
||||
[crtc.lock().unwrap().crtc_index as usize] = new_state;
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_CURSOR => ipc::DrmModeCursor::with(payload, |data| {
|
||||
@@ -772,29 +787,29 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
|
||||
// Disable planes that use this framebuffer.
|
||||
for (vt, vt_data) in &mut self.vts {
|
||||
for (display_id, fb) in vt_data.display_fbs.iter_mut().enumerate() {
|
||||
if *fb != Some(fb_id) {
|
||||
for (crtc_idx, crtc_state) in vt_data.crtc_state.iter_mut().enumerate() {
|
||||
if crtc_state.fb_id != Some(fb_id) {
|
||||
continue;
|
||||
}
|
||||
*fb = None;
|
||||
crtc_state.fb_id = None;
|
||||
|
||||
if *vt != self.active_vt {
|
||||
continue;
|
||||
}
|
||||
let crtc = self.objects.crtcs().nth(display_id).unwrap();
|
||||
crtc.lock().unwrap().state.fb_id = KmsObjectId::INVALID;
|
||||
self.adapter.set_crtc(
|
||||
&self.objects,
|
||||
crtc,
|
||||
None,
|
||||
None,
|
||||
Damage {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
},
|
||||
);
|
||||
let crtc = self.objects.crtcs().nth(crtc_idx).unwrap();
|
||||
self.adapter
|
||||
.set_crtc(
|
||||
&self.objects,
|
||||
crtc,
|
||||
crtc_state.clone(),
|
||||
Damage {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -822,10 +837,9 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
|
||||
if *vt == self.active_vt {
|
||||
for crtc in self.objects.crtcs() {
|
||||
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);
|
||||
let state = crtc.lock().unwrap().state.clone();
|
||||
if state.fb_id == Some(KmsObjectId(data.fb_id())) {
|
||||
self.adapter.set_crtc(&self.objects, crtc, state, damage)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -887,7 +901,14 @@ 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().state.fb_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)
|
||||
|
||||
@@ -404,7 +404,7 @@ impl Device {
|
||||
let buffers = 1024;
|
||||
//TODO: how to use 64-bit surface addresses?
|
||||
let surface_memory = gm.size.min(u32::max_value() as usize) as u32;
|
||||
let mut this = Self {
|
||||
Ok(Self {
|
||||
kind,
|
||||
alloc_buffers: RangeAllocator::new(0..buffers),
|
||||
alloc_surfaces: RangeAllocator::new(0..surface_memory),
|
||||
@@ -422,12 +422,10 @@ impl Device {
|
||||
power_wells,
|
||||
ref_freq,
|
||||
transcoders,
|
||||
};
|
||||
this.init()?;
|
||||
Ok(this)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn init(&mut self) -> Result<()> {
|
||||
pub fn init_inner(&mut self) {
|
||||
// Discover current framebuffers
|
||||
self.alloc_buffers.reset();
|
||||
self.alloc_surfaces.reset();
|
||||
@@ -440,15 +438,12 @@ impl Device {
|
||||
let buffer_end = (buf_cfg >> 16) & 0x7FF;
|
||||
self.alloc_buffers
|
||||
.allocate_exact_range(buffer_start..(buffer_end + 1))
|
||||
.map_err(|err| {
|
||||
log::warn!(
|
||||
.unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"failed to allocate pre-existing buffer blocks {} to {}: {:?}",
|
||||
buffer_start,
|
||||
buffer_end,
|
||||
err
|
||||
buffer_start, buffer_end, err
|
||||
);
|
||||
Error::new(EIO)
|
||||
})?;
|
||||
});
|
||||
|
||||
let size = plane.size.read();
|
||||
let width = (size & 0xFFFF) + 1;
|
||||
@@ -459,10 +454,9 @@ impl Device {
|
||||
let surf = plane.surf.read() & 0xFFFFF000;
|
||||
//TODO: read bits per pixel
|
||||
let surf_size = (stride * height * 4).next_multiple_of(4096);
|
||||
self.alloc_surfaces.allocate_exact_range(surf .. (surf + surf_size)).map_err(|err| {
|
||||
log::warn!("failed to allocate pre-existing surface at 0x{:x} of size {}: {:?}", surf, surf_size, err);
|
||||
Error::new(EIO)
|
||||
})?;
|
||||
self.alloc_surfaces.allocate_exact_range(surf .. (surf + surf_size)).unwrap_or_else(|err| {
|
||||
panic!("failed to allocate pre-existing surface at 0x{:x} of size {}: {:?}", surf, surf_size, err);
|
||||
});
|
||||
|
||||
self.framebuffers.push(unsafe {
|
||||
DeviceFb::new(
|
||||
@@ -480,7 +474,7 @@ impl Device {
|
||||
// Probe all DDIs
|
||||
let ddi_names: Vec<&str> = self.ddis.iter().map(|ddi| ddi.name).collect();
|
||||
for ddi_name in ddi_names {
|
||||
self.probe_ddi(ddi_name)?;
|
||||
self.probe_ddi(ddi_name).expect("failed to probe DDI");
|
||||
}
|
||||
|
||||
self.dump();
|
||||
@@ -517,8 +511,6 @@ impl Device {
|
||||
for change_detect in self.int.change_detects.iter_mut() {
|
||||
change_detect.log();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn dump(&self) {
|
||||
|
||||
@@ -6,9 +6,9 @@ use std::ptr::{self, NonNull};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus};
|
||||
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, 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};
|
||||
use drm_sys::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
|
||||
use syscall::{error::EINVAL, PAGE_SIZE};
|
||||
|
||||
use super::Device;
|
||||
@@ -38,6 +38,8 @@ impl GraphicsAdapter for Device {
|
||||
}
|
||||
|
||||
fn init(&mut self, objects: &mut KmsObjects<Self>) {
|
||||
self.init_inner();
|
||||
|
||||
// FIXME enumerate actual connectors
|
||||
for (framebuffer_id, _) in self.framebuffers.iter().enumerate() {
|
||||
let crtc = objects.add_crtc((), ());
|
||||
@@ -84,13 +86,16 @@ impl GraphicsAdapter for Device {
|
||||
fn set_crtc(
|
||||
&mut self,
|
||||
objects: &KmsObjects<Self>,
|
||||
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
|
||||
mode: Option<drm_mode_modeinfo>,
|
||||
buffer: Option<&objects::KmsFramebuffer<Self::Framebuffer, Self::Buffer>>,
|
||||
crtc: &Mutex<KmsCrtc<Self>>,
|
||||
state: KmsCrtcState<Self>,
|
||||
damage: Damage,
|
||||
) {
|
||||
) -> syscall::Result<()> {
|
||||
let mut crtc = crtc.lock().unwrap();
|
||||
crtc.state.mode = mode;
|
||||
let buffer = state
|
||||
.fb_id
|
||||
.map(|fb_id| objects.get_framebuffer(fb_id))
|
||||
.transpose()?;
|
||||
crtc.state = state;
|
||||
|
||||
for connector in objects.connectors() {
|
||||
let connector = connector.lock().unwrap();
|
||||
@@ -117,6 +122,8 @@ impl GraphicsAdapter for Device {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn hw_cursor_size(&self) -> Option<(u32, u32)> {
|
||||
|
||||
@@ -4,9 +4,9 @@ use std::ptr::{self, NonNull};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus};
|
||||
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, 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};
|
||||
use drm_sys::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
|
||||
use syscall::{EINVAL, PAGE_SIZE};
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -92,13 +92,16 @@ impl GraphicsAdapter for FbAdapter {
|
||||
fn set_crtc(
|
||||
&mut self,
|
||||
objects: &KmsObjects<Self>,
|
||||
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
|
||||
mode: Option<drm_mode_modeinfo>,
|
||||
buffer: Option<&objects::KmsFramebuffer<Self::Framebuffer, Self::Buffer>>,
|
||||
crtc: &Mutex<KmsCrtc<Self>>,
|
||||
state: KmsCrtcState<Self>,
|
||||
damage: Damage,
|
||||
) {
|
||||
) -> syscall::Result<()> {
|
||||
let mut crtc = crtc.lock().unwrap();
|
||||
crtc.state.mode = mode;
|
||||
let buffer = state
|
||||
.fb_id
|
||||
.map(|fb_id| objects.get_framebuffer(fb_id))
|
||||
.transpose()?;
|
||||
crtc.state = state;
|
||||
|
||||
for connector in objects.connectors() {
|
||||
let connector = connector.lock().unwrap();
|
||||
@@ -125,6 +128,8 @@ impl GraphicsAdapter for FbAdapter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn hw_cursor_size(&self) -> Option<(u32, u32)> {
|
||||
|
||||
@@ -3,10 +3,10 @@ use std::sync::{Arc, Mutex};
|
||||
|
||||
use common::{dma::Dma, sgl};
|
||||
use driver_graphics::kms::connector::{KmsConnectorDriver, KmsConnectorStatus};
|
||||
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::kms::objects::{KmsCrtc, KmsCrtcState, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::{Buffer as DrmBuffer, CursorPlane, Damage, GraphicsAdapter, GraphicsScheme};
|
||||
use drm_sys::{
|
||||
drm_mode_modeinfo, DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_CAP_DUMB_BUFFER,
|
||||
DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH, DRM_CAP_DUMB_BUFFER,
|
||||
DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT,
|
||||
};
|
||||
|
||||
@@ -405,14 +405,17 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
fn set_crtc(
|
||||
&mut self,
|
||||
objects: &KmsObjects<Self>,
|
||||
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
|
||||
mode: Option<drm_mode_modeinfo>,
|
||||
framebuffer: Option<&objects::KmsFramebuffer<Self::Framebuffer, Self::Buffer>>,
|
||||
crtc: &Mutex<KmsCrtc<Self>>,
|
||||
state: KmsCrtcState<Self>,
|
||||
damage: Damage,
|
||||
) {
|
||||
) -> syscall::Result<()> {
|
||||
futures::executor::block_on(async {
|
||||
let mut crtc = crtc.lock().unwrap();
|
||||
crtc.state.mode = mode;
|
||||
let framebuffer = state
|
||||
.fb_id
|
||||
.map(|fb_id| objects.get_framebuffer(fb_id))
|
||||
.transpose()?;
|
||||
crtc.state = state;
|
||||
|
||||
for connector in objects.connectors() {
|
||||
let connector = connector.lock().unwrap();
|
||||
@@ -433,7 +436,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
let header = self.send_request(scanout_request).await.unwrap();
|
||||
assert_eq!(header.ty, CommandTy::RespOkNodata);
|
||||
self.displays[display_id as usize].active_resource = None;
|
||||
return;
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let req = Dma::new(XferToHost2d::new(
|
||||
@@ -472,7 +475,9 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
let header = self.send_request(Dma::new(flush).unwrap()).await.unwrap();
|
||||
assert_eq!(header.ty, CommandTy::RespOkNodata);
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
fn hw_cursor_size(&self) -> Option<(u32, u32)> {
|
||||
|
||||
Reference in New Issue
Block a user