⚠️ VeridianOS Kernel Documentation - This is low-level kernel code. All functions are unsafe unless explicitly marked otherwise. no_std

veridian_kernel/graphics/
mod.rs

1//! Graphics and GUI subsystem
2//!
3//! Provides basic graphics support including framebuffer and compositor.
4
5use crate::error::KernelError;
6
7pub mod compositor;
8pub mod cursor;
9pub mod damage_tracking;
10pub mod drm_ioctl;
11pub mod fbcon;
12pub mod font8x16;
13pub mod framebuffer;
14pub mod gl_compositor;
15pub mod gpu;
16pub mod gpu_accel;
17pub mod multi_output;
18pub mod shader;
19pub mod texture_atlas;
20pub mod vsync_sw;
21
22/// Canonical pixel format descriptor.
23///
24/// This is the single source of truth for pixel formats across all subsystems
25/// (drivers, video, graphics acceleration, Wayland buffers).
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub enum PixelFormat {
28    /// 24-bit: R(8) G(8) B(8), packed.
29    Rgb888,
30    /// 24-bit: B(8) G(8) R(8), packed.
31    Bgr888,
32    /// 32-bit: R(8) G(8) B(8) A(8).
33    Rgba8888,
34    /// 32-bit: B(8) G(8) R(8) A(8).
35    Bgra8888,
36    /// 32-bit: x(8) R(8) G(8) B(8), alpha ignored.
37    Xrgb8888,
38    /// 32-bit: A(8) R(8) G(8) B(8), premultiplied alpha.
39    Argb8888,
40    /// 16-bit: R(5) G(6) B(5).
41    Rgb565,
42    /// 32-bit: B(8) G(8) R(8) x(8), alpha ignored.
43    Bgrx8888,
44    /// 8-bit grayscale.
45    Gray8,
46    /// 32-bit: x(8) B(8) G(8) R(8), alpha ignored.
47    Xbgr8888,
48    /// 32-bit: A(8) B(8) G(8) R(8).
49    Abgr8888,
50}
51
52impl PixelFormat {
53    /// Number of bytes per pixel.
54    pub fn bytes_per_pixel(&self) -> usize {
55        match self {
56            Self::Xrgb8888
57            | Self::Argb8888
58            | Self::Bgrx8888
59            | Self::Xbgr8888
60            | Self::Abgr8888
61            | Self::Rgba8888
62            | Self::Bgra8888 => 4,
63            Self::Rgb888 | Self::Bgr888 => 3,
64            Self::Rgb565 => 2,
65            Self::Gray8 => 1,
66        }
67    }
68
69    /// Bytes per pixel (alias for `bytes_per_pixel`, returns `u32`).
70    pub fn bpp(&self) -> u32 {
71        self.bytes_per_pixel() as u32
72    }
73
74    /// Whether this format carries an alpha channel.
75    pub fn has_alpha(&self) -> bool {
76        matches!(
77            self,
78            Self::Argb8888 | Self::Abgr8888 | Self::Rgba8888 | Self::Bgra8888
79        )
80    }
81
82    /// Convert a Wayland wl_shm format code to our enum.
83    pub fn from_wl_format(code: u32) -> Option<Self> {
84        match code {
85            0 => Some(PixelFormat::Argb8888), // WL_SHM_FORMAT_ARGB8888
86            1 => Some(PixelFormat::Xrgb8888), // WL_SHM_FORMAT_XRGB8888
87            _ => None,
88        }
89    }
90
91    /// Convert our format to the Wayland wl_shm format code.
92    pub fn to_wl_format(self) -> u32 {
93        match self {
94            PixelFormat::Argb8888 => 0,
95            PixelFormat::Xrgb8888 => 1,
96            PixelFormat::Rgb565 => 0x20363154, // WL_SHM_FORMAT_RGB565
97            _ => 0,                            // Default to ARGB8888 for unsupported formats
98        }
99    }
100}
101
102/// Color representation (RGBA)
103#[derive(Debug, Clone, Copy, PartialEq, Eq)]
104pub struct Color {
105    pub r: u8,
106    pub g: u8,
107    pub b: u8,
108    pub a: u8,
109}
110
111impl Color {
112    pub const BLACK: Self = Self::rgb(0, 0, 0);
113    pub const WHITE: Self = Self::rgb(255, 255, 255);
114    pub const RED: Self = Self::rgb(255, 0, 0);
115    pub const GREEN: Self = Self::rgb(0, 255, 0);
116    pub const BLUE: Self = Self::rgb(0, 0, 255);
117
118    pub const fn rgb(r: u8, g: u8, b: u8) -> Self {
119        Self { r, g, b, a: 255 }
120    }
121
122    pub const fn rgba(r: u8, g: u8, b: u8, a: u8) -> Self {
123        Self { r, g, b, a }
124    }
125
126    pub fn to_u32(&self) -> u32 {
127        ((self.a as u32) << 24) | ((self.r as u32) << 16) | ((self.g as u32) << 8) | (self.b as u32)
128    }
129}
130
131/// Rectangle
132#[derive(Debug, Clone, Copy)]
133pub struct Rect {
134    pub x: i32,
135    pub y: i32,
136    pub width: u32,
137    pub height: u32,
138}
139
140/// Graphics context
141pub trait GraphicsContext {
142    fn draw_pixel(&mut self, x: i32, y: i32, color: Color);
143    fn draw_rect(&mut self, rect: Rect, color: Color);
144    fn fill_rect(&mut self, rect: Rect, color: Color);
145    fn clear(&mut self, color: Color);
146}
147
148/// Initialize graphics subsystem
149pub fn init() -> Result<(), KernelError> {
150    println!("[GFX] Initializing graphics subsystem...");
151
152    // Initialize framebuffer
153    framebuffer::init()?;
154
155    // Initialize compositor
156    compositor::init()?;
157
158    println!("[GFX] Graphics subsystem initialized");
159    Ok(())
160}
161
162#[cfg(test)]
163mod tests {
164    use super::*;
165
166    #[test]
167    fn test_color() {
168        let c = Color::rgb(128, 64, 32);
169        assert_eq!(c.r, 128);
170        assert_eq!(c.g, 64);
171        assert_eq!(c.b, 32);
172        assert_eq!(c.a, 255);
173    }
174
175    #[test]
176    fn test_color_to_u32() {
177        let c = Color::rgb(255, 0, 128);
178        let u = c.to_u32();
179        assert_ne!(u, 0);
180    }
181}