prometeu-runtime/discussion/lessons/DSC-0010-perf-host-desktop-frame-pacing-and-presentation/LSN-0036-frame-publication-and-host-invalidation-must-be-separate.md
bQUARKz c78f091efe
All checks were successful
Intrepid/Prometeu/Runtime/pipeline/head This commit looks good
Intrepid/Prometeu/Runtime/pipeline/pr-master This commit looks good
[PERF] Host Desktop Frame Pacing and Presentation
2026-04-20 11:12:32 +01:00

3.5 KiB

id ticket title created tags
LSN-0036 perf-host-desktop-frame-pacing-and-presentation Frame Publication and Host Invalidation Must Be Separate 2026-04-20
performance
host
desktop
presentation
frame-pacing
debug

Frame Publication and Host Invalidation Must Be Separate

Context

The desktop host was waking aggressively with ControlFlow::Poll, requesting redraw continuously, and converting the full RGB565 framebuffer to RGBA8 on every redraw even when the machine had not published a new logical frame.

That design hid real presentation cost, wasted CPU on stable screens, and blurred an important boundary: the runtime owns logical frame production, while the host owns window invalidation, overlays, and debugger presentation.

Key Decisions

Published logical frames are the canonical machine-side redraw trigger

What: The host presentation loop now treats "a new logical frame was published" as the primary reason to redraw the machine image.

Why: PROMETEU portability and timing depend on logical frames, not on a host polling loop. If the host redraws just to discover whether a frame changed, presentation cost stops reflecting actual machine behavior.

Trade-offs: This requires an explicit or at least stable host-side way to observe frame publication. The extra state tracking is worth it because it keeps redraw policy honest and testable.

Host-only invalidation is a separate redraw cause

What: Resize, expose, overlay toggle, and debugger-visible transitions remain valid redraw causes, but they are treated as host-owned invalidation rather than machine frame production.

Why: The host still has to repair or recomposite its visible surface when the OS window changes or a technical HUD becomes visible. That need is real, but it must not be confused with "the machine emitted another frame."

Trade-offs: The host needs separate invalidation bookkeeping. In return, paused or stable machine state no longer forces continuous framebuffer conversion.

Patterns and Algorithms

  • Use two independent signals in presentation code:
    • latest published logical frame;
    • host-owned surface invalidation.
  • Request redraw only when one of those signals changes and only once per pending update.
  • After presentation completes, mark the current logical frame as presented and clear host invalidation.
  • When the machine is running, wait until the next logical deadline instead of spinning continuously.
  • When the machine is paused or waiting for debugger start, allow low-frequency host wakeups or OS events, but keep the last valid image until a real invalidation occurs.

Pitfalls

  • Do not use redraw polling as a substitute for a missing publication signal. That only hides the architectural gap.
  • Do not let host overlays imply extra logical frame production. Host HUDs may change the visible surface without changing machine state.
  • Do not promote host-only invalidation into guest-visible ABI. The runtime-host handshake may need internal state, but the cartridge contract does not.
  • Do not reopen render-backend architecture just to fix pacing. Dirty regions or GPU offload are separate optimization questions.

Takeaways

  • A stable screen is a first-class state and should not cost continuous presentation work.
  • Frame production and host invalidation are different events and should remain different in code.
  • Event-driven redraw policy is easier to test, cheaper to run, and more faithful to the machine contract than polling-driven presentation.