From 74bc1ce1f0d3783578e89030955319c403db6e72 Mon Sep 17 00:00:00 2001 From: salmonik Date: Fri, 31 Jul 2026 17:55:52 +0200 Subject: gop: RAM backbuffer — scrolling never reads the framebuffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Real-hardware GOP framebuffers are typically uncacheable or write-combining (firmware MTRR/PAT), so the scroll shift's full-screen memcpy *read* ~4-8 MB through uncached memory — a bus round-trip per cache line. That made scroll printing crawl on real hardware while plain printing (a few glyph writes) stayed instant. - gop keeps a RAM shadow copy of the whole framebuffer (same pitch layout), allocated at init. - Every raster write (glyph blits, clear) goes to both the display and the shadow. - shift_up becomes: cached shadow memcpy up one row + clear exposed bottom row in the shadow + one write-only push shadow→display via copy_nonoverlapping (64-byte bursts that coalesce on WC memory) — the display is never read. - Fallback to the old direct shift if the shadow allocation is null. Verified in QEMU: mmap output scrolls ~100 lines with coherent rows and a clean bottom row, clear wipes the screen, cursor tracks the prompt, editor paths untouched. Release + dev builds pass. --- CONTEXT.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'CONTEXT.md') diff --git a/CONTEXT.md b/CONTEXT.md index a1ef4bb..32a6eca 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -162,11 +162,15 @@ Single Rust crate (`x86_64-unknown-uefi` target). Module breakdown: ## Known issues / perf notes -- **Scroll is slow under QEMU without KVM**: each scroll shifts the whole - framebuffer up (~3 MB copy at 1280×800) with TCG-emulated stores. - Deferred optimisation: ring-buffer rows / deferred pan so scrolling - never touches the whole framebuffer. The vt's cell grid already avoids - re-rasterising on scroll (only the exposed bottom row is blitted). +- **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. - **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