drivers/graphics: Implement proper support for framebuffers
Including support for creating and destroying framebuffers.
This commit is contained in:
@@ -5,7 +5,7 @@ use std::sync::{Arc, Mutex};
|
||||
|
||||
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_PROPERTY,
|
||||
DRM_MODE_OBJECT_ENCODER, DRM_MODE_OBJECT_FB, DRM_MODE_OBJECT_PROPERTY,
|
||||
};
|
||||
use syscall::{Error, Result, EINVAL};
|
||||
|
||||
@@ -19,6 +19,7 @@ pub struct KmsObjects<T: GraphicsAdapter> {
|
||||
pub(crate) connectors: Vec<KmsObjectId>,
|
||||
pub(crate) encoders: Vec<KmsObjectId>,
|
||||
crtcs: Vec<KmsObjectId>,
|
||||
framebuffers: Vec<KmsObjectId>,
|
||||
pub(crate) objects: HashMap<KmsObjectId, Arc<KmsObjectData<T>>>,
|
||||
_marker: PhantomData<T>,
|
||||
}
|
||||
@@ -30,6 +31,7 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
connectors: vec![],
|
||||
encoders: vec![],
|
||||
crtcs: vec![],
|
||||
framebuffers: vec![],
|
||||
objects: HashMap::new(),
|
||||
_marker: PhantomData,
|
||||
}
|
||||
@@ -93,6 +95,39 @@ impl<T: GraphicsAdapter> KmsObjects<T> {
|
||||
pub fn get_crtc(&self, id: KmsObjectId) -> Result<&Mutex<KmsCrtc<T::Crtc>>> {
|
||||
self.get(id)
|
||||
}
|
||||
|
||||
pub fn add_framebuffer(
|
||||
&mut self,
|
||||
fb: KmsFramebuffer<T::Framebuffer, T::Buffer>,
|
||||
) -> KmsObjectId {
|
||||
let id = self.add(fb);
|
||||
self.framebuffers.push(id);
|
||||
id
|
||||
}
|
||||
|
||||
pub fn remove_framebuffer(&mut self, id: KmsObjectId) -> Result<()> {
|
||||
let kind = match self.objects.get(&id).map(|object| &**object) {
|
||||
Some(KmsObjectData { kind, .. }) => kind,
|
||||
_ => return Err(Error::new(EINVAL)),
|
||||
};
|
||||
let KmsObjectKind::Framebuffer(_) = **kind else {
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
self.objects.remove(&id).unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn fb_ids(&self) -> &[KmsObjectId] {
|
||||
&self.framebuffers
|
||||
}
|
||||
|
||||
pub fn get_framebuffer(
|
||||
&self,
|
||||
id: KmsObjectId,
|
||||
) -> Result<&KmsFramebuffer<T::Framebuffer, T::Buffer>> {
|
||||
self.get(id)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
||||
@@ -158,6 +193,7 @@ define_object_kinds! { <T>
|
||||
Connector(Mutex<KmsConnector<T::Connector>>) = 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,
|
||||
Blob(KmsBlob) = DRM_MODE_OBJECT_BLOB,
|
||||
}
|
||||
|
||||
@@ -169,3 +205,14 @@ pub struct KmsCrtc<T> {
|
||||
pub mode: Option<drm_mode_modeinfo>,
|
||||
pub driver_data: T,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct KmsFramebuffer<T, Buf> {
|
||||
pub width: u32,
|
||||
pub height: u32,
|
||||
pub pitch: u32,
|
||||
pub bpp: u32,
|
||||
pub depth: u32,
|
||||
pub buffer: Arc<Buf>,
|
||||
pub driver_data: T,
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ use syscall::schemev2::NewFdFlags;
|
||||
use syscall::{Error, MapFlags, Result, EACCES, EAGAIN, EBADF, EINVAL, ENOENT, EOPNOTSUPP};
|
||||
|
||||
use crate::kms::connector::KmsConnector;
|
||||
use crate::kms::objects::{KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use crate::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use crate::kms::properties::KmsPropertyKind;
|
||||
|
||||
pub mod kms;
|
||||
@@ -42,6 +42,7 @@ pub trait GraphicsAdapter: Sized + Debug {
|
||||
type Crtc: Debug;
|
||||
|
||||
type Buffer: Buffer;
|
||||
type Framebuffer: Framebuffer;
|
||||
|
||||
fn name(&self) -> &'static [u8];
|
||||
fn desc(&self) -> &'static [u8];
|
||||
@@ -65,7 +66,9 @@ pub trait GraphicsAdapter: Sized + Debug {
|
||||
fn display_size(&self, display_id: usize) -> (u32, u32);
|
||||
|
||||
fn create_dumb_buffer(&mut self, width: u32, height: u32) -> Self::Buffer;
|
||||
fn map_dumb_buffer(&mut self, framebuffer: &Self::Buffer) -> *mut u8;
|
||||
fn map_dumb_buffer(&mut self, buffer: &Self::Buffer) -> *mut u8;
|
||||
|
||||
fn create_framebuffer(&mut self, buffer: &Self::Buffer) -> Self::Framebuffer;
|
||||
|
||||
fn set_crtc(
|
||||
&mut self,
|
||||
@@ -73,7 +76,7 @@ pub trait GraphicsAdapter: Sized + Debug {
|
||||
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
|
||||
connectors: &[KmsObjectId],
|
||||
mode: Option<drm_mode_modeinfo>,
|
||||
framebuffer: Option<&Self::Buffer>,
|
||||
framebuffer: Option<&objects::KmsFramebuffer<Self::Framebuffer, Self::Buffer>>,
|
||||
damage: Damage,
|
||||
);
|
||||
|
||||
@@ -86,7 +89,10 @@ pub trait Buffer: Debug {
|
||||
fn height(&self) -> u32;
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub trait Framebuffer: Debug {}
|
||||
|
||||
impl Framebuffer for () {}
|
||||
|
||||
pub struct CursorPlane<C: Buffer> {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
@@ -225,21 +231,29 @@ impl<T: GraphicsAdapter> GraphicsScheme<T> {
|
||||
for (display_id, fb) in vt_state.display_fbs.iter().enumerate() {
|
||||
let crtc = self.inner.objects.crtcs().nth(display_id).unwrap();
|
||||
|
||||
let mode = fb.as_ref().map(|fb| {
|
||||
KmsConnector::<()>::modeinfo_for_size(fb.width(), fb.height())
|
||||
crtc.lock().unwrap().fb_id = fb.unwrap_or(KmsObjectId::INVALID);
|
||||
|
||||
let fb = fb.map(|fb| {
|
||||
self.inner
|
||||
.objects
|
||||
.get_framebuffer(fb)
|
||||
.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,
|
||||
&[self.inner.objects.connector_ids()[display_id]],
|
||||
mode,
|
||||
fb.as_deref(),
|
||||
fb,
|
||||
Damage {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: fb.as_deref().map_or(0, |fb| fb.width()),
|
||||
height: fb.as_deref().map_or(0, |fb| fb.height()),
|
||||
width: fb.map_or(0, |fb| fb.width),
|
||||
height: fb.map_or(0, |fb| fb.height),
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -313,7 +327,7 @@ struct GraphicsSchemeInner<T: GraphicsAdapter> {
|
||||
}
|
||||
|
||||
struct VtState<T: GraphicsAdapter> {
|
||||
display_fbs: Vec<Option<Arc<T::Buffer>>>,
|
||||
display_fbs: Vec<Option<KmsObjectId>>,
|
||||
cursor_plane: CursorPlane<T::Buffer>,
|
||||
}
|
||||
|
||||
@@ -454,14 +468,6 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
id & 0xFF
|
||||
}
|
||||
|
||||
fn fb_id(i: u32) -> u32 {
|
||||
id_index(i) | (1 << 11)
|
||||
}
|
||||
|
||||
fn fb_handle_id(i: u32) -> u32 {
|
||||
id_index(i) | (1 << 12)
|
||||
}
|
||||
|
||||
fn plane_id(i: u32) -> u32 {
|
||||
id_index(i) | (1 << 13)
|
||||
}
|
||||
@@ -504,7 +510,6 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_CARD_RES => ipc::DrmModeCardRes::with(payload, |mut data| {
|
||||
let count = self.adapter.display_count();
|
||||
let conn_ids = self
|
||||
.objects
|
||||
.connector_ids()
|
||||
@@ -523,10 +528,12 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
.iter()
|
||||
.map(|id| id.0)
|
||||
.collect::<Vec<_>>();
|
||||
let mut fb_ids = Vec::with_capacity(count);
|
||||
for i in 0..(count as u32) {
|
||||
fb_ids.push(fb_id(i));
|
||||
}
|
||||
let fb_ids = self
|
||||
.objects
|
||||
.fb_ids()
|
||||
.iter()
|
||||
.map(|id| id.0)
|
||||
.collect::<Vec<_>>();
|
||||
data.set_fb_id_ptr(&fb_ids);
|
||||
data.set_crtc_id_ptr(&crtc_ids);
|
||||
data.set_connector_id_ptr(&conn_ids);
|
||||
@@ -711,18 +718,71 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_GET_FB => ipc::DrmModeFbCmd::with(payload, |mut data| {
|
||||
let i = id_index(data.fb_id());
|
||||
let (width, height) = self.adapter.display_size(i as usize);
|
||||
data.set_width(width);
|
||||
data.set_height(height);
|
||||
data.set_pitch(width * 4); //TODO: stride
|
||||
data.set_bpp(32);
|
||||
data.set_depth(24);
|
||||
data.set_handle(fb_handle_id(i));
|
||||
let fb = self.objects.get_framebuffer(KmsObjectId(data.fb_id()))?;
|
||||
|
||||
*next_id += 1;
|
||||
buffers.insert(*next_id, fb.buffer.clone());
|
||||
|
||||
data.set_width(fb.width);
|
||||
data.set_height(fb.height);
|
||||
data.set_pitch(fb.pitch);
|
||||
data.set_bpp(fb.bpp);
|
||||
data.set_depth(fb.depth);
|
||||
data.set_handle(*next_id);
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_ADD_FB => ipc::DrmModeFbCmd::with(payload, |mut data| {
|
||||
data.set_fb_id(fb_handle_id(data.handle()));
|
||||
let buffer = buffers.get(&data.handle()).ok_or(Error::new(EINVAL))?;
|
||||
|
||||
let fb = self.adapter.create_framebuffer(buffer);
|
||||
|
||||
let id = self.objects.add_framebuffer(objects::KmsFramebuffer {
|
||||
width: data.width(),
|
||||
height: data.height(),
|
||||
pitch: data.pitch(),
|
||||
bpp: data.bpp(),
|
||||
depth: data.depth(),
|
||||
buffer: buffer.clone(),
|
||||
driver_data: fb,
|
||||
});
|
||||
|
||||
data.set_fb_id(id.0);
|
||||
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_RM_FB => ipc::StandinForUint::with(payload, |data| {
|
||||
let fb_id = KmsObjectId(data.inner());
|
||||
self.objects.remove_framebuffer(fb_id)?;
|
||||
|
||||
// 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) {
|
||||
continue;
|
||||
}
|
||||
*fb = None;
|
||||
|
||||
if *vt != self.active_vt {
|
||||
continue;
|
||||
}
|
||||
let crtc = self.objects.crtcs().nth(display_id).unwrap();
|
||||
crtc.lock().unwrap().fb_id = KmsObjectId::INVALID;
|
||||
self.adapter.set_crtc(
|
||||
&self.objects,
|
||||
crtc,
|
||||
&[self.objects.connector_ids()[display_id]],
|
||||
None,
|
||||
None,
|
||||
Damage {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_CREATE_DUMB => ipc::DrmModeCreateDumb::with(payload, |mut data| {
|
||||
@@ -730,10 +790,10 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
return Err(Error::new(EINVAL));
|
||||
}
|
||||
|
||||
let fb = self.adapter.create_dumb_buffer(data.width(), data.height());
|
||||
let buffer = self.adapter.create_dumb_buffer(data.width(), data.height());
|
||||
|
||||
*next_id += 1;
|
||||
buffers.insert(*next_id, Arc::new(fb));
|
||||
buffers.insert(*next_id, Arc::new(buffer));
|
||||
data.set_handle(*next_id as u32);
|
||||
data.set_pitch(data.width() * 4);
|
||||
data.set_size(u64::from(data.width()) * u64::from(data.height()) * 4);
|
||||
@@ -777,8 +837,10 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
}),
|
||||
ipc::MODE_GET_PLANE => ipc::DrmModeGetPlane::with(payload, |mut data| {
|
||||
let i = id_index(data.plane_id());
|
||||
data.set_crtc_id(self.objects.crtc_ids()[i as usize].0);
|
||||
data.set_fb_id(fb_id(i));
|
||||
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_possible_crtcs(1 << i);
|
||||
data.set_format_type_ptr(&[DRM_FORMAT_ARGB8888]);
|
||||
Ok(0)
|
||||
@@ -833,13 +895,16 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_GET_FB2 => ipc::DrmModeFbCmd2::with(payload, |mut data| {
|
||||
let i = id_index(data.fb_id());
|
||||
let (width, height) = self.adapter.display_size(i as usize);
|
||||
data.set_width(width);
|
||||
data.set_height(height);
|
||||
let fb = self.objects.get_framebuffer(KmsObjectId(data.fb_id()))?;
|
||||
|
||||
*next_id += 1;
|
||||
buffers.insert(*next_id, fb.buffer.clone());
|
||||
|
||||
data.set_width(fb.width);
|
||||
data.set_height(fb.height);
|
||||
data.set_pixel_format(DRM_FORMAT_ARGB8888);
|
||||
data.set_handles([fb_handle_id(i), 0, 0, 0]);
|
||||
data.set_pitches([width * 4, 0, 0, 0]);
|
||||
data.set_handles([*next_id, 0, 0, 0]);
|
||||
data.set_pitches([fb.width * 4, 0, 0, 0]);
|
||||
data.set_offsets([0; 4]);
|
||||
data.set_modifier([0; 4]);
|
||||
Ok(0)
|
||||
@@ -859,28 +924,30 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
return Err(Error::new(EINVAL));
|
||||
};
|
||||
|
||||
let framebuffer = if payload.fb_id == 0 {
|
||||
let fb = if payload.fb_id == 0 {
|
||||
None
|
||||
} else if let Some(framebuffer) = buffers.get(&id_index(payload.fb_id)) {
|
||||
Some(framebuffer)
|
||||
} else {
|
||||
return Err(Error::new(EINVAL));
|
||||
Some(self.objects.get_framebuffer(KmsObjectId(payload.fb_id))?)
|
||||
};
|
||||
|
||||
self.vts.get_mut(vt).unwrap().display_fbs[display_id] =
|
||||
framebuffer.map(Arc::clone);
|
||||
self.vts.get_mut(vt).unwrap().display_fbs[display_id] = if payload.fb_id == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(KmsObjectId(payload.fb_id))
|
||||
};
|
||||
|
||||
if *vt == self.active_vt {
|
||||
let mode = framebuffer.as_ref().map(|fb| {
|
||||
KmsConnector::<()>::modeinfo_for_size(fb.width(), fb.height())
|
||||
});
|
||||
crtc.lock().unwrap().fb_id = KmsObjectId(payload.fb_id);
|
||||
|
||||
let mode =
|
||||
fb.map(|fb| KmsConnector::<()>::modeinfo_for_size(fb.width, fb.height));
|
||||
|
||||
self.adapter.set_crtc(
|
||||
&self.objects,
|
||||
crtc,
|
||||
&[self.objects.connector_ids()[display_id]],
|
||||
mode,
|
||||
framebuffer.map(|fb| &**fb),
|
||||
fb,
|
||||
payload.damage,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::ptr::{self, NonNull};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter, StandardProperties};
|
||||
use drm_sys::{drm_mode_modeinfo, DRM_MODE_DPMS_ON};
|
||||
use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
|
||||
@@ -25,6 +25,7 @@ impl GraphicsAdapter for Device {
|
||||
type Crtc = ();
|
||||
|
||||
type Buffer = DumbFb;
|
||||
type Framebuffer = ();
|
||||
|
||||
fn name(&self) -> &'static [u8] {
|
||||
b"ihdgd"
|
||||
@@ -95,13 +96,17 @@ impl GraphicsAdapter for Device {
|
||||
framebuffer.ptr.as_ptr().cast::<u8>()
|
||||
}
|
||||
|
||||
fn create_framebuffer(&mut self, _buffer: &Self::Buffer) -> Self::Framebuffer {
|
||||
()
|
||||
}
|
||||
|
||||
fn set_crtc(
|
||||
&mut self,
|
||||
objects: &KmsObjects<Self>,
|
||||
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
|
||||
connectors: &[KmsObjectId],
|
||||
mode: Option<drm_mode_modeinfo>,
|
||||
buffer: Option<&Self::Buffer>,
|
||||
buffer: Option<&objects::KmsFramebuffer<Self::Framebuffer, Self::Buffer>>,
|
||||
damage: Damage,
|
||||
) {
|
||||
crtc.lock().unwrap().mode = mode;
|
||||
@@ -116,7 +121,7 @@ impl GraphicsAdapter for Device {
|
||||
|
||||
let framebuffer = &mut self.framebuffers[framebuffer_id];
|
||||
if let Some(buffer) = buffer {
|
||||
buffer.sync(framebuffer, damage)
|
||||
buffer.buffer.sync(framebuffer, damage)
|
||||
} else {
|
||||
let onscreen_ptr = framebuffer.onscreen as *mut u32; // FIXME use as_mut_ptr once stable
|
||||
for row in 0..framebuffer.height {
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::ptr::{self, NonNull};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::{Buffer, CursorPlane, GraphicsAdapter, StandardProperties};
|
||||
use drm_sys::{drm_mode_modeinfo, DRM_MODE_DPMS_ON};
|
||||
use graphics_ipc::v2::ipc::{DRM_CAP_DUMB_BUFFER, DRM_CLIENT_CAP_CURSOR_PLANE_HOTSPOT};
|
||||
@@ -28,6 +28,7 @@ impl GraphicsAdapter for FbAdapter {
|
||||
type Crtc = ();
|
||||
|
||||
type Buffer = GraphicScreen;
|
||||
type Framebuffer = ();
|
||||
|
||||
fn name(&self) -> &'static [u8] {
|
||||
b"vesad"
|
||||
@@ -102,13 +103,17 @@ impl GraphicsAdapter for FbAdapter {
|
||||
framebuffer.ptr.as_ptr().cast::<u8>()
|
||||
}
|
||||
|
||||
fn create_framebuffer(&mut self, _buffer: &Self::Buffer) -> Self::Framebuffer {
|
||||
()
|
||||
}
|
||||
|
||||
fn set_crtc(
|
||||
&mut self,
|
||||
objects: &KmsObjects<Self>,
|
||||
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
|
||||
connectors: &[KmsObjectId],
|
||||
mode: Option<drm_mode_modeinfo>,
|
||||
buffer: Option<&Self::Buffer>,
|
||||
buffer: Option<&objects::KmsFramebuffer<Self::Framebuffer, Self::Buffer>>,
|
||||
damage: Damage,
|
||||
) {
|
||||
crtc.lock().unwrap().mode = mode;
|
||||
@@ -123,7 +128,7 @@ impl GraphicsAdapter for FbAdapter {
|
||||
let framebuffer = &mut self.framebuffers[framebuffer_id];
|
||||
|
||||
if let Some(buffer) = buffer {
|
||||
buffer.sync(framebuffer, damage)
|
||||
buffer.buffer.sync(framebuffer, damage)
|
||||
} else {
|
||||
let onscreen_ptr = framebuffer.onscreen as *mut u32; // FIXME use as_mut_ptr once stable
|
||||
for row in 0..framebuffer.height {
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::sync::{Arc, Mutex};
|
||||
|
||||
use common::{dma::Dma, sgl};
|
||||
use driver_graphics::kms::connector::KmsConnectorStatus;
|
||||
use driver_graphics::kms::objects::{KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::kms::objects::{self, KmsCrtc, KmsObjectId, KmsObjects};
|
||||
use driver_graphics::{
|
||||
Buffer as DrmBuffer, CursorPlane, GraphicsAdapter, GraphicsScheme, StandardProperties,
|
||||
};
|
||||
@@ -269,6 +269,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
type Crtc = ();
|
||||
|
||||
type Buffer = VirtGpuFramebuffer<'a>;
|
||||
type Framebuffer = ();
|
||||
|
||||
fn name(&self) -> &'static [u8] {
|
||||
b"virtio-gpud"
|
||||
@@ -414,8 +415,12 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
fn map_dumb_buffer(&mut self, framebuffer: &Self::Buffer) -> *mut u8 {
|
||||
framebuffer.sgl.as_ptr()
|
||||
fn map_dumb_buffer(&mut self, buffer: &Self::Buffer) -> *mut u8 {
|
||||
buffer.sgl.as_ptr()
|
||||
}
|
||||
|
||||
fn create_framebuffer(&mut self, _buffer: &Self::Buffer) -> Self::Framebuffer {
|
||||
()
|
||||
}
|
||||
|
||||
fn set_crtc(
|
||||
@@ -424,7 +429,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
crtc: &Mutex<KmsCrtc<Self::Crtc>>,
|
||||
connectors: &[KmsObjectId],
|
||||
mode: Option<drm_mode_modeinfo>,
|
||||
framebuffer: Option<&Self::Buffer>,
|
||||
framebuffer: Option<&objects::KmsFramebuffer<Self::Framebuffer, Self::Buffer>>,
|
||||
damage: Damage,
|
||||
) {
|
||||
futures::executor::block_on(async {
|
||||
@@ -452,7 +457,7 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
};
|
||||
|
||||
let req = Dma::new(XferToHost2d::new(
|
||||
framebuffer.id,
|
||||
framebuffer.buffer.id,
|
||||
GpuRect {
|
||||
x: 0,
|
||||
y: 0,
|
||||
@@ -466,20 +471,20 @@ impl<'a> GraphicsAdapter for VirtGpuAdapter<'a> {
|
||||
assert_eq!(header.ty, CommandTy::RespOkNodata);
|
||||
|
||||
// FIXME once we support resizing we also need to check that the current and target size match
|
||||
if self.displays[display_id as usize].active_resource != Some(framebuffer.id) {
|
||||
if self.displays[display_id as usize].active_resource != Some(framebuffer.buffer.id) {
|
||||
let scanout_request = Dma::new(SetScanout::new(
|
||||
display_id,
|
||||
framebuffer.id,
|
||||
framebuffer.buffer.id,
|
||||
GpuRect::new(0, 0, framebuffer.width, framebuffer.height),
|
||||
))
|
||||
.unwrap();
|
||||
let header = self.send_request(scanout_request).await.unwrap();
|
||||
assert_eq!(header.ty, CommandTy::RespOkNodata);
|
||||
self.displays[display_id as usize].active_resource = Some(framebuffer.id);
|
||||
self.displays[display_id as usize].active_resource = Some(framebuffer.buffer.id);
|
||||
}
|
||||
|
||||
let flush = ResourceFlush::new(
|
||||
framebuffer.id,
|
||||
framebuffer.buffer.id,
|
||||
damage.clip(framebuffer.width, framebuffer.height).into(),
|
||||
);
|
||||
let header = self.send_request(Dma::new(flush).unwrap()).await.unwrap();
|
||||
|
||||
Reference in New Issue
Block a user