From 744a0bb796d65236f1205f4ac2f41bd71008d6a8 Mon Sep 17 00:00:00 2001 From: Elaina Claus Date: Fri, 17 Mar 2023 23:54:10 -0400 Subject: [PATCH] rough draft of something to manipulate the FB --- src/main.rs | 33 ++++-------------- src/uefi_fb/mod.rs | 85 +++++++++++++++------------------------------- 2 files changed, 33 insertions(+), 85 deletions(-) diff --git a/src/main.rs b/src/main.rs index 1de26ef..156a2a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -28,6 +28,7 @@ use uefi::{ AllocateType, BootServices, MemoryType, OpenProtocolAttributes, OpenProtocolParams, }, }; +use uefi_fb::UefiFb; mod uefi_fb; mod sync; @@ -68,36 +69,14 @@ pub fn efi_main(_image: Handle, mut st: SystemTable) -> Status { } }; + let fb = uefi_fb::UefiFb::new(); + uefifb_test(&fb) +} - +fn uefifb_test(fb: &UefiFb) -> Status { - let handle = bt.get_handle_for_protocol::() - .expect("missing GraphicsOutput protocol"); - - - let mut gop = unsafe { - let mut gop_proto = st.boot_services().open_protocol::( - OpenProtocolParams { - handle, - agent: st.boot_services().image_handle(), - controller: None, - }, - // For this test, don't open in exclusive mode. That - // would break the connection between stdout and the - // video console. - OpenProtocolAttributes::GetProtocol, - ) - .expect("failed to open Graphics Output Protocol"); - - gop_proto - }; - - set_graphics_mode(&mut gop); - fill_color(&mut gop); - draw_fb(&mut gop); + // run tests here info!("GOP Framebuffer test complete"); - - // Return success status Status::SUCCESS } diff --git a/src/uefi_fb/mod.rs b/src/uefi_fb/mod.rs index 18f7f57..d9b70af 100644 --- a/src/uefi_fb/mod.rs +++ b/src/uefi_fb/mod.rs @@ -12,15 +12,15 @@ use uefi::{ }; use alloc::sync::Arc; use crate::sync; -use crate::sync::Spinlock::*; +use crate::sync::{Spinlock, SpinlockGuard}; -struct UefiFb { - gop: Arc> +pub struct UefiFb<'a> { + gop: ScopedProtocol<'a, GraphicsOutput<'a>> } -impl UefiFb { +impl UefiFb<'_> { - pub fn new() -> UefiFb { + pub fn new() -> UefiFb<'static> { let st_ref = unsafe { uefi_services::system_table().as_ref() }; let bt = st_ref.boot_services(); @@ -45,27 +45,15 @@ impl UefiFb { gop_proto }; + UefiFb { gop } - UefiFb { - gop: Arc::new(gop) - } - - - /* - set_graphics_mode(&mut gop); - fill_color(&mut gop); - draw_fb(&mut gop); - info!("GOP Framebuffer test complete"); - - // Return success status - Status::SUCCESS - */ } // Set a larger graphics mode. - pub fn set_graphics_mode(&mut self) { - // We know for sure QEMU has a 1024x768 mode. - let mode = self.gop + pub fn set_graphics_mode(&mut self, mode_tuple: Option<(i16,i16,i16)>) { + if mode_tuple == None { + // We know for sure QEMU has a 1024x768 mode. + let mode = self.gop .modes() .find(|mode| { let info = mode.info(); @@ -73,42 +61,38 @@ impl UefiFb { }) .unwrap(); - self.gop.set_mode(&mode).expect("Failed to set graphics mode"); + self.gop.set_mode(&mode).expect("Failed to set graphics mode"); + } else { + unimplemented!() + } } // Fill the screen with color. - fn fill_color(&mut self) { + fn fb_blt_fill(&mut self, color: BltPixel, dest: (usize, usize), dims: (usize, usize)) { let op = BltOp::VideoFill { - // Cornflower blue. - color: BltPixel::new(100, 149, 237), - dest: (0, 0), - dims: (1024, 768), + color, + dest, + dims }; self.gop.blt(op).expect("Failed to fill screen with color"); } + // Draw directly to the frame buffer. - fn draw_fb(&mut self) { - // The `virtio-gpu-pci` graphics device we use on aarch64 doesn't - // support `PixelFormat::BltOnly`. - if cfg!(target_arch = "aarch64") { - return; - } - + fn draw_fb(&mut self, index: usize, rgb: [u8; 3]) { let mi = self.gop.current_mode_info(); - let stride = mi.stride(); - let (width, height) = mi.resolution(); - let mut fb = self.gop.frame_buffer(); type PixelWriter = unsafe fn(&mut FrameBuffer, usize, [u8; 3]); - unsafe fn write_pixel_rgb(fb: &mut FrameBuffer, pixel_base: usize, rgb: [u8; 3]) { - fb.write_value(pixel_base, rgb); + + unsafe fn write_pixel_rgb(fb: &mut FrameBuffer, index: usize, rgb: [u8; 3]) { + fb.write_value(index, rgb); } - unsafe fn write_pixel_bgr(fb: &mut FrameBuffer, pixel_base: usize, rgb: [u8; 3]) { - fb.write_value(pixel_base, [rgb[2], rgb[1], rgb[0]]); + unsafe fn write_pixel_bgr(fb: &mut FrameBuffer, index: usize, rgb: [u8; 3]) { + fb.write_value(index, [rgb[2], rgb[1], rgb[0]]); } + let write_pixel: PixelWriter = match mi.pixel_format() { PixelFormat::Rgb => write_pixel_rgb, PixelFormat::Bgr => write_pixel_bgr, @@ -118,21 +102,6 @@ impl UefiFb { } }; - let mut fill_rectangle = |(x1, y1), (x2, y2), color| { - assert!((x1 < width) && (x2 < width), "Bad X coordinate"); - assert!((y1 < height) && (y2 < height), "Bad Y coordinate"); - for row in y1..y2 { - for column in x1..x2 { - unsafe { - let pixel_index = (row * stride) + column; - let pixel_base = 4 * pixel_index; - write_pixel(&mut fb, pixel_base, color); - } - } - } - }; - - fill_rectangle((50, 30), (150, 600), [250, 128, 64]); - fill_rectangle((400, 120), (750, 450), [16, 128, 255]); + unsafe { write_pixel(&mut fb, index, rgb) }; } } \ No newline at end of file