diff --git a/graphics/driver-graphics/Cargo.toml b/graphics/driver-graphics/Cargo.toml index 6ad15add9d..a592861035 100644 --- a/graphics/driver-graphics/Cargo.toml +++ b/graphics/driver-graphics/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] log = "0.4" redox-scheme = { git = "https://gitlab.redox-os.org/redox-os/redox-scheme.git" } -redox_syscall = "0.5" +redox_syscall = { version = "0.5", features = ["std"] } libredox = "0.1.3" common = { path = "../../common" } diff --git a/graphics/driver-graphics/src/lib.rs b/graphics/driver-graphics/src/lib.rs index 147802dc60..c35b88bcd8 100644 --- a/graphics/driver-graphics/src/lib.rs +++ b/graphics/driver-graphics/src/lib.rs @@ -96,11 +96,6 @@ impl GraphicsScheme { } } - VtEventKind::Deactivate => { - log::info!("deactivate {}", vt_event.vt); - // nothing to do :) - } - VtEventKind::Resize => { log::warn!("driver-graphics: resize is not implemented yet") } diff --git a/graphics/fbbootlogd/src/display.rs b/graphics/fbbootlogd/src/display.rs index 4fa9d53213..4f736f8643 100644 --- a/graphics/fbbootlogd/src/display.rs +++ b/graphics/fbbootlogd/src/display.rs @@ -41,18 +41,26 @@ enum DisplayCommand { pub struct Display { cmd_tx: Sender, - pub map: Arc>, + pub map: Arc>>, } impl Display { pub fn open_first_vt() -> io::Result { let input_handle = ConsumerHandle::for_vt(1)?; - let display_handle = LegacyGraphicsHandle::from_file(input_handle.open_display()?)?; - - let map = Arc::new(Mutex::new( - display_fd_map(display_handle).unwrap_or_else(|e| panic!("failed to map display: {e}")), - )); + let map = match input_handle.open_display() { + Ok(display) => { + let display_handle = LegacyGraphicsHandle::from_file(display)?; + Arc::new(Mutex::new(Some( + display_fd_map(display_handle) + .unwrap_or_else(|e| panic!("failed to map display: {e}")), + ))) + } + Err(err) => { + println!("fbbootlogd: No display present yet: {err}"); + Arc::new(Mutex::new(None)) + } + }; let map_clone = map.clone(); std::thread::spawn(move || { @@ -68,7 +76,7 @@ impl Display { Ok(Self { cmd_tx, map }) } - fn handle_input_events(map: Arc>, input_handle: ConsumerHandle) { + fn handle_input_events(map: Arc>>, input_handle: ConsumerHandle) { let event_queue = EventQueue::new().expect("fbbootlogd: failed to create event queue"); user_data! { @@ -93,13 +101,17 @@ impl Display { Err(err) if err.errno() == ESTALE => { eprintln!("fbbootlogd: handoff requested"); - let new_display_handle = - LegacyGraphicsHandle::from_file(input_handle.open_display().unwrap()) - .unwrap(); + let new_display_handle = match input_handle.open_display() { + Ok(display) => LegacyGraphicsHandle::from_file(display).unwrap(), + Err(err) => { + println!("fbbootlogd: No display present yet: {err}"); + continue; + } + }; match display_fd_map(new_display_handle) { Ok(ok) => { - *map.lock().unwrap() = ok; + *map.lock().unwrap() = Some(ok); eprintln!("fbbootlogd: handoff finished"); } @@ -117,13 +129,17 @@ impl Display { } } - fn handle_sync_rect(map: Arc>, cmd_rx: Receiver) { + fn handle_sync_rect(map: Arc>>, cmd_rx: Receiver) { while let Ok(cmd) = cmd_rx.recv() { match cmd { DisplayCommand::SyncRects(sync_rects) => { // We may not hold this lock across the write call to avoid deadlocking if the // graphics driver tries to write to the bootlog. - let display_handle = map.lock().unwrap().display_handle.clone(); + let display_handle = if let Some(map) = &*map.lock().unwrap() { + map.display_handle.clone() + } else { + continue; + }; display_handle.sync_rects(&sync_rects).unwrap(); } } diff --git a/graphics/fbbootlogd/src/scheme.rs b/graphics/fbbootlogd/src/scheme.rs index 3447a91466..1cf0adb5c3 100644 --- a/graphics/fbbootlogd/src/scheme.rs +++ b/graphics/fbbootlogd/src/scheme.rs @@ -55,19 +55,21 @@ impl Scheme for FbbootlogScheme { } fn write(&mut self, _id: usize, buf: &[u8], _offset: u64, _fcntl_flags: u32) -> Result { - let mut map = self.display.map.lock().unwrap(); - let damage = self.text_screen.write( - &mut console_draw::DisplayMap { - offscreen: map.inner.ptr_mut(), - width: map.inner.width(), - height: map.inner.height(), - }, - buf, - &mut VecDeque::new(), - ); - drop(map); + let mut map_guard = self.display.map.lock().unwrap(); + if let Some(map) = &mut *map_guard { + let damage = self.text_screen.write( + &mut console_draw::DisplayMap { + offscreen: map.inner.ptr_mut(), + width: map.inner.width(), + height: map.inner.height(), + }, + buf, + &mut VecDeque::new(), + ); + drop(map_guard); - self.display.sync_rects(damage); + self.display.sync_rects(damage); + } Ok(buf.len()) } diff --git a/graphics/vesad/src/main.rs b/graphics/vesad/src/main.rs index 8cafa6b2ee..541ce13d79 100644 --- a/graphics/vesad/src/main.rs +++ b/graphics/vesad/src/main.rs @@ -13,7 +13,6 @@ use crate::scheme::FbAdapter; mod framebuffer; mod scheme; -mod screen; fn main() { let mut spec = Vec::new(); @@ -22,6 +21,11 @@ fn main() { spec.push(()); } + if env::var("FRAMEBUFFER_WIDTH").is_err() { + println!("vesad: No boot framebuffer"); + return; + } + let width = usize::from_str_radix( &env::var("FRAMEBUFFER_WIDTH").expect("FRAMEBUFFER_WIDTH not set"), 16, @@ -49,6 +53,7 @@ fn main() { ); if phys == 0 { + println!("vesad: Boot framebuffer at address 0"); return; } diff --git a/graphics/vesad/src/scheme.rs b/graphics/vesad/src/scheme.rs index 51a3712e02..48c3b0940a 100644 --- a/graphics/vesad/src/scheme.rs +++ b/graphics/vesad/src/scheme.rs @@ -1,7 +1,12 @@ -use driver_graphics::GraphicsAdapter; -use graphics_ipc::legacy::Damage; +use std::alloc::{self, Layout}; +use std::convert::TryInto; +use std::ptr::{self, NonNull}; -use crate::{framebuffer::FrameBuffer, screen::GraphicScreen}; +use driver_graphics::{GraphicsAdapter, Resource}; +use graphics_ipc::legacy::Damage; +use syscall::PAGE_SIZE; + +use crate::framebuffer::FrameBuffer; pub struct FbAdapter { pub framebuffers: Vec, @@ -26,11 +31,11 @@ impl GraphicsAdapter for FbAdapter { } fn map_resource(&mut self, resource: &Self::Resource) -> *mut u8 { - resource.ptr() + resource.ptr.as_ptr().cast::() } fn set_scanout(&mut self, display_id: usize, resource: &Self::Resource) { - resource.redraw(&mut self.framebuffers[display_id]); + self.flush_resource(display_id, resource, None); } fn flush_resource( @@ -42,7 +47,91 @@ impl GraphicsAdapter for FbAdapter { if let Some(damage) = damage { resource.sync(&mut self.framebuffers[display_id], damage) } else { - resource.redraw(&mut self.framebuffers[display_id]) + let framebuffer: &mut FrameBuffer = &mut self.framebuffers[display_id]; + let width = resource.width.try_into().unwrap(); + let height = resource.height.try_into().unwrap(); + resource.sync( + framebuffer, + &[Damage { + x: 0, + y: 0, + width, + height, + }], + ); + } + } +} + +pub struct GraphicScreen { + width: usize, + height: usize, + ptr: NonNull<[u32]>, +} + +impl GraphicScreen { + fn new(width: usize, height: usize) -> GraphicScreen { + let len = width * height; + let layout = Self::layout(len); + let ptr = unsafe { alloc::alloc_zeroed(layout) }; + let ptr = ptr::slice_from_raw_parts_mut(ptr.cast(), len); + let ptr = NonNull::new(ptr).unwrap_or_else(|| alloc::handle_alloc_error(layout)); + + GraphicScreen { width, height, ptr } + } + + #[inline] + fn layout(len: usize) -> Layout { + // optimizes to an integer mul + Layout::array::(len) + .unwrap() + .align_to(PAGE_SIZE) + .unwrap() + } +} + +impl Drop for GraphicScreen { + fn drop(&mut self) { + let layout = Self::layout(self.ptr.len()); + unsafe { alloc::dealloc(self.ptr.as_ptr().cast(), layout) }; + } +} + +impl Resource for GraphicScreen { + fn width(&self) -> u32 { + self.width as u32 + } + + fn height(&self) -> u32 { + self.height as u32 + } +} + +impl GraphicScreen { + fn sync(&self, framebuffer: &mut FrameBuffer, sync_rects: &[Damage]) { + for sync_rect in sync_rects { + let sync_rect = sync_rect.clip( + self.width.try_into().unwrap(), + self.height.try_into().unwrap(), + ); + + let start_x: usize = sync_rect.x.try_into().unwrap_or(0); + let start_y: usize = sync_rect.y.try_into().unwrap_or(0); + let w: usize = sync_rect.width.try_into().unwrap_or(0); + let h: usize = sync_rect.height.try_into().unwrap_or(0); + + let offscreen_ptr = self.ptr.as_ptr() as *mut u32; + let onscreen_ptr = framebuffer.onscreen as *mut u32; // FIXME use as_mut_ptr once stable + + for row in start_y..start_y + h { + unsafe { + ptr::copy( + offscreen_ptr.add(row * self.width + start_x), + onscreen_ptr.add(row * framebuffer.stride + start_x), + w, + ); + } + } } } } diff --git a/graphics/vesad/src/screen.rs b/graphics/vesad/src/screen.rs deleted file mode 100644 index 8460ffbbf7..0000000000 --- a/graphics/vesad/src/screen.rs +++ /dev/null @@ -1,107 +0,0 @@ -use std::alloc::{self, Layout}; -use std::convert::TryInto; -use std::ptr::{self, NonNull}; - -use driver_graphics::Resource; -use graphics_ipc::legacy::Damage; -use syscall::PAGE_SIZE; - -use crate::framebuffer::FrameBuffer; - -pub struct GraphicScreen { - pub width: usize, - pub height: usize, - ptr: NonNull<[u32]>, -} - -impl GraphicScreen { - pub fn new(width: usize, height: usize) -> GraphicScreen { - let len = width * height; - let layout = Self::layout(len); - let ptr = unsafe { alloc::alloc_zeroed(layout) }; - let ptr = ptr::slice_from_raw_parts_mut(ptr.cast(), len); - let ptr = NonNull::new(ptr).unwrap_or_else(|| alloc::handle_alloc_error(layout)); - - GraphicScreen { width, height, ptr } - } - - #[inline] - fn layout(len: usize) -> Layout { - // optimizes to an integer mul - Layout::array::(len) - .unwrap() - .align_to(PAGE_SIZE) - .unwrap() - } -} - -impl Drop for GraphicScreen { - fn drop(&mut self) { - let layout = Self::layout(self.ptr.len()); - unsafe { alloc::dealloc(self.ptr.as_ptr().cast(), layout) }; - } -} - -impl Resource for GraphicScreen { - fn width(&self) -> u32 { - self.width as u32 - } - - fn height(&self) -> u32 { - self.height as u32 - } -} - -impl GraphicScreen { - pub fn ptr(&self) -> *mut u8 { - self.ptr.as_ptr().cast::() - } - - pub fn sync(&self, framebuffer: &mut FrameBuffer, sync_rects: &[Damage]) { - for sync_rect in sync_rects { - let sync_rect = sync_rect.clip( - self.width.try_into().unwrap(), - self.height.try_into().unwrap(), - ); - - let start_x: usize = sync_rect.x.try_into().unwrap_or(0); - let start_y: usize = sync_rect.y.try_into().unwrap_or(0); - let w: usize = sync_rect.width.try_into().unwrap_or(0); - let h: usize = sync_rect.height.try_into().unwrap_or(0); - - let end_y = start_y + h; - - let row_pixel_count = w; - - let mut offscreen_ptr = self.ptr.as_ptr() as *mut u32; - let mut onscreen_ptr = framebuffer.onscreen as *mut u32; // FIXME use as_mut_ptr once stable - - unsafe { - offscreen_ptr = offscreen_ptr.add(start_y * self.width + start_x); - onscreen_ptr = onscreen_ptr.add(start_y * framebuffer.stride + start_x); - - let mut rows = end_y - start_y; - while rows > 0 { - ptr::copy(offscreen_ptr, onscreen_ptr, row_pixel_count); - offscreen_ptr = offscreen_ptr.add(self.width); - onscreen_ptr = onscreen_ptr.add(framebuffer.stride); - rows -= 1; - } - } - } - } - - pub fn redraw(&self, framebuffer: &mut FrameBuffer) { - let width = self.width.try_into().unwrap(); - let height = self.height.try_into().unwrap(); - self.sync( - framebuffer, - &[Damage { - x: 0, - y: 0, - width, - height, - }], - ); - } -} diff --git a/inputd/Cargo.toml b/inputd/Cargo.toml index d45b055cb1..c3cb227a08 100644 --- a/inputd/Cargo.toml +++ b/inputd/Cargo.toml @@ -8,7 +8,7 @@ authors = ["Anhad Singh "] anyhow = "1.0.71" log = "0.4.19" redox-daemon = "0.1.2" -redox_syscall = "0.5" +redox_syscall = { version = "0.5", features = ["std"] } orbclient = "0.3.27" libredox = "0.1.3" diff --git a/inputd/src/lib.rs b/inputd/src/lib.rs index 877e3f3145..239c5f1b52 100644 --- a/inputd/src/lib.rs +++ b/inputd/src/lib.rs @@ -32,8 +32,7 @@ impl ConsumerHandle { pub fn open_display(&self) -> Result { let mut buffer = [0; 1024]; let fd = self.0.as_raw_fd(); - let written = libredox::call::fpath(fd as usize, &mut buffer) - .expect("init: failed to get the path to the display device"); + let written = libredox::call::fpath(fd as usize, &mut buffer)?; assert!(written <= buffer.len()); @@ -119,7 +118,6 @@ impl ControlHandle { #[repr(usize)] pub enum VtEventKind { Activate, - Deactivate, Resize, } diff --git a/inputd/src/main.rs b/inputd/src/main.rs index edd0be1a33..218da3c62f 100644 --- a/inputd/src/main.rs +++ b/inputd/src/main.rs @@ -120,19 +120,6 @@ impl InputScheme { device, .. } => { - if let Some(active_vt) = self.active_vt { - if &self.vts[&active_vt].display == &*device { - pending.push(VtEvent { - kind: VtEventKind::Deactivate, - vt: self.active_vt.unwrap(), - width: 0, - height: 0, - stride: 0, - }); - *notified = false; - } - } - if &self.vts[&new_active].display == &*device { pending.push(VtEvent { kind: VtEventKind::Activate, @@ -420,23 +407,24 @@ impl Scheme for InputScheme { let handle = self.handles.get_mut(&id).ok_or(SysError::new(EINVAL))?; assert!(handle.is_producer()); - let active_vt = self.active_vt.unwrap(); - for handle in self.handles.values_mut() { - match handle { - Handle::Consumer { - pending, - notified, - vt, - .. - } => { - if *vt != active_vt { - continue; - } + if let Some(active_vt) = self.active_vt { + for handle in self.handles.values_mut() { + match handle { + Handle::Consumer { + pending, + notified, + vt, + .. + } => { + if *vt != active_vt { + continue; + } - pending.extend_from_slice(buf); - *notified = false; + pending.extend_from_slice(buf); + *notified = false; + } + _ => continue, } - _ => continue, } }