plex_boot/core/
display.rs1use alloc::vec;
5use alloc::vec::Vec;
6use embedded_graphics::{pixelcolor::Rgb888, prelude::*};
7use uefi::proto::console::gop::{BltOp, BltPixel, BltRegion, GraphicsOutput};
8
9pub struct GopDisplay<'a> {
14 width: usize,
15 height: usize,
16 buffer: Vec<BltPixel>,
17 gop: &'a mut GraphicsOutput,
18}
19
20impl<'a> GopDisplay<'a> {
21 pub fn new(gop: &'a mut GraphicsOutput) -> Self {
23 let (width, height) = gop.current_mode_info().resolution();
24 Self {
25 width,
26 height,
27 buffer: vec![BltPixel::new(0, 0, 0); width * height],
28 gop,
29 }
30 }
31
32 pub fn flush(&mut self) -> Result<(), uefi::Error> {
34 self.gop.blt(BltOp::BufferToVideo {
35 buffer: &self.buffer,
36 src: BltRegion::Full,
37 dest: (0, 0),
38 dims: (self.width, self.height),
39 })
40 }
41
42 pub fn clear(&mut self, color: Rgb888) {
44 let pixel = BltPixel::new(color.r(), color.g(), color.b());
45 self.buffer.fill(pixel);
46 }
47}
48
49impl<'a> DrawTarget for GopDisplay<'a> {
50 type Color = Rgb888;
51 type Error = core::convert::Infallible;
52
53 fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
54 where
55 I: IntoIterator<Item = Pixel<Self::Color>>,
56 {
57 for Pixel(coord, color) in pixels.into_iter() {
58 let (x, y) = match (coord.x, coord.y) {
60 (x, y) if x >= 0 && y >= 0 => (x as usize, y as usize),
61 _ => continue,
62 };
63
64 if x < self.width && y < self.height {
65 let index = y * self.width + x;
66 let pixel = &mut self.buffer[index];
67 pixel.red = color.r();
68 pixel.green = color.g();
69 pixel.blue = color.b();
70 }
71 }
72 Ok(())
73 }
74}
75
76impl<'a> OriginDimensions for GopDisplay<'a> {
77 fn size(&self) -> Size {
78 Size::new(self.width as u32, self.height as u32)
79 }
80}