Skip to main content

strat9_kernel/framebuffer/gpu/
mod.rs

1pub trait GraphicsBackend {
2    fn fill_rect(&mut self, x: u32, y: u32, w: u32, h: u32, color: u32);
3    fn blit(&mut self, dst_x: u32, dst_y: u32, src: &[u32], src_w: u32, src_h: u32);
4    fn present(&mut self);
5}
6
7pub struct CpuFramebuffer {
8    pub buffer: *mut u32,
9    pub width: u32,
10    pub height: u32,
11    pub stride: u32,
12    pub ops: super::FramebufferOps,
13}
14
15impl GraphicsBackend for CpuFramebuffer {
16    fn fill_rect(&mut self, x: u32, y: u32, w: u32, h: u32, color: u32) {
17        let end_y = core::cmp::min(y + h, self.height);
18        let end_x = core::cmp::min(x + w, self.width);
19        let actual_w = end_x.saturating_sub(x);
20
21        for cur_y in y..end_y {
22            let offset = (cur_y * self.stride + x) as usize;
23            unsafe {
24                (self.ops.fill)(self.buffer.add(offset), color, actual_w as usize);
25            }
26        }
27    }
28
29    fn blit(&mut self, dst_x: u32, dst_y: u32, src: &[u32], src_w: u32, src_h: u32) {
30        let end_y = core::cmp::min(dst_y + src_h, self.height);
31        let end_x = core::cmp::min(dst_x + src_w, self.width);
32        let actual_w = end_x.saturating_sub(dst_x);
33        let actual_h = end_y.saturating_sub(dst_y);
34
35        for i in 0..actual_h {
36            let src_offset = (i * src_w) as usize;
37            let dst_offset = ((dst_y + i) * self.stride + dst_x) as usize;
38            unsafe {
39                (self.ops.blit)(
40                    self.buffer.add(dst_offset),
41                    src.as_ptr().add(src_offset),
42                    actual_w as usize,
43                );
44            }
45        }
46    }
47
48    fn present(&mut self) {
49        // CPU buffer flush or nothing if directly mapped
50    }
51}