tg_rcore_tutorial_driver/
gpu.rs1extern crate alloc;
2
3use alloc::vec::Vec;
4use core::any::Any;
5use embedded_graphics::pixelcolor::Rgb888;
6use spin::Mutex;
7use tinybmp::Bmp;
8use virtio_drivers::{Hal, MmioTransport, VirtIOGpu};
9
10use crate::devices::Device;
11
12pub trait GpuDevice: Device + Send + Sync + Any {
13 fn get_framebuffer(&self) -> Result<&mut [u8], virtio_drivers::Error>;
14 fn resolution(&self) -> Result<(u32, u32), virtio_drivers::Error>;
15 fn flush(&self) -> Result<(), virtio_drivers::Error>;
16}
17
18pub struct VirtIOGpuWrapper<H: Hal> {
19 gpu: Mutex<VirtIOGpu<'static, H, MmioTransport>>,
20 fb: &'static [u8],
21}
22
23unsafe impl<H: Hal> Send for VirtIOGpuWrapper<H> {}
24unsafe impl<H: Hal> Sync for VirtIOGpuWrapper<H> {}
25
26static BMP_DATA: &[u8] = include_bytes!("mouse.bmp");
27
28impl<H: Hal> VirtIOGpuWrapper<H> {
29 pub fn new(transport: MmioTransport) -> Result<Self, virtio_drivers::Error> {
30 let mut virtio = VirtIOGpu::new(transport)?;
31
32 let fbuffer = virtio.setup_framebuffer()?;
33 let len = fbuffer.len();
34 let ptr = fbuffer.as_mut_ptr();
35 let fb = unsafe { core::slice::from_raw_parts_mut(ptr, len) };
38
39 let bmp = Bmp::<Rgb888>::from_slice(BMP_DATA).expect("Failed to parse mouse.bmp");
40 let raw = bmp.as_raw();
41 let mut b = Vec::new();
42 for i in raw.image_data().chunks(3) {
43 let mut v = i.to_vec();
44 b.append(&mut v);
45 if i == [255, 255, 255] {
46 b.push(0x0)
47 } else {
48 b.push(0xff)
49 }
50 }
51 virtio.setup_cursor(b.as_slice(), 50, 50, 50, 50)?;
52
53 Ok(Self {
54 gpu: Mutex::new(virtio),
55 fb,
56 })
57 }
58}
59
60impl<H: Hal + 'static> GpuDevice for VirtIOGpuWrapper<H> {
61 fn flush(&self) -> Result<(), virtio_drivers::Error> {
62 self.gpu.lock().flush()
63 }
64
65 fn resolution(&self) -> Result<(u32, u32), virtio_drivers::Error> {
66 self.gpu.lock().resolution()
67 }
68
69 fn get_framebuffer(&self) -> Result<&mut [u8], virtio_drivers::Error> {
70 unsafe {
73 let ptr = self.fb.as_ptr() as *mut u8;
74 Ok(core::slice::from_raw_parts_mut(ptr, self.fb.len()))
75 }
76 }
77}
78
79impl<H: Hal + 'static> Device for VirtIOGpuWrapper<H> {
80 fn handle_irq(&self) {}
81}