From 075c87d52a4d90c0f00f8ba7ba849677771a9be3 Mon Sep 17 00:00:00 2001 From: salmonik Date: Fri, 31 Jul 2026 18:08:45 +0200 Subject: vt: defer scrolls and batch framebuffer pushes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Streaming output scrolled one framebuffer push per line (each a ~3-8 MB write-only copy). The vt now scrolls the logical grid instantly in RAM and defers the display shift: N pending scrolls are pushed together as one shift_up_n — one push regardless of batch size. - vt: PENDING_SCROLLS counter; scroll_up shifts CELLS only; flush renders nothing while pending (the diff would otherwise re-rasterise the whole screen per line); sync_scroll() does one gop::shift_up_n + RENDERED mirror + normal diff flush (which re-blits just the newly exposed rows and the cursor). - Sync triggers: batch of 16 rows, ~40 ms of stream pause (100 Hz TICKS), any CSI sequence (full-screen apps like the editor render immediately), clear_all/set_cursor_visible, interactive input (tty read_line/read_byte), and the shell before each prompt. - gop: shift_up → shift_up_n(n) (one shadow memcpy + one push). Verified in QEMU: mmap/hexdump streaming renders in coherent batches with the prompt syncing at the end; clear wipes clean; the editor scrolls and redraws immediately (45-line file, gutter + status bar intact, cursor correct); save/exit/cat round-trip unchanged. Release and dev builds pass. --- CONTEXT.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'CONTEXT.md') diff --git a/CONTEXT.md b/CONTEXT.md index 32a6eca..8fa4025 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -163,14 +163,22 @@ Single Rust crate (`x86_64-unknown-uefi` target). Module breakdown: ## Known issues / perf notes - **Scroll cost** — scrolling still shifts the whole framebuffer (a - ~3-8 MB pixel copy per row), but a RAM backbuffer (`gop::SHADOW`) - makes it fast on real hardware: every raster write goes to the shadow - too, and scrolling is a cached shadow memcpy + one write-only push to - the display. The display is never *read* — that was the killer, since - real-hardware GOP framebuffers are uncacheable/write-combining and - uncached reads cost a bus round-trip per cache line. Still on the - someday list: a pan-based ring so scrolling never touches the whole - framebuffer at all. + ~3-8 MB pixel copy per row), but two mechanisms make it fast on real + hardware: + 1. a RAM backbuffer (`gop::SHADOW`): every raster write goes to the + shadow too; scrolling is a cached shadow memcpy + one write-only + push to the display — the display is never *read* (uncached reads + were the killer, since real-hardware GOP framebuffers are + uncacheable/write-combining). + 2. deferred scroll batching (`vt::PENDING_SCROLLS`): the logical grid + scrolls instantly in RAM while the framebuffer shift+push is + deferred; N pending scrolls cost one push. Bursts of streaming + output (hexdump/cat) push every ~16 rows (or after ~40 ms of + pause), and the shell syncs before each prompt. Any CSI sequence + (full-screen apps like the editor) or interactive input pushes + immediately. + Still on the someday list: a pan-based ring so scrolling never touches + the whole framebuffer at all. - **Editor redraw** re-blits changed cells per keystroke (fine at 1280×800); the "optimize drawing someday" item. - **ramfs only**: edited files live in memory, lost on reboot until disk -- cgit v1.2.3