From 511c6080caf00ac1c115c68e49d3ef956c9de41f Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Wed, 11 Mar 2026 22:49:19 +0100 Subject: [PATCH] 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. --- drivers/graphics/console-draw/src/lib.rs | 18 +++++++++++------- drivers/graphics/driver-graphics/src/lib.rs | 4 ++++ drivers/graphics/fbbootlogd/src/scheme.rs | 14 +++++++------- drivers/graphics/fbcond/src/display.rs | 10 +++++----- 4 files changed, 27 insertions(+), 19 deletions(-) diff --git a/drivers/graphics/console-draw/src/lib.rs b/drivers/graphics/console-draw/src/lib.rs index 20be8bb8d2..25a409042e 100644 --- a/drivers/graphics/console-draw/src/lib.rs +++ b/drivers/graphics/console-draw/src/lib.rs @@ -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 { - 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<'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); diff --git a/drivers/graphics/driver-graphics/src/lib.rs b/drivers/graphics/driver-graphics/src/lib.rs index 01b9f7b2cb..e43c4cbc95 100644 --- a/drivers/graphics/driver-graphics/src/lib.rs +++ b/drivers/graphics/driver-graphics/src/lib.rs @@ -810,6 +810,10 @@ impl SchemeSync for GraphicsSchemeInner { 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)); diff --git a/drivers/graphics/fbbootlogd/src/scheme.rs b/drivers/graphics/fbbootlogd/src/scheme.rs index a599893aa1..f3485c94d1 100644 --- a/drivers/graphics/fbbootlogd/src/scheme.rs +++ b/drivers/graphics/fbbootlogd/src/scheme.rs @@ -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(); } } diff --git a/drivers/graphics/fbcond/src/display.rs b/drivers/graphics/fbcond/src/display.rs index 2cc3b57d30..5bbd47c4a2 100644 --- a/drivers/graphics/fbcond/src/display.rs +++ b/drivers/graphics/fbcond/src/display.rs @@ -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(); } }