uefi_graphics_driver/
lib.rs1#![no_std]
2
3extern crate alloc;
4
5use alloc::string::String;
6use alloc::{vec, vec::Vec};
7
8use embedded_graphics_core::{
9 draw_target::DrawTarget,
10 geometry::{OriginDimensions, Size},
11 pixelcolor::Rgb888,
12 pixelcolor::RgbColor,
13 Pixel,
14};
15use uefi::proto::console::gop::{BltOp, BltPixel, BltRegion, GraphicsOutput};
16
17#[derive(Debug)]
19pub enum UefiDisplayError {
20 PixelRangeError(String),
21 DisplayError(String),
22}
23
24pub struct UefiDisplay {
26 width: usize,
28 height: usize,
30 pixels: Vec<BltPixel>,
32}
33
34impl UefiDisplay {
35 pub fn new((width, height): (usize, usize)) -> Self {
36 Self {
37 width,
38 height,
39 pixels: vec![BltPixel::new(0, 0, 0); width * height],
40 }
41 }
42
43 fn pixel(&mut self, x: usize, y: usize) -> Option<&mut BltPixel> {
44 self.pixels.get_mut(y * self.width + x)
45 }
46
47 pub fn flush(&self, gop: &mut GraphicsOutput) -> Result<(), UefiDisplayError> {
48 match gop.blt(BltOp::BufferToVideo {
49 buffer: &self.pixels,
50 src: BltRegion::Full,
51 dest: (0, 0),
52 dims: (self.width, self.height),
53 }) {
54 Ok(_) => Ok(()),
55 Err(_) => Err(UefiDisplayError::DisplayError("draw pixel error".into())),
56 }
57 }
58}
59
60impl OriginDimensions for UefiDisplay {
61 fn size(&self) -> Size {
62 Size {
63 width: self.width as u32,
64 height: self.height as u32,
65 }
66 }
67}
68
69impl DrawTarget for UefiDisplay {
70 type Color = Rgb888;
71 type Error = UefiDisplayError;
72
73 fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
74 where
75 I: IntoIterator<Item = Pixel<Self::Color>>,
76 {
77 for Pixel(point, color) in pixels {
78 let (x, y) = (point.x, point.y);
80 if let Some(pixel) = self.pixel(x as usize, y as usize) {
82 pixel.red = color.r();
84 pixel.green = color.g();
85 pixel.blue = color.b();
86 }
87 }
88
89 Ok(())
90 }
91}