112 lines
2.7 KiB
Zig
112 lines
2.7 KiB
Zig
// MARKUS MAIWALD (ARCHITECT) | VOXIS FORGE (AI)
|
|
// Phase 35a: The Surface Allocator
|
|
// Manages contiguous memory chunks for window buffers.
|
|
|
|
const std = @import("std");
|
|
const uart = @import("uart.zig");
|
|
|
|
pub const MAX_SURFACES = 16;
|
|
pub const SURFACE_POOL_SIZE = 32 * 1024 * 1024; // 32MB for surfaces
|
|
|
|
// Surface Descriptor
|
|
pub const Surface = struct {
|
|
id: i32,
|
|
ptr: [*]u32,
|
|
width: u32,
|
|
height: u32,
|
|
active: bool,
|
|
};
|
|
|
|
// Global Surface Pool
|
|
var surfaces: [MAX_SURFACES]Surface = undefined;
|
|
var next_surface_id: i32 = 1;
|
|
|
|
// Backing memory for surfaces (in BSS)
|
|
var surface_heap: [SURFACE_POOL_SIZE]u8 align(4096) = undefined;
|
|
var heap_offset: usize = 0;
|
|
|
|
export fn hal_surface_init() void {
|
|
for (&surfaces) |*s| {
|
|
s.id = -1;
|
|
s.active = false;
|
|
s.ptr = undefined;
|
|
s.width = 0;
|
|
s.height = 0;
|
|
}
|
|
heap_offset = 0;
|
|
uart.print("[Surface] Allocator Initialized. Pool: 32MB\n");
|
|
}
|
|
|
|
pub fn alloc(width: u32, height: u32) ?i32 {
|
|
const size = width * height * 4;
|
|
|
|
// Alignment to 4096
|
|
const aligned_size = (size + 4095) & ~@as(u32, 4095);
|
|
|
|
if (heap_offset + aligned_size > SURFACE_POOL_SIZE) {
|
|
uart.print("[Surface] ERROR: Out of Memory in Surface Pool!\n");
|
|
return null;
|
|
}
|
|
|
|
// Find free slot
|
|
var slot: ?*Surface = null;
|
|
for (&surfaces) |*s| {
|
|
if (!s.active) {
|
|
slot = s;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (slot) |s| {
|
|
s.id = next_surface_id;
|
|
next_surface_id += 1;
|
|
s.width = width;
|
|
s.height = height;
|
|
s.ptr = @ptrCast(@alignCast(&surface_heap[heap_offset]));
|
|
s.active = true;
|
|
|
|
heap_offset += aligned_size;
|
|
|
|
uart.print("[Surface] Allocated ID=");
|
|
uart.print_hex(@intCast(s.id));
|
|
uart.print(" Size=");
|
|
uart.print_hex(size);
|
|
uart.print("\n");
|
|
|
|
return s.id;
|
|
}
|
|
|
|
uart.print("[Surface] ERROR: Max Surfaces Reached!\n");
|
|
return null;
|
|
}
|
|
|
|
pub fn get_surface(id: i32) ?*Surface {
|
|
for (&surfaces) |*s| {
|
|
if (s.active and s.id == id) return s;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
pub fn free(id: i32) bool {
|
|
for (&surfaces) |*s| {
|
|
if (s.active and s.id == id) {
|
|
s.active = false;
|
|
// Note: In our simple bump-style allocator, we don't reclaim heap space
|
|
// unless we implement a real allocator. For now, we assume surfaces are
|
|
// mostly permanent or the system reboots.
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Exported for Nim
|
|
export fn hal_surface_alloc(w: u32, h: u32) i32 {
|
|
return alloc(w, h) orelse -1;
|
|
}
|
|
|
|
export fn hal_surface_get_ptr(id: i32) ?[*]u32 {
|
|
if (get_surface(id)) |s| return s.ptr;
|
|
return null;
|
|
}
|