diff options
| author | salmonik <salmonik@tuta.io> | 2026-07-31 17:55:52 +0200 |
|---|---|---|
| committer | salmonik <salmonik@tuta.io> | 2026-07-31 17:55:52 +0200 |
| commit | 74bc1ce1f0d3783578e89030955319c403db6e72 (patch) | |
| tree | 96ff3988879fad175a51ab035755649fb3c93832 /CONTEXT.md | |
| parent | vt: don't strand stale inverse cursor cells on scroll/clear (diff) | |
| download | rs-dos-74bc1ce1f0d3783578e89030955319c403db6e72.tar.gz rs-dos-74bc1ce1f0d3783578e89030955319c403db6e72.zip | |
gop: RAM backbuffer — scrolling never reads the framebuffer
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.
Diffstat (limited to '')
| -rw-r--r-- | CONTEXT.md | 14 |
1 files changed, 9 insertions, 5 deletions
| @@ -162,11 +162,15 @@ Single Rust crate (`x86_64-unknown-uefi` target). Module breakdown: | |||
| 162 | 162 | ||
| 163 | ## Known issues / perf notes | 163 | ## Known issues / perf notes |
| 164 | 164 | ||
| 165 | - **Scroll is slow under QEMU without KVM**: each scroll shifts the whole | 165 | - **Scroll cost** — scrolling still shifts the whole framebuffer (a |
| 166 | framebuffer up (~3 MB copy at 1280×800) with TCG-emulated stores. | 166 | ~3-8 MB pixel copy per row), but a RAM backbuffer (`gop::SHADOW`) |
| 167 | Deferred optimisation: ring-buffer rows / deferred pan so scrolling | 167 | makes it fast on real hardware: every raster write goes to the shadow |
| 168 | never touches the whole framebuffer. The vt's cell grid already avoids | 168 | too, and scrolling is a cached shadow memcpy + one write-only push to |
| 169 | re-rasterising on scroll (only the exposed bottom row is blitted). | 169 | the display. The display is never *read* — that was the killer, since |
| 170 | real-hardware GOP framebuffers are uncacheable/write-combining and | ||
| 171 | uncached reads cost a bus round-trip per cache line. Still on the | ||
| 172 | someday list: a pan-based ring so scrolling never touches the whole | ||
| 173 | framebuffer at all. | ||
| 170 | - **Editor redraw** re-blits changed cells per keystroke (fine at 1280×800); | 174 | - **Editor redraw** re-blits changed cells per keystroke (fine at 1280×800); |
| 171 | the "optimize drawing someday" item. | 175 | the "optimize drawing someday" item. |
| 172 | - **ramfs only**: edited files live in memory, lost on reboot until disk | 176 | - **ramfs only**: edited files live in memory, lost on reboot until disk |
