1#![no_std]
3use core::{convert::TryInto, marker::PhantomData};
4use embedded_graphics_core::{
5 draw_target::DrawTarget,
6 geometry::{OriginDimensions, Size},
7 pixelcolor::{IntoStorage, Rgb888},
8 Pixel,
9};
10
11#[derive(Debug)]
12pub struct Unsupported(());
13
14impl Unsupported {
15 fn new<T>(_: T) -> Self {
16 Unsupported(())
17 }
18}
19
20pub struct UefiDisplay<'a> {
22 fb: *mut u8,
24 stride: u32,
25 size: (u32, u32),
26 spooky: PhantomData<&'a mut [u8]>,
27}
28
29impl<'a> UefiDisplay<'a> {
30 pub fn new<T>(fb: *mut u8, stride: u32, size: (u32, u32), _lifetime: &'a T) -> Self {
41 Self {
42 fb,
43 stride,
44 size,
45 spooky: PhantomData,
46 }
47 }
48}
49
50impl<'a> OriginDimensions for UefiDisplay<'a> {
51 fn size(&self) -> Size {
53 Size::from(self.size)
54 }
55}
56
57impl<'a> DrawTarget for UefiDisplay<'a> {
58 type Color = Rgb888;
59
60 type Error = Unsupported;
61
62 fn draw_iter<I>(&mut self, pixels: I) -> Result<(), Self::Error>
63 where
64 I: IntoIterator<Item = Pixel<Self::Color>>,
65 {
66 let pixels = pixels.into_iter();
67 for Pixel(point, color) in pixels {
68 let bytes = color.into_storage();
69 let stride = self.stride as u64;
70 let (x, y) = (point.x as u64, point.y as u64);
71 let index: usize = (((y * stride) + x) * 4)
73 .try_into()
74 .map_err(Unsupported::new)?;
75 unsafe { (self.fb.add(index) as *mut u32).write_volatile(bytes) };
76 }
77 Ok(())
78 }
79}