uefi_graphics_driver/
lib.rs

1#![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/// display error
18#[derive(Debug)]
19pub enum UefiDisplayError {
20    PixelRangeError(String),
21    DisplayError(String),
22}
23
24/// Display Buffer
25pub struct UefiDisplay {
26    /// 宽
27    width: usize,
28    // 长
29    height: usize,
30    // pixels
31    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            // 像素坐标
79            let (x, y) = (point.x, point.y);
80            // 坐标转换为pixels的索引
81            if let Some(pixel) = self.pixel(x as usize, y as usize) {
82                // 写入颜色
83                pixel.red = color.r();
84                pixel.green = color.g();
85                pixel.blue = color.b();
86            }
87        }
88
89        Ok(())
90    }
91}