From 64b3962c5945014411cc70112b8e12ec6e97ce04 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Mon, 2 Mar 2026 17:02:01 -0600 Subject: [PATCH] Add render throttle to decouple parse throughput from GDI overhead During bulk serial data flow, renders are capped at ~20fps (50ms interval) so the ANSI parser can run at full speed without blocking on FlipToScreen. When idle, renders immediately for interactive responsiveness. Co-Authored-By: Claude Opus 4.6 --- delphi/TESTMAIN.PAS | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/delphi/TESTMAIN.PAS b/delphi/TESTMAIN.PAS index 1f35e13..65e6ecb 100644 --- a/delphi/TESTMAIN.PAS +++ b/delphi/TESTMAIN.PAS @@ -165,13 +165,18 @@ end; procedure TMainForm.Run; +const + RenderMs = 50; { Minimum ms between renders during bulk flow (20 fps) } var - Msg: TMsg; - S: string; - HasData: Boolean; + Msg: TMsg; + S: string; + HasData: Boolean; + Now: Longint; + LastRenderTick: Longint; begin Show; - FDone := False; + FDone := False; + LastRenderTick := GetTickCount; while not FDone do begin { Process all pending Windows messages (keyboard, paint, scrollbar) } @@ -218,9 +223,16 @@ begin if FDone then Break; - { Tick blink (dirties rows if interval elapsed), then render } - FAnsi.TickBlink; - FAnsi.FlipToScreen; + { Render throttle: during bulk data flow, only render every RenderMs } + { to decouple parse throughput from GDI overhead. When idle, render } + { immediately for interactive responsiveness. } + Now := GetTickCount; + if (not HasData) or (Now - LastRenderTick >= RenderMs) then + begin + FAnsi.TickBlink; + FAnsi.FlipToScreen; + LastRenderTick := Now; + end; { Yield CPU to other apps when no serial data is flowing. } { PM_NOYIELD keeps message draining fast; Yield here gives other }