using System.Runtime.InteropServices;
using XFESystem.Branding;
namespace XFESystem.NativeKernel;
/// <summary>A native scheduler worker owns scanout until the application's first complete frame is ready.</summary>
public static unsafe class BootSplash
{
// Zero deliberately omits IsVolatile. Explicit unmanaged memory barriers
// make each scheduler boundary reload these single-BSP handoff flags.
private static bool _active, _ready, _finished, _failed;
private static ulong _started, _frames;
private static uint* _backbuffer;
private static ulong _bufferBytes;
public static bool Active => _active;
public static bool Start()
{
if (!Framebuffer.Ready || !Threads.Ready || !MonotonicClock.Ready || _active) return false;
_bufferBytes = ((ulong)Framebuffer.Width * Framebuffer.Height * 4 + 4095) & ~4095UL;
ulong flags = Native.IrqSave();
_backbuffer = (uint*)VirtualMemory.Reserve(_bufferBytes, 4096);
bool allocated = _backbuffer != null && VirtualMemory.Commit((ulong)_backbuffer, _bufferBytes);
if (!allocated && _backbuffer != null) VirtualMemory.Release((ulong)_backbuffer, _bufferBytes);
Native.IrqRestore(flags);
if (!allocated) { _backbuffer = null; return false; }
for (ulong i = 0; i < (ulong)Framebuffer.Width * Framebuffer.Height; i++) _backbuffer[i] = 0;
_ready = _finished = _failed = false; _frames = 0;
_started = MonotonicClock.Nanoseconds(); _active = true;
Serial.Line("XFE_BOOT_VISUAL_START|IntroMs|2400|Text|XFESystem|NativeWorker|1");
if (Threads.Create(&Run, null, 65536, 0, false) != 0) return true;
ReleaseBuffer(); _active = false; return false;
}
[UnmanagedCallersOnly(EntryPoint = "xfe_boot_visual_worker")]
public static uint Run(void* argument)
{
bool introReported = false, waitingReported = false;
for (;;)
{
Native.MemoryBarrier();
if (_failed) break;
ulong elapsed = (MonotonicClock.Nanoseconds() - _started) / 1000000;
if (elapsed >= BootVisual.IntroMilliseconds && !introReported)
{ introReported = true; Serial.Line("XFE_BOOT_VISUAL_INTRO_COMPLETE"); }
if (BootVisual.ShouldRelease(elapsed, _ready))
{
Serial.Write("XFE_BOOT_VISUAL_RELEASED|ElapsedMs|"); Serial.Number(elapsed);
Serial.Write("|Frames|"); Serial.Number(_frames);
Serial.Write("|LoadingShown|"); Serial.Number(waitingReported ? 1UL : 0UL); Serial.Line("");
_active = false; ReleaseBuffer(); Native.MemoryBarrier(); _finished = true;
return 0;
}
bool waiting = BootVisual.IsWaiting(elapsed, _ready);
if (waiting && !waitingReported)
{ waitingReported = true; Serial.Line("XFE_BOOT_VISUAL_WAITING"); }
Framebuffer.PaintBoot(_backbuffer, elapsed, waiting);
_frames++;
Threads.Sleep(16);
}
_active = false; ReleaseBuffer(); _finished = true;
return 1;
}
[UnmanagedCallersOnly(EntryPoint = "xfe_runtime_boot_complete")]
public static int Complete()
{
if (!_active && !_finished || _failed) return 0;
Serial.Line("XFE_BOOT_VISUAL_APPLICATION_FRAME_READY");
_ready = true; Native.MemoryBarrier();
// Main has already prepared its first frame. The boot worker finishes
// the intro or stops its loader before this caller can touch scanout.
for (;;)
{
Native.MemoryBarrier();
if (_finished || _failed) break;
Threads.Sleep(1);
}
return _failed ? 0 : 1;
}
public static void Blackout()
{
_failed = true;
Framebuffer.Fill(0);
Native.MemoryBarrier();
}
private static void ReleaseBuffer()
{
ulong flags = Native.IrqSave();
if (_backbuffer != null) VirtualMemory.Release((ulong)_backbuffer, _bufferBytes);
_backbuffer = null; _bufferBytes = 0;
Native.IrqRestore(flags);
}
}
using System.Runtime.InteropServices;
using XFESystem.Branding;
namespace XFESystem.NativeKernel;
/// <summary>A native scheduler worker owns scanout until the application's first complete frame is ready.</summary>
public static unsafe class BootSplash
{
// Zero deliberately omits IsVolatile. Explicit unmanaged memory barriers
// make each scheduler boundary reload these single-BSP handoff flags.
private static bool _active, _ready, _finished, _failed;
private static ulong _started, _frames;
private static uint* _backbuffer;
private static ulong _bufferBytes;
public static bool Active => _active;
public static bool Start()
{
if (!Framebuffer.Ready || !Threads.Ready || !MonotonicClock.Ready || _active) return false;
_bufferBytes = ((ulong)Framebuffer.Width * Framebuffer.Height * 4 + 4095) & ~4095UL;
ulong flags = Native.IrqSave();
_backbuffer = (uint*)VirtualMemory.Reserve(_bufferBytes, 4096);
bool allocated = _backbuffer != null && VirtualMemory.Commit((ulong)_backbuffer, _bufferBytes);
if (!allocated && _backbuffer != null) VirtualMemory.Release((ulong)_backbuffer, _bufferBytes);
Native.IrqRestore(flags);
if (!allocated) { _backbuffer = null; return false; }
for (ulong i = 0; i < (ulong)Framebuffer.Width * Framebuffer.Height; i++) _backbuffer[i] = 0;
_ready = _finished = _failed = false; _frames = 0;
_started = MonotonicClock.Nanoseconds(); _active = true;
Serial.Line("XFE_BOOT_VISUAL_START|IntroMs|2400|Text|XFESystem|NativeWorker|1");
if (Threads.Create(&Run, null, 65536, 0, false) != 0) return true;
ReleaseBuffer(); _active = false; return false;
}
[UnmanagedCallersOnly(EntryPoint = "xfe_boot_visual_worker")]
public static uint Run(void* argument)
{
bool introReported = false, waitingReported = false;
for (;;)
{
Native.MemoryBarrier();
if (_failed) break;
ulong elapsed = (MonotonicClock.Nanoseconds() - _started) / 1000000;
if (elapsed >= BootVisual.IntroMilliseconds && !introReported)
{ introReported = true; Serial.Line("XFE_BOOT_VISUAL_INTRO_COMPLETE"); }
if (BootVisual.ShouldRelease(elapsed, _ready))
{
Serial.Write("XFE_BOOT_VISUAL_RELEASED|ElapsedMs|"); Serial.Number(elapsed);
Serial.Write("|Frames|"); Serial.Number(_frames);
Serial.Write("|LoadingShown|"); Serial.Number(waitingReported ? 1UL : 0UL); Serial.Line("");
_active = false; ReleaseBuffer(); Native.MemoryBarrier(); _finished = true;
return 0;
}
bool waiting = BootVisual.IsWaiting(elapsed, _ready);
if (waiting && !waitingReported)
{ waitingReported = true; Serial.Line("XFE_BOOT_VISUAL_WAITING"); }
Framebuffer.PaintBoot(_backbuffer, elapsed, waiting);
_frames++;
Threads.Sleep(16);
}
_active = false; ReleaseBuffer(); _finished = true;
return 1;
}
[UnmanagedCallersOnly(EntryPoint = "xfe_runtime_boot_complete")]
public static int Complete()
{
if (!_active && !_finished || _failed) return 0;
Serial.Line("XFE_BOOT_VISUAL_APPLICATION_FRAME_READY");
_ready = true; Native.MemoryBarrier();
// Main has already prepared its first frame. The boot worker finishes
// the intro or stops its loader before this caller can touch scanout.
for (;;)
{
Native.MemoryBarrier();
if (_finished || _failed) break;
Threads.Sleep(1);
}
return _failed ? 0 : 1;
}
public static void Blackout()
{
_failed = true;
Framebuffer.Fill(0);
Native.MemoryBarrier();
}
private static void ReleaseBuffer()
{
ulong flags = Native.IrqSave();
if (_backbuffer != null) VirtualMemory.Release((ulong)_backbuffer, _bufferBytes);
_backbuffer = null; _bufferBytes = 0;
Native.IrqRestore(flags);
}
}