Skip to main content

os/drivers/gpu/
mod.rs

1use crate::drivers::bus::virtio::VirtioHal;
2use crate::sync::UPIntrFreeCell;
3use alloc::{sync::Arc, vec::Vec};
4use core::any::Any;
5use embedded_graphics::pixelcolor::Rgb888;
6use tinybmp::Bmp;
7use virtio_drivers::{VirtIOGpu, VirtIOHeader};
8const VIRTIO7: usize = 0x10007000;
9pub trait GpuDevice: Send + Sync + Any {
10    fn get_framebuffer(&self) -> &mut [u8];
11    fn flush(&self);
12}
13
14lazy_static::lazy_static!(
15    pub static ref GPU_DEVICE: Arc<dyn GpuDevice> = Arc::new(VirtIOGpuWrapper::new());
16);
17
18pub struct VirtIOGpuWrapper {
19    gpu: UPIntrFreeCell<VirtIOGpu<'static, VirtioHal>>,
20    fb: &'static [u8],
21}
22static BMP_DATA: &[u8] = include_bytes!("../../assert/mouse.bmp");
23impl VirtIOGpuWrapper {
24    pub fn new() -> Self {
25        unsafe {
26            let mut virtio =
27                VirtIOGpu::<VirtioHal>::new(&mut *(VIRTIO7 as *mut VirtIOHeader)).unwrap();
28
29            let fbuffer = virtio.setup_framebuffer().unwrap();
30            let len = fbuffer.len();
31            let ptr = fbuffer.as_mut_ptr();
32            let fb = core::slice::from_raw_parts_mut(ptr, len);
33
34            let bmp = Bmp::<Rgb888>::from_slice(BMP_DATA).unwrap();
35            let raw = bmp.as_raw();
36            let mut b = Vec::new();
37            for i in raw.image_data().chunks(3) {
38                let mut v = i.to_vec();
39                b.append(&mut v);
40                if i == [255, 255, 255] {
41                    b.push(0x0)
42                } else {
43                    b.push(0xff)
44                }
45            }
46            virtio.setup_cursor(b.as_slice(), 50, 50, 50, 50).unwrap();
47
48            Self {
49                gpu: UPIntrFreeCell::new(virtio),
50                fb,
51            }
52        }
53    }
54}
55
56impl GpuDevice for VirtIOGpuWrapper {
57    fn flush(&self) {
58        self.gpu.exclusive_access().flush().unwrap();
59    }
60    fn get_framebuffer(&self) -> &mut [u8] {
61        unsafe {
62            let ptr = self.fb.as_ptr() as *const _ as *mut u8;
63            core::slice::from_raw_parts_mut(ptr, self.fb.len())
64        }
65    }
66}