progress: ImGui Port - Desktop UI + ImGui rendering performance overhaul
Full ImGui desktop environment (desktop.pas): - Gradient wallpaper, taskbar with clock, start menu - Desktop icons with click-to-open - Windowed apps: System Info, Terminal, File Browser, Task Manager - Terminal dispatches to registered kernel commands with output capture Performance: Software rasterizer rewrite (imgui.pas, imgbridge.c) - Quad detection: merge consecutive triangle pairs into fast rect fills - 3 new fast-path rect fillers (solid/gradient/textured) using REP STOSD and 16.16 fixed-point integer inner loops - Triangle rasterizer rewritten with fixed-point edge functions - Back-buffer clear: DrawPixel loop -> REP STOSD (~200x faster) - Render stat debug counters added ISR-safe input buffering (imgbridge.c) - Keyboard/mouse events buffered in lock-free ring buffers from ISR context - Drained once per frame from main loop to prevent data races Other changes: - imguitypes.pas: InputTextFlags renumbered for cimgui 1.91+ - video.pas: backBufferLocation getter added - kernel.pas: VFS init moved earlier, main loop uses desktop_frame, mouse hook uses ISR-safe buffering - lmemorymanager.pas: kalloc/kfree exported with public aliases for C linkage - scheduler.pas: Root_Task moved to interface for desktop task manager - terminal.pas: freeParams exposed in interface
This commit is contained in:
1 parent
51a29244ed
commit
aac376fa22
13 files changed
+2362
-128
No files matched your search
@@ -838,6 +838,18 @@ const
|
||||
MAX_WINDOWS = 255; //< Maximum number of Windows open.
|
||||
DefaultWND = 0; //< The Window assigned for output when no Window is specified. (Default).
|
||||
|
||||
type
|
||||
TWNDCaptureCallback = procedure(s: pchar);
|
||||
|
||||
var
|
||||
WND_CaptureActive : boolean = false;
|
||||
WND_CaptureHWND : uint32 = 0;
|
||||
WND_CaptureBuf : array[0..511] of char;
|
||||
WND_CaptureBufIdx : uint32 = 0;
|
||||
WND_CaptureCallback : TWNDCaptureCallback = nil;
|
||||
|
||||
procedure flushCapture;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@@ -2259,6 +2271,7 @@ var
|
||||
x,y: Byte;
|
||||
|
||||
begin
|
||||
if WND_CaptureActive and (WND = WND_CaptureHWND) then exit;
|
||||
if WindowManager.Windows[WND] <> nil then begin
|
||||
for y:=0 to Console_Properties.MAX_CELL_Y do begin
|
||||
for x:=0 to Console_Properties.MAX_CELL_X do begin
|
||||
@@ -2419,8 +2432,26 @@ begin
|
||||
console.writeintlnexWND(i, Console_Properties.Default_Attribute, WND);
|
||||
end;
|
||||
|
||||
procedure flushCapture;
|
||||
begin
|
||||
if WND_CaptureActive and (WND_CaptureCallback <> nil) and (WND_CaptureBufIdx > 0) then begin
|
||||
WND_CaptureBuf[WND_CaptureBufIdx] := #0;
|
||||
WND_CaptureCallback(@WND_CaptureBuf[0]);
|
||||
WND_CaptureBufIdx := 0;
|
||||
WND_CaptureBuf[0] := #0;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure writecharexWND(character: char; attributes: uint32; WND : uint32);
|
||||
begin
|
||||
if WND_CaptureActive and (WND = WND_CaptureHWND) and (WND_CaptureCallback <> nil) then begin
|
||||
if WND_CaptureBufIdx < 511 then begin
|
||||
WND_CaptureBuf[WND_CaptureBufIdx] := character;
|
||||
inc(WND_CaptureBufIdx);
|
||||
WND_CaptureBuf[WND_CaptureBufIdx] := #0;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
if WindowManager.Windows[WND] <> nil then begin
|
||||
WindowManager.Windows[WND]^.Buffer[WindowManager.Windows[WND]^.Cursor.Y][WindowManager.Windows[WND]^.Cursor.X].Character:= character;
|
||||
WindowManager.Windows[WND]^.Buffer[WindowManager.Windows[WND]^.Cursor.Y][WindowManager.Windows[WND]^.Cursor.X].Attributes:= attributes;
|
||||
@@ -2603,6 +2634,13 @@ end;
|
||||
|
||||
procedure backspaceWND(WND : uint32);
|
||||
begin
|
||||
if WND_CaptureActive and (WND = WND_CaptureHWND) then begin
|
||||
if WND_CaptureBufIdx > 0 then begin
|
||||
dec(WND_CaptureBufIdx);
|
||||
WND_CaptureBuf[WND_CaptureBufIdx] := #0;
|
||||
end;
|
||||
exit;
|
||||
end;
|
||||
if WindowManager.Windows[WND] <> nil then begin
|
||||
Dec(WindowManager.Windows[WND]^.Cursor.X);
|
||||
writecharWND(' ', WND);
|
||||
@@ -2659,6 +2697,13 @@ end;
|
||||
|
||||
procedure _safeincrement_y_WND(WND : uint32);
|
||||
begin
|
||||
if WND_CaptureActive and (WND = WND_CaptureHWND) and (WND_CaptureCallback <> nil) then begin
|
||||
WND_CaptureBuf[WND_CaptureBufIdx] := #0;
|
||||
WND_CaptureCallback(@WND_CaptureBuf[0]);
|
||||
WND_CaptureBufIdx := 0;
|
||||
WND_CaptureBuf[0] := #0;
|
||||
exit;
|
||||
end;
|
||||
if WindowManager.Windows[WND] <> nil then begin
|
||||
WindowManager.Windows[WND]^.Cursor.Y:= WindowManager.Windows[WND]^.Cursor.Y+1;
|
||||
if WindowManager.Windows[WND]^.Cursor.Y > WindowManager.Windows[WND]^.WND_H-1 then begin
|
||||
|
||||
@@ -92,6 +92,7 @@ var
|
||||
Root : PVFSObject;
|
||||
CurrentDirectory : pchar = nil;
|
||||
PushPopDirectory : PLinkedListBase;
|
||||
MountDepth : uint32 = 0;
|
||||
|
||||
procedure init();
|
||||
Function OpenFile(Filename : pchar; OpenMode : TOpenMode; WriteMode : TWriteMode; Lock : Boolean; Error : PError) : TFileHandle;
|
||||
@@ -104,6 +105,7 @@ function GetDirectories(Handle : uint32; Path : pchar) : PHashMap;
|
||||
function PathValid(Path : pchar) : TIsPathValid;
|
||||
function changeDirectory(Path : pchar) : TIsPathValid;
|
||||
function getWorkingDirectory : pchar;
|
||||
function GetDirectoryListing(Path : pchar) : PHashMap;
|
||||
|
||||
//VFS Functions
|
||||
function newVirtualDirectory(Path : pchar) : TError;
|
||||
@@ -288,6 +290,7 @@ begin
|
||||
NewObj:= PVFSObject(hashmap.get(ht, item));
|
||||
if NewObj = nil then begin
|
||||
GetObjectFromPath:= nil;
|
||||
STRLL_Free(SplitPath);
|
||||
tracer.push_trace('vfs.GetObjectFromPath.shortexit_1');
|
||||
exit;
|
||||
end;
|
||||
@@ -304,6 +307,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
GetObjectFromPath:= Obj;
|
||||
STRLL_Free(SplitPath);
|
||||
tracer.push_trace('vfs.GetObjectFromPath.exit');
|
||||
end;
|
||||
|
||||
@@ -348,7 +352,17 @@ begin
|
||||
GetDirectoryListing:= nil;
|
||||
end;
|
||||
otMOUNT:begin
|
||||
{ Safety: cap mount-follow depth to prevent infinite recursion
|
||||
from circular mounts. Use a simple static counter. }
|
||||
if MountDepth < 16 then begin
|
||||
Inc(MountDepth);
|
||||
GetDirectoryListing:= GetDirectoryListing(PVFSMount(Obj^.Reference)^.Path);
|
||||
Dec(MountDepth);
|
||||
end else
|
||||
GetDirectoryListing:= nil;
|
||||
end;
|
||||
else begin
|
||||
GetDirectoryListing:= nil;
|
||||
end;
|
||||
end;
|
||||
end else begin
|
||||
@@ -420,7 +434,7 @@ begin
|
||||
|
||||
NewObj^.Reference:= void(NewDev);
|
||||
|
||||
hashmap.add(ht, stringCopy(DeviceName), void(NewDev));
|
||||
hashmap.add(ht, stringCopy(DeviceName), void(NewObj));
|
||||
end;
|
||||
|
||||
{ Filesystem Functions }
|
||||
|
||||
@@ -54,13 +54,8 @@ end;
|
||||
|
||||
procedure Flush(FrontBuffer : PVideoBuffer; BackBuffer : PVideoBuffer);
|
||||
var
|
||||
idx : uint32;
|
||||
Back,Front : uint32;
|
||||
BufferSize : uint32;
|
||||
|
||||
const
|
||||
//COPY_WIDTH = 64; //Use this for 64bit copies
|
||||
COPY_WIDTH = 128; //Use this for SSE copies
|
||||
Count64 : uint32;
|
||||
|
||||
begin
|
||||
//tracer.push_trace('doublebuffer.Flush.enter');
|
||||
@@ -68,11 +63,32 @@ begin
|
||||
if ((FrontBuffer^.Width > BackBuffer^.Width) or (FrontBuffer^.Height > BackBuffer^.Height)) then exit;
|
||||
Back:= BackBuffer^.Location;
|
||||
Front:= FrontBuffer^.Location;
|
||||
BufferSize:= ( ( BackBuffer^.Width * BackBuffer^.Height * BackBuffer^.BitsPerPixel) div COPY_WIDTH ) - 1;
|
||||
for idx:=0 to BufferSize do begin
|
||||
//Front[idx]:= Back[idx];
|
||||
// -- TODO: Get SSE working here for 128bit copies --
|
||||
__SSE_128_memcpy(Back + (idx * 16), Front + (idx * 16));
|
||||
{ Number of 64-byte blocks: total_bytes / 64 = (W * H * BPP/8) / 64 }
|
||||
Count64:= ( BackBuffer^.Width * BackBuffer^.Height * BackBuffer^.BitsPerPixel) div 512;
|
||||
if Count64 = 0 then exit;
|
||||
{ Bulk SSE copy: 4 x MOVAPS (64 bytes) per iteration.
|
||||
4x fewer loop iterations than the old per-16-byte function-call loop. }
|
||||
asm
|
||||
PUSH ESI
|
||||
PUSH EDI
|
||||
MOV ESI, Back
|
||||
MOV EDI, Front
|
||||
MOV ECX, Count64
|
||||
@sseloop:
|
||||
MOVAPS XMM0, [ESI]
|
||||
MOVAPS XMM1, [ESI + 16]
|
||||
MOVAPS XMM2, [ESI + 32]
|
||||
MOVAPS XMM3, [ESI + 48]
|
||||
MOVAPS [EDI], XMM0
|
||||
MOVAPS [EDI + 16], XMM1
|
||||
MOVAPS [EDI + 32], XMM2
|
||||
MOVAPS [EDI + 48], XMM3
|
||||
ADD ESI, 64
|
||||
ADD EDI, 64
|
||||
DEC ECX
|
||||
JNZ @sseloop
|
||||
POP EDI
|
||||
POP ESI
|
||||
end;
|
||||
//tracer.push_trace('doublebuffer.Flush.exit');
|
||||
end;
|
||||
|
||||
@@ -125,9 +125,11 @@ char* strcpy(char* dst, const char* src) {
|
||||
}
|
||||
|
||||
char* strncpy(char* dst, const char* src, size_t n) {
|
||||
char* d = dst;
|
||||
while (n-- && (*d++ = *src++));
|
||||
while (n--) *d++ = '\0';
|
||||
size_t i;
|
||||
for (i = 0; i < n && src[i] != '\0'; i++)
|
||||
dst[i] = src[i];
|
||||
for (; i < n; i++)
|
||||
dst[i] = '\0';
|
||||
return dst;
|
||||
}
|
||||
|
||||
@@ -150,8 +152,8 @@ int strcmp(const char* a, const char* b) {
|
||||
}
|
||||
|
||||
int strncmp(const char* a, const char* b, size_t n) {
|
||||
while (n-- && *a && (*a == *b)) { a++; b++; }
|
||||
if (!n) return 0;
|
||||
while (--n && *a && (*a == *b)) { a++; b++; }
|
||||
return (unsigned char)*a - (unsigned char)*b;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -137,27 +137,33 @@ const
|
||||
============================================================ }
|
||||
const
|
||||
ImGuiInputTextFlags_None = 0;
|
||||
{ Character filters }
|
||||
ImGuiInputTextFlags_CharsDecimal = 1 SHL 0;
|
||||
ImGuiInputTextFlags_CharsHexadecimal = 1 SHL 1;
|
||||
ImGuiInputTextFlags_CharsUppercase = 1 SHL 2;
|
||||
ImGuiInputTextFlags_CharsNoBlank = 1 SHL 3;
|
||||
ImGuiInputTextFlags_AutoSelectAll = 1 SHL 4;
|
||||
ImGuiInputTextFlags_EnterReturnsTrue = 1 SHL 5;
|
||||
ImGuiInputTextFlags_CallbackCompletion = 1 SHL 6;
|
||||
ImGuiInputTextFlags_CallbackHistory = 1 SHL 7;
|
||||
ImGuiInputTextFlags_CallbackAlways = 1 SHL 8;
|
||||
ImGuiInputTextFlags_CallbackCharFilter = 1 SHL 9;
|
||||
ImGuiInputTextFlags_AllowTabInput = 1 SHL 10;
|
||||
ImGuiInputTextFlags_CtrlEnterForNewLine = 1 SHL 11;
|
||||
ImGuiInputTextFlags_NoHorizontalScroll = 1 SHL 12;
|
||||
ImGuiInputTextFlags_AlwaysOverwrite = 1 SHL 13;
|
||||
ImGuiInputTextFlags_ReadOnly = 1 SHL 14;
|
||||
ImGuiInputTextFlags_Password = 1 SHL 15;
|
||||
ImGuiInputTextFlags_CharsScientific = 1 SHL 2;
|
||||
ImGuiInputTextFlags_CharsUppercase = 1 SHL 3;
|
||||
ImGuiInputTextFlags_CharsNoBlank = 1 SHL 4;
|
||||
{ Inputs }
|
||||
ImGuiInputTextFlags_AllowTabInput = 1 SHL 5;
|
||||
ImGuiInputTextFlags_EnterReturnsTrue = 1 SHL 6;
|
||||
ImGuiInputTextFlags_EscapeClearsAll = 1 SHL 7;
|
||||
ImGuiInputTextFlags_CtrlEnterForNewLine = 1 SHL 8;
|
||||
{ Other options }
|
||||
ImGuiInputTextFlags_ReadOnly = 1 SHL 9;
|
||||
ImGuiInputTextFlags_Password = 1 SHL 10;
|
||||
ImGuiInputTextFlags_AlwaysOverwrite = 1 SHL 11;
|
||||
ImGuiInputTextFlags_AutoSelectAll = 1 SHL 12;
|
||||
ImGuiInputTextFlags_ParseEmptyRefVal = 1 SHL 13;
|
||||
ImGuiInputTextFlags_DisplayEmptyRefVal = 1 SHL 14;
|
||||
ImGuiInputTextFlags_NoHorizontalScroll = 1 SHL 15;
|
||||
ImGuiInputTextFlags_NoUndoRedo = 1 SHL 16;
|
||||
ImGuiInputTextFlags_CharsScientific = 1 SHL 17;
|
||||
ImGuiInputTextFlags_CallbackResize = 1 SHL 18;
|
||||
ImGuiInputTextFlags_CallbackEdit = 1 SHL 19;
|
||||
ImGuiInputTextFlags_EscapeClearsAll = 1 SHL 20;
|
||||
{ Callback features }
|
||||
ImGuiInputTextFlags_CallbackCompletion = 1 SHL 17;
|
||||
ImGuiInputTextFlags_CallbackHistory = 1 SHL 18;
|
||||
ImGuiInputTextFlags_CallbackAlways = 1 SHL 19;
|
||||
ImGuiInputTextFlags_CallbackCharFilter = 1 SHL 20;
|
||||
ImGuiInputTextFlags_CallbackResize = 1 SHL 21;
|
||||
ImGuiInputTextFlags_CallbackEdit = 1 SHL 22;
|
||||
|
||||
{ ============================================================
|
||||
ImGuiTreeNodeFlags
|
||||
|
||||
@@ -40,6 +40,7 @@ function frontBufferBpp : uint8;
|
||||
function backBufferWidth : uint32;
|
||||
function backBufferHeight : uint32;
|
||||
function backBufferBpp : uint8;
|
||||
function backBufferLocation : uint32;
|
||||
|
||||
Procedure basicFDrawTexture(Buffer : PVideoBuffer; X : uint32; Y : uint32; Texture : PTexture);
|
||||
|
||||
@@ -315,4 +316,9 @@ begin
|
||||
backBufferBpp:= VideoInterface.BackBuffer.BitsPerPixel;
|
||||
end;
|
||||
|
||||
function backBufferLocation : uint32;
|
||||
begin
|
||||
backBufferLocation:= VideoInterface.BackBuffer.Location;
|
||||
end;
|
||||
|
||||
end.
|
||||
+22
-8
@@ -57,7 +57,7 @@ uses
|
||||
terminal,
|
||||
hashmap, vfs,
|
||||
video, vesa, doublebuffer, color,
|
||||
imgui, imguitypes;
|
||||
imgui, imguitypes, desktop;
|
||||
|
||||
procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall;
|
||||
|
||||
@@ -122,11 +122,16 @@ begin
|
||||
end;
|
||||
|
||||
procedure imgui_mouse_hook(x, y: sint32; lmb, rmb, mmb: boolean);
|
||||
var
|
||||
fx, fy: Single;
|
||||
begin
|
||||
imgui_feed_mouse_pos(Single(x), Single(y));
|
||||
imgui_feed_mouse_button(0, lmb);
|
||||
imgui_feed_mouse_button(1, rmb);
|
||||
imgui_feed_mouse_button(2, mmb);
|
||||
{ Buffer mouse events — will be drained before next frame }
|
||||
fx := x;
|
||||
fy := y;
|
||||
imgui_handle_mouse_pos(fx, fy);
|
||||
imgui_handle_mouse_button(0, sint32(lmb));
|
||||
imgui_handle_mouse_button(1, sint32(rmb));
|
||||
imgui_handle_mouse_button(2, sint32(mmb));
|
||||
end;
|
||||
|
||||
procedure kmain(mbinfo: Pmultiboot_info_t; mbmagic: uint32); stdcall; [public, alias: 'kmain'];
|
||||
@@ -235,6 +240,9 @@ begin
|
||||
{ Call Tracer }
|
||||
tracer.init();
|
||||
|
||||
{ Virtual File System }
|
||||
vfs.init();
|
||||
|
||||
video.init();
|
||||
vesa.init(@video.register);
|
||||
doublebuffer.init(@video.register);
|
||||
@@ -282,6 +290,11 @@ begin
|
||||
imgui_init(video.frontBufferWidth, video.frontBufferHeight);
|
||||
console.outputln('KERNEL', 'ImGui: INIT END.');
|
||||
|
||||
{ Initialize desktop }
|
||||
console.outputln('KERNEL', 'Desktop: INIT BEGIN.');
|
||||
desktop_init;
|
||||
console.outputln('KERNEL', 'Desktop: INIT END.');
|
||||
|
||||
{ Initialize input drivers }
|
||||
console.outputln('KERNEL', 'Input: INIT BEGIN.');
|
||||
keyboard.init(keyboard_layout);
|
||||
@@ -302,10 +315,10 @@ begin
|
||||
|
||||
{ Warm-up frames: ImGui needs 2+ frames for window layout }
|
||||
imgui_new_frame;
|
||||
imgui_test_window;
|
||||
desktop_frame;
|
||||
imgui_render;
|
||||
imgui_new_frame;
|
||||
imgui_test_window;
|
||||
desktop_frame;
|
||||
imgui_render;
|
||||
|
||||
{ Main interactive render loop }
|
||||
@@ -321,8 +334,9 @@ begin
|
||||
else
|
||||
imgui_feed_delta_time(Single(0.001));
|
||||
|
||||
imgui_process_input;
|
||||
imgui_new_frame;
|
||||
imgui_test_window;
|
||||
desktop_frame;
|
||||
imgui_render;
|
||||
end;
|
||||
|
||||
|
||||
@@ -170,7 +170,7 @@ begin
|
||||
klalloc:= Address;
|
||||
end;
|
||||
|
||||
function kalloc(size : uint32) : void;
|
||||
function kalloc(size : uint32) : void; [public, alias: 'kernel_kalloc'];
|
||||
var
|
||||
Heap_Entries : uint32;
|
||||
i, j : uint32;
|
||||
@@ -217,7 +217,7 @@ begin
|
||||
//pop_trace;
|
||||
end;
|
||||
|
||||
procedure kfree(area : void);
|
||||
procedure kfree(area : void); [public, alias: 'kernel_kfree'];
|
||||
var
|
||||
hp : PHeapPage;
|
||||
entry : uint32;
|
||||
|
||||
@@ -72,6 +72,7 @@ procedure registerCommandEx(command : pchar; method : TCommandMethod; descriptio
|
||||
function getParams(buf : TCommandBuffer) : PParamList;
|
||||
function paramCount(params : PParamList) : uint32;
|
||||
function getParam(index : uint32; params : PParamList) : pchar;
|
||||
procedure freeParams(params : PParamList);
|
||||
procedure setWorkingDirectory(str : pchar);
|
||||
function getWorkingDirectory : pchar;
|
||||
function getTerminalHWND : uint32;
|
||||
|
||||
+1
-1
@@ -45,6 +45,7 @@ type
|
||||
|
||||
var
|
||||
Active : Boolean;
|
||||
Root_Task : PScheduler_Entry;
|
||||
|
||||
procedure init;
|
||||
procedure add_task(priority : uint8);
|
||||
@@ -53,7 +54,6 @@ implementation
|
||||
|
||||
var
|
||||
Tick : uint32;
|
||||
Root_Task : PScheduler_Entry = nil;
|
||||
Current_Task : PScheduler_Entry = nil;
|
||||
|
||||
procedure context_switch();
|
||||
|
||||
Reference in new issue
Block a user