Overview

The FreeWorld Graphics System provides complete graphics support from kernel to user space. It uses UEFI Graphics Output Protocol (GOP) for modern framebuffer access, replacing legacy VESA/VBE.

Status: Complete graphics system with GOP framebuffer, framebuffer console, and Node.js bridge. Total: ~1,200+ lines of code.
UEFI Migration Complete (2025): Graphics now uses GOP framebuffer from UEFI. VESA/VBE is deprecated.

GOP Framebuffer (UEFI-Aware)

Location: kernel/drivers/framebuffer_console.asm (~540 lines)

The GOP (Graphics Output Protocol) framebuffer provides direct linear framebuffer access from UEFI:

Features

  • UEFI GOP: Framebuffer information from UEFI bootloader
  • Framebuffer Console: Text output directly to framebuffer (replaces serial/VGA)
  • 8x16 Font: Bitmap font for ASCII characters (0x20-0x7E)
  • Character Rendering: Pixel-by-pixel character drawing
  • Automatic Scrolling: Screen scrolling when cursor reaches bottom
  • Color Support: Text and background colors

Framebuffer Information

Framebuffer information is provided by UEFI bootloader via boot_params_t:

  • Base Address: Physical framebuffer base address
  • Size: Framebuffer size in bytes
  • Width: Screen width in pixels
  • Height: Screen height in pixels
  • Pixels Per Scanline: Pitch/stride in pixels
  • Bits Per Pixel: Color depth (typically 32-bit ARGB)

Key Functions

  • framebuffer_console_init() - Initialize framebuffer console
  • framebuffer_putchar() - Print character to framebuffer
  • framebuffer_println() - Print string with newline
  • framebuffer_clear_screen() - Clear framebuffer
  • render_char() - Render character using bitmap font
  • scroll_screen() - Scroll screen up one line

VESA Graphics Driver - ⚠️ DEPRECATED

Location: kernel/drivers/vesa.asm (~400 lines)

Status: ⚠️ Deprecated - Replaced by GOP framebuffer

The legacy VESA driver provided direct framebuffer access via VESA BIOS Extensions. See VESA Graphics documentation for details.

Replacement: Use GOP framebuffer from UEFI instead. VESA is no longer used in UEFI boot.

Legacy Graphics Mode

  • Resolution: 1024x768
  • Color Depth: 32-bit (ARGB)
  • Mode Number: 0x118
  • Framebuffer: Linear (direct memory access)

Graphics Bridge (graphics_bridge.asm)

Location: kernel/graphics/graphics_bridge.asm (~200 lines)

C-callable functions that wrap the VESA driver for use from C and Node.js:

Key Functions

Function Description C Signature
graphics_init Initialize graphics mode int graphics_init(void)
graphics_get_framebuffer Get framebuffer address void* graphics_get_framebuffer(void)
graphics_get_size Get screen dimensions void graphics_get_size(int* width, int* height)
graphics_draw_pixel Draw pixel void graphics_draw_pixel(int x, int y, unsigned int color)
graphics_draw_line Draw line void graphics_draw_line(int x1, int y1, int x2, int y2, unsigned int color)
graphics_draw_rect Draw filled rectangle void graphics_draw_rect(int x, int y, int width, int height, unsigned int color)
graphics_clear_screen Clear screen void graphics_clear_screen(unsigned int color)
graphics_blit Copy buffer to framebuffer void graphics_blit(int x, int y, int width, int height, void* buffer)

Node.js Bridge

Location: kernel/graphics/node_bridge.c, system/graphics-bridge.js

Bridge layer connecting kernel graphics to Node.js window system:

C Bridge (node_bridge.c)

Provides Node.js-callable functions:

  • node_graphics_init - Initialize graphics and return framebuffer info
  • node_graphics_blit_window - Blit window buffer to screen
  • node_graphics_draw_pixel - Draw pixel (for testing)
  • node_graphics_draw_rect - Draw rectangle
  • node_graphics_clear - Clear screen

JavaScript Bridge (graphics-bridge.js)

Node.js module providing graphics operations:

const graphicsBridge = require('./graphics-bridge');

// Initialize graphics
graphicsBridge.init();

// Get framebuffer info
const info = graphicsBridge.getFramebufferInfo();
console.log(`Framebuffer: ${info.width}x${info.height}`);

// Blit window to framebuffer
graphicsBridge.blitWindow(x, y, width, height, buffer);

Integration with Compositor

The graphics bridge is integrated with the Node.js compositor (system/compositor.js):

const graphicsBridge = require('./graphics-bridge');

class Compositor {
    render() {
        // Initialize graphics if needed
        if (!graphicsBridge.initialized) {
            graphicsBridge.init();
        }
        
        // Clear screen
        graphicsBridge.clear(0xFF000000);  // Black
        
        // Blit all windows to framebuffer
        for (const window of windows) {
            if (window.visible && window.dirty) {
                graphicsBridge.blitWindow(
                    window.x, window.y,
                    window.width, window.height,
                    window.dc.buffer
                );
                window.dirty = false;
            }
        }
    }
}

Integration with Device Context

The Device Context (system/dc.js) now uses actual RGBA buffers:

class DeviceContext {
    constructor(width, height) {
        // Create RGBA buffer for window content
        this.buffer = Buffer.alloc(width * height * 4);
        this.buffer.fill(0);  // Initialize to transparent black
    }
    
    drawPixel(x, y) {
        // Write pixel to buffer (RGBA format)
        const offset = (y * this.width + x) * 4;
        this.buffer[offset] = (color >> 16) & 0xFF;      // R
        this.buffer[offset + 1] = (color >> 8) & 0xFF;  // G
        this.buffer[offset + 2] = color & 0xFF;          // B
        this.buffer[offset + 3] = (color >> 24) & 0xFF;   // A
    }
}

Usage Examples

Initialize Graphics Mode

; In assembly
call graphics_init
cmp eax, 0
jne graphics_error

; In C
if (graphics_init() != 0) {
    // Error initializing graphics
}

; In Node.js
if (!graphicsBridge.init()) {
    console.error('Failed to initialize graphics');
}

Draw to Framebuffer

; Draw a pixel
mov eax, 100   ; X
mov ebx, 100   ; Y
mov ecx, 0xFFFFFFFF  ; White
call graphics_draw_pixel

; Draw a rectangle
mov eax, 50    ; X
mov ebx, 50    ; Y
mov ecx, 200   ; Width
mov edx, 100   ; Height
mov esi, 0xFF0000FF  ; Blue
call graphics_draw_rect

Blit Window Buffer

// In Node.js compositor
const window = getWindow(hwnd);
graphicsBridge.blitWindow(
    window.x,           // X position
    window.y,           // Y position
    window.width,      // Width
    window.height,      // Height
    window.dc.buffer    // RGBA buffer
);

Graphics Pipeline

The complete graphics pipeline:

  1. Application draws to Device Context (DC) buffer
  2. Compositor collects all window buffers
  3. Graphics Bridge blits window buffers to framebuffer
  4. VESA Driver provides direct framebuffer access
  5. Hardware displays framebuffer on screen