Overview
The framebuffer module provides direct access to VESA linear framebuffer with hardware-accelerated operations and dirty region tracking for optimal performance.
Location: kernel/src/graphics/driver/framebuffer.rs
Core Components
Framebuffer
The main framebuffer struct managing the backbuffer and hardware video memory.
pub struct Framebuffer {
lfb: u64, // Linear framebuffer address
backbuf: u64, // Back buffer (0x0060_0000)
pub width: usize,
pub height: usize,
lfb_pitch: usize,
bpp: u8,
back_pitch: usize,
pub dirty: DirtyRegion,
}
Constructor
Initializes the framebuffer by reading VESA mode information from memory-mapped addresses and allocating the backbuffer.
Returns: A new framebuffer instance with default resolution or VESA detected mode.
Console
High-level console abstraction with text rendering and drawing primitives.
pub struct Console {
fb: Framebuffer,
pub cursor_x: usize,
pub cursor_y: usize,
pub margin_x: usize,
pub fg_color: Color,
pub bg_color: Color,
font_w: usize, // 8px
font_h: usize, // 8px
}
Constructor
Creates a new console with an embedded framebuffer instance.
Color
Struct Definition
pub struct Color(pub u32); // 0xRRGGBB format
Predefined Colors
0x01080F - Main background dark blue
0x0E2240 - Active tab background
Color Methods
pub const fn new(r: u8, g: u8, b: u8) -> Self
Creates a new color from RGB components.
pub const fn dim(self, alpha: u8) -> Self
Dims the color by an alpha factor.
Opacity (0=transparent, 255=opaque)
pub const fn blend(self, other: Color, alpha: u8) -> Self
Blends two colors with alpha blending.
Blend amount (0=fully other, 255=fully self)
Drawing Primitives
fill_rect
pub fn fill_rect(&mut self, x: usize, y: usize, w: usize, h: usize, color: Color)
Fills a rectangle with solid color using hardware-accelerated rep stosd.
Example:
let mut console = Console::new();
console.fill_rect(100, 100, 200, 150, Color::PORTIX_GOLD);
console.present();
draw_line
pub fn draw_line(&mut self, x0: i32, y0: i32, x1: i32, y1: i32, color: Color)
Draws a line using Bresenham’s algorithm.
fill_circle
pub fn fill_circle(&mut self, cx: i32, cy: i32, radius: i32, color: Color)
Fills a circle using midpoint circle algorithm.
fill_rounded
pub fn fill_rounded(&mut self, x: usize, y: usize, w: usize, h: usize, radius: usize, color: Color)
Fills a rounded rectangle.
Buffer Management
present
pub fn present(&mut self)
Presents the backbuffer to screen using dirty region tracking. Only modified regions are copied to video memory using hardware-accelerated rep movsd.
Performance: 3-5x faster than naive pixel copy due to:
- Dirty region optimization
- x86
rep movsd instruction
- Single-pass scanline copy
Example:
let mut console = Console::new();
console.clear(Color::PORTIX_BG);
console.fill_rect(50, 50, 100, 100, Color::RED);
console.present(); // Only copies dirty regions
present_full
pub fn present_full(&mut self)
Forces a full screen refresh, ignoring dirty region tracking. Use when switching tabs or major UI changes.
clear
pub fn clear(&mut self, color: Color)
Clears the entire screen with a solid color and resets cursor position.
Text Rendering
write
pub fn write(&mut self, text: &str, color: Color)
Writes text at the current cursor position with automatic line wrapping.
Text to render (supports \n, \t)
write_at
pub fn write_at(&mut self, text: &str, x: usize, y: usize, color: Color)
Writes text at specific coordinates without moving the cursor.
draw_char
fn draw_char(&mut self, x: usize, y: usize, ch: char, fg: Color, bg: Color)
Draws a single character using the 8x8 bitmap font.
Font: ASCII 32-127, 8x8 pixels per glyph
Location: kernel/src/graphics/render/font.rs:6
Character to draw (ASCII 32-127)
Layout
Responsive layout calculator for UI chrome elements.
pub struct Layout {
pub fw: usize, // Frame width
pub fh: usize, // Frame height
pub header_h: usize, // Header height
pub tab_h: usize, // Tab bar height
pub content_y: usize, // Content area start Y
pub bottom_y: usize, // Bottom bar Y
pub status_h: usize, // Status bar height
pub font_w: usize, // Font width (8)
pub font_h: usize, // Font height (8)
// ... more fields
}
Constructor
pub fn new(fw: usize, fh: usize) -> Self
Calculates responsive layout proportions based on framebuffer dimensions.
Example:
let console = Console::new();
let layout = Layout::new(console.width(), console.height());
// Draw header
console.fill_rect(0, 0, layout.fw, layout.header_h, Color::PORTIX_PANEL);
DirtyRegion
Tracks modified screen regions for optimized blitting.
pub struct DirtyRegion {
pub min_x: usize,
pub min_y: usize,
pub max_x: usize,
pub max_y: usize,
pub dirty: bool,
}
Methods
pub fn mark(&mut self, x: usize, y: usize, w: usize, h: usize)
Marks a region as dirty.
Resets dirty tracking after present.
Hardware Acceleration
The framebuffer uses x86_64 SIMD instructions for maximum performance:
#[cfg(target_arch = "x86_64")]
unsafe fn fast_fill_u32(dst: *mut u32, val: u32, count: usize) {
core::arch::asm!(
"cld", "rep stosd",
inout("rdi") dst => _,
inout("ecx") count => _,
in("eax") val,
);
}
Alpha LUT
Pre-computed alpha multiplication lookup table eliminates divisions:
static mut ALPHA_LUT: [[u8; 256]; 256];
pub fn init_alpha_lut() // Called during framebuffer initialization
Bayer Dithering
4x4 ordered dithering matrix for gradient rendering:
const BAYER_4X4: [[u8; 4]; 4] = [
[ 0, 8, 2, 10],
[12, 4, 14, 6],
[ 3, 11, 1, 9],
[15, 7, 13, 5],
];
Used in fill_gradient_dither() for smooth gradients without color banding.