drivers/graphics: Add framebuffer indirection to the DRM interface
This matches the Linux DRM interface. With this I believe the only divergence from the Linux DRM interface that would be a breaking change to the in-tree users of the graphics api to change to the proper interface is the use of the UPDATE_PLANE ioctl in the place of proper modesetting interface. It should be possible to support this in parallel to UPDATE_PLANE, so updating Orbital to the DRM interface should now be possible. Orbital can be updated to the proper modesetting interface once it is implemented.
This commit is contained in:
@@ -6,27 +6,31 @@ use std::{cmp, io, mem, ptr};
|
||||
|
||||
use drm::buffer::{Buffer, DrmFourcc};
|
||||
use drm::control::dumbbuffer::{DumbBuffer, DumbMapping};
|
||||
use drm::control::Device;
|
||||
use drm::control::{framebuffer, Device};
|
||||
use graphics_ipc::v1::Damage;
|
||||
use graphics_ipc::v2::V2GraphicsHandle;
|
||||
use orbclient::FONT;
|
||||
|
||||
pub struct V2DisplayMap {
|
||||
pub display_handle: V2GraphicsHandle,
|
||||
pub fb: DumbBuffer,
|
||||
pub fb: framebuffer::Handle,
|
||||
pub buffer: DumbBuffer,
|
||||
mapping: DumbMapping<'static>,
|
||||
}
|
||||
|
||||
impl V2DisplayMap {
|
||||
pub fn new(display_handle: V2GraphicsHandle, width: u32, height: u32) -> io::Result<Self> {
|
||||
let mut fb = display_handle.create_dumb_buffer((width, height), DrmFourcc::Argb8888, 32)?;
|
||||
let mut buffer =
|
||||
display_handle.create_dumb_buffer((width, height), DrmFourcc::Argb8888, 32)?;
|
||||
let fb = display_handle.add_framebuffer(&buffer, 24, 32)?;
|
||||
|
||||
let map = display_handle.map_dumb_buffer(&mut fb)?;
|
||||
let map = display_handle.map_dumb_buffer(&mut buffer)?;
|
||||
let map = unsafe { mem::transmute::<DumbMapping<'_>, DumbMapping<'static>>(map) };
|
||||
|
||||
Ok(Self {
|
||||
display_handle,
|
||||
fb,
|
||||
buffer,
|
||||
mapping: map,
|
||||
})
|
||||
}
|
||||
@@ -37,8 +41,8 @@ impl V2DisplayMap {
|
||||
self.mapping.as_mut_ptr() as *mut u32,
|
||||
self.mapping.len() / 4,
|
||||
),
|
||||
width: self.fb.size().0 as usize,
|
||||
height: self.fb.size().1 as usize,
|
||||
width: self.buffer.size().0 as usize,
|
||||
height: self.buffer.size().1 as usize,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -324,7 +328,7 @@ impl TextScreen {
|
||||
}
|
||||
}
|
||||
|
||||
let old_fb = mem::replace(&mut map.fb, new_fb);
|
||||
let old_fb = mem::replace(&mut map.buffer, new_fb);
|
||||
map.mapping = new_mapping;
|
||||
|
||||
let _ = map.display_handle.destroy_dumb_buffer(old_fb);
|
||||
|
||||
@@ -810,6 +810,10 @@ impl<T: GraphicsAdapter> SchemeSync for GraphicsSchemeInner<T> {
|
||||
data.set_handle(fb_handle_id(i));
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_ADD_FB => ipc::DrmModeFbCmd::with(payload, |mut data| {
|
||||
data.set_fb_id(fb_handle_id(id_index(data.handle())));
|
||||
Ok(0)
|
||||
}),
|
||||
ipc::MODE_CREATE_DUMB => ipc::DrmModeCreateDumb::with(payload, |mut data| {
|
||||
if data.bpp() != 32 {
|
||||
return Err(Error::new(EINVAL));
|
||||
|
||||
@@ -122,7 +122,7 @@ impl FbbootlogScheme {
|
||||
self.is_scrollback = true;
|
||||
self.scrollback_offset = cmp::min(
|
||||
self.scrollback_offset,
|
||||
buffer_len - map.fb.size().1 as usize / 16 + spare_lines,
|
||||
buffer_len - map.buffer.size().1 as usize / 16 + spare_lines,
|
||||
);
|
||||
let mut i = self.scrollback_offset;
|
||||
self.text_screen
|
||||
@@ -135,9 +135,9 @@ impl FbbootlogScheme {
|
||||
.write(map, &self.text_buffer.lines[i][..], &mut VecDeque::new());
|
||||
i += 1;
|
||||
let yd = (damage.y + damage.height) as usize;
|
||||
if i == buffer_len || yd + spare_lines * 16 > map.fb.size().1 as usize {
|
||||
if i == buffer_len || yd + spare_lines * 16 > map.buffer.size().1 as usize {
|
||||
// render until end of screen
|
||||
damage.height = map.fb.size().1 - damage.y;
|
||||
damage.height = map.buffer.size().1 - damage.y;
|
||||
total_damage = total_damage.merge(damage);
|
||||
self.is_scrollback = i < buffer_len;
|
||||
break;
|
||||
@@ -146,7 +146,7 @@ impl FbbootlogScheme {
|
||||
}
|
||||
}
|
||||
map.display_handle
|
||||
.update_plane(0, u32::from(map.fb.handle()), total_damage)
|
||||
.update_plane(0, u32::from(map.buffer.handle()), total_damage)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
@@ -157,11 +157,11 @@ impl FbbootlogScheme {
|
||||
Ok((width, height)) => (width.into(), height.into()),
|
||||
Err(err) => {
|
||||
eprintln!("fbbootlogd: failed to get display size: {}", err);
|
||||
map.fb.size()
|
||||
map.buffer.size()
|
||||
}
|
||||
};
|
||||
|
||||
if (width, height) != map.fb.size() {
|
||||
if (width, height) != map.buffer.size() {
|
||||
match text_screen.resize(map, width, height) {
|
||||
Ok(()) => eprintln!("fbbootlogd: mapped display"),
|
||||
Err(err) => {
|
||||
@@ -248,7 +248,7 @@ impl SchemeSync for FbbootlogScheme {
|
||||
|
||||
if let Some(map) = &self.display_map {
|
||||
map.display_handle
|
||||
.update_plane(0, u32::from(map.fb.handle()), damage)
|
||||
.update_plane(0, u32::from(map.buffer.handle()), damage)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ impl Display {
|
||||
Ok(map) => {
|
||||
log::debug!(
|
||||
"fbcond: Mapped new display with size {}x{}",
|
||||
map.fb.size().0,
|
||||
map.fb.size().1,
|
||||
map.buffer.size().0,
|
||||
map.buffer.size().1,
|
||||
);
|
||||
self.map = Some(map)
|
||||
}
|
||||
@@ -64,11 +64,11 @@ impl Display {
|
||||
Ok((width, height)) => (width.into(), height.into()),
|
||||
Err(err) => {
|
||||
log::error!("fbcond: failed to get display size: {}", err);
|
||||
map.fb.size()
|
||||
map.buffer.size()
|
||||
}
|
||||
};
|
||||
|
||||
if (width, height) != map.fb.size() {
|
||||
if (width, height) != map.buffer.size() {
|
||||
match text_screen.resize(map, width, height) {
|
||||
Ok(()) => eprintln!("fbcond: mapped display"),
|
||||
Err(err) => {
|
||||
@@ -82,7 +82,7 @@ impl Display {
|
||||
pub fn sync_rect(&mut self, damage: Damage) {
|
||||
if let Some(map) = &self.map {
|
||||
map.display_handle
|
||||
.update_plane(0, u32::from(map.fb.handle()), damage)
|
||||
.update_plane(0, u32::from(map.buffer.handle()), damage)
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user