diff --git a/drivers/graphics/console-draw/src/lib.rs b/drivers/graphics/console-draw/src/lib.rs index 64f2ad2f9a..20be8bb8d2 100644 --- a/drivers/graphics/console-draw/src/lib.rs +++ b/drivers/graphics/console-draw/src/lib.rs @@ -4,7 +4,7 @@ use std::collections::VecDeque; use std::convert::{TryFrom, TryInto}; use std::{cmp, io, mem, ptr}; -use drm::buffer::Buffer; +use drm::buffer::{Buffer, DrmFourcc}; use drm::control::dumbbuffer::{DumbBuffer, DumbMapping}; use drm::control::Device; use graphics_ipc::v1::Damage; @@ -14,10 +14,23 @@ use orbclient::FONT; pub struct V2DisplayMap { pub display_handle: V2GraphicsHandle, pub fb: DumbBuffer, - pub mapping: DumbMapping<'static>, + 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 map = display_handle.map_dumb_buffer(&mut fb)?; + let map = unsafe { mem::transmute::, DumbMapping<'static>>(map) }; + + Ok(Self { + display_handle, + fb, + mapping: map, + }) + } + unsafe fn console_map(&mut self) -> DisplayMap { DisplayMap { offscreen: ptr::slice_from_raw_parts_mut( @@ -30,10 +43,10 @@ impl V2DisplayMap { } } -pub struct DisplayMap { - pub offscreen: *mut [u32], - pub width: usize, - pub height: usize, +struct DisplayMap { + offscreen: *mut [u32], + width: usize, + height: usize, } pub struct TextScreen { @@ -257,7 +270,7 @@ impl TextScreen { damage } - pub fn resize(&mut self, old_map: &mut V2DisplayMap, mut new_fb: DumbBuffer) -> io::Result<()> { + pub fn resize(&mut self, map: &mut V2DisplayMap, width: u32, height: u32) -> io::Result<()> { // FIXME fold row when target is narrower and maybe unfold when it is wider fn copy_row( old_map: &mut DisplayMap, @@ -274,14 +287,18 @@ impl TextScreen { } } - let new_mapping = old_map.display_handle.map_dumb_buffer(&mut new_fb)?; + let mut new_fb = + map.display_handle + .create_dumb_buffer((width, height), DrmFourcc::Argb8888, 32)?; + + let new_mapping = map.display_handle.map_dumb_buffer(&mut new_fb)?; let mut new_mapping = unsafe { mem::transmute::, DumbMapping<'static>>(new_mapping) }; new_mapping.fill(0); { - let old_map = unsafe { &mut old_map.console_map() }; + let old_map = unsafe { &mut map.console_map() }; let new_map = &mut DisplayMap { offscreen: ptr::slice_from_raw_parts_mut( new_mapping.as_mut_ptr() as *mut u32, @@ -307,10 +324,10 @@ impl TextScreen { } } - let old_fb = mem::replace(&mut old_map.fb, new_fb); - old_map.mapping = new_mapping; + let old_fb = mem::replace(&mut map.fb, new_fb); + map.mapping = new_mapping; - let _ = old_map.display_handle.destroy_dumb_buffer(old_fb); + let _ = map.display_handle.destroy_dumb_buffer(old_fb); Ok(()) } diff --git a/drivers/graphics/fbbootlogd/src/scheme.rs b/drivers/graphics/fbbootlogd/src/scheme.rs index 41e6f3f009..832c511d76 100644 --- a/drivers/graphics/fbbootlogd/src/scheme.rs +++ b/drivers/graphics/fbbootlogd/src/scheme.rs @@ -1,9 +1,8 @@ +use std::cmp; use std::collections::VecDeque; -use std::{cmp, mem}; use console_draw::{TextScreen, V2DisplayMap}; -use drm::buffer::{Buffer, DrmFourcc}; -use drm::control::dumbbuffer::DumbMapping; +use drm::buffer::Buffer; use drm::control::Device; use graphics_ipc::v2::V2GraphicsHandle; use inputd::ConsumerHandle; @@ -54,26 +53,15 @@ impl FbbootlogScheme { .unwrap() .modes()[0] .size(); - let mut fb = new_display_handle - .create_dumb_buffer((width.into(), height.into()), DrmFourcc::Argb8888, 32) - .unwrap(); - let display_map = match new_display_handle.map_dumb_buffer(&mut fb) { - Ok(display_map) => unsafe { - mem::transmute::, DumbMapping<'static>>(display_map) - }, + match V2DisplayMap::new(new_display_handle, width.into(), height.into()) { + Ok(display_map) => self.display_map = Some(display_map), Err(err) => { eprintln!("fbbootlogd: failed to open display: {}", err); return; } }; - self.display_map = Some(V2DisplayMap { - display_handle: new_display_handle, - mapping: display_map, - fb, - }); - eprintln!("fbbootlogd: mapped display"); } @@ -173,19 +161,10 @@ impl FbbootlogScheme { }; if (width, height) != map.fb.size() { - match map - .display_handle - .create_dumb_buffer((width, height), DrmFourcc::Argb8888, 32) - { - Ok(fb) => match text_screen.resize(map, fb) { - Ok(()) => eprintln!("fbbootlogd: mapped display"), - Err(err) => { - eprintln!("fbbootlogd: failed to open display: {}", err); - return; - } - }, + match text_screen.resize(map, width, height) { + Ok(()) => eprintln!("fbbootlogd: mapped display"), Err(err) => { - eprintln!("fbbootlogd: failed to create framebuffer: {}", err); + eprintln!("fbbootlogd: failed to create or map framebuffer: {}", err); return; } } diff --git a/drivers/graphics/fbcond/src/display.rs b/drivers/graphics/fbcond/src/display.rs index 0d23e95ab9..639bc8f06a 100644 --- a/drivers/graphics/fbcond/src/display.rs +++ b/drivers/graphics/fbcond/src/display.rs @@ -1,10 +1,9 @@ use console_draw::{TextScreen, V2DisplayMap}; -use drm::buffer::{Buffer, DrmFourcc}; -use drm::control::dumbbuffer::DumbMapping; +use drm::buffer::Buffer; use drm::control::Device; use graphics_ipc::v2::{Damage, V2GraphicsHandle}; use inputd::ConsumerHandle; -use std::{io, mem}; +use std::io; pub struct Display { pub input_handle: ConsumerHandle, @@ -35,29 +34,21 @@ impl Display { .unwrap() .modes()[0] .size(); - let mut fb = new_display_handle - .create_dumb_buffer((width.into(), height.into()), DrmFourcc::Argb8888, 32) - .unwrap(); - let map = match new_display_handle.map_dumb_buffer(&mut fb) { - Ok(map) => unsafe { mem::transmute::, DumbMapping<'static>>(map) }, + match V2DisplayMap::new(new_display_handle, width.into(), height.into()) { + Ok(map) => { + log::debug!( + "fbcond: Mapped new display with size {}x{}", + map.fb.size().0, + map.fb.size().1, + ); + self.map = Some(map) + } Err(err) => { - log::error!("failed to map display: {}", err); + eprintln!("fbcond: failed to open display: {}", err); return; } - }; - - log::debug!( - "fbcond: Mapped new display with size {}x{}", - fb.size().0, - fb.size().1, - ); - - self.map = Some(V2DisplayMap { - display_handle: new_display_handle, - fb, - mapping: map, - }); + } } pub fn handle_resize(map: &mut V2DisplayMap, text_screen: &mut TextScreen) { @@ -72,21 +63,11 @@ impl Display { }; if (width, height) != map.fb.size() { - match map - .display_handle - .create_dumb_buffer((width, height), DrmFourcc::Argb8888, 32) - { - Ok(fb) => { - match text_screen.resize(map, fb) { - Ok(()) => eprintln!("fbcond: mapped display"), - Err(err) => { - eprintln!("fbcond: failed to open display: {}", err); - return; - } - }; - } + match text_screen.resize(map, width, height) { + Ok(()) => eprintln!("fbcond: mapped display"), Err(err) => { - log::error!("fbcond: failed to create framebuffer: {}", err); + eprintln!("fbcond: failed to create or map framebuffer: {}", err); + return; } } }