Skip to main content

roxy_loader_api/
framebuffer.rs

1/// A framebuffer provided to the kernel at boot time.
2///
3/// Kernels can use this value to find the framebuffer memory and understand its
4/// basic layout.
5#[derive(Clone, Copy)]
6#[repr(C)]
7pub struct Framebuffer {
8    ptr: usize,
9    /// The total size of the framebuffer in bytes.
10    pub size: usize,
11    /// The number of pixels in each row of the framebuffer.
12    pub stride: usize,
13}
14
15impl Framebuffer {
16    /// Creates a framebuffer value.
17    pub fn new(ptr: *mut u8, size: usize, stride: usize) -> Self {
18        Self {
19            ptr: ptr as usize,
20            size,
21            stride,
22        }
23    }
24
25    /// Returns a pointer to the framebuffer memory.
26    pub fn ptr(&self) -> *mut u8 {
27        self.ptr as *mut u8
28    }
29}
30
31#[cfg(test)]
32mod tests {
33    use super::Framebuffer;
34    use core::{
35        mem::{MaybeUninit, align_of, size_of},
36        ptr::addr_of,
37    };
38
39    #[test]
40    fn layout_is_stable() {
41        assert_eq!(
42            size_of::<Framebuffer>(),
43            size_of::<(*mut u8, usize, usize)>()
44        );
45        assert_eq!(align_of::<Framebuffer>(), align_of::<usize>());
46
47        let framebuffer = MaybeUninit::<Framebuffer>::uninit();
48        let base = framebuffer.as_ptr();
49
50        // ABI stability matters because the loader and kernel share this struct across a raw boundary.
51        unsafe {
52            assert_eq!(addr_of!((*base).ptr) as usize - base as usize, 0);
53            assert_eq!(
54                addr_of!((*base).size) as usize - base as usize,
55                size_of::<*mut u8>()
56            );
57            assert_eq!(
58                addr_of!((*base).stride) as usize - base as usize,
59                size_of::<*mut u8>() + size_of::<usize>()
60            );
61        }
62    }
63}