Skip to content

1204: exact damage per frame for SCFB (flag DAMAGE), on all drawing threads - #23

Merged
dylanneve1 merged 1 commit into
mainfrom
avf/scfb-damage
Oct 23, 2026
Merged

dylanneve1 merged 1 commit into
mainfrom
avf/scfb-damage

Conversation

@dylanneve1

Copy link
Copy Markdown
Collaborator

Until now, MiniIOMobileFramebuffer marked the whole panel dirty on every swap, so Scion's damage-only copy (scion #123) had nothing to save.

How it works now

  • With SCFB, it keeps a cached shadow of the panel.
  • drawRows compares each new row with the shadow: the changed span of an unscaled row, or pixel by pixel when scaling. It writes only the changes to the shadow and the panel. The panel's write-combined memory is never read, and fewer bytes are written to it.
  • Each row share folds its bounds into the frame's damage with lock-free min/max. Drawing therefore stays on all the helper threads; fDiff forces a single thread.
  • Each frame is published with that rectangle and flag bit 2 DAMAGE.
  • The first frame after the text console, and a black screen, are published whole.

QEMU (hvf), iOS 16.5 home screen

  • Frames are published with flags=5 and a damage rectangle of about 30×80 px, around the Clock icon's second hand.
  • While Settings sits idle, frames are published with an empty rectangle (dirty=(0,0,0,0)), which the app now skips.
  • Settings renders completely in the dumped panel.

Also qemu-tap.py now takes its port from $QMP. Without that, with two QEMUs running, a tap went to the other one.

Docs: scion-avf#21 (SCFB.md, bit 2).

🤖 Generated with Claude Code

MiniIOMobileFramebuffer marked the whole panel dirty on every swap, so
the Scion app (scion #123) copied 11 MB per frame. With SCFB it now keeps
a cached shadow of the panel: drawRows compares each new row with it (the
changed span of an unscaled row, pixel by pixel when scaling), writes only
the changes to the shadow and the panel, and folds its bounds into the
frame's damage with lock-free min/max, so the row shares stay on all
helper threads (unlike fDiff). The frame is published with that
rectangle and flag bit 2 (DAMAGE: exact; empty means nothing changed).
The first frame after the text console is published whole. Without SCFB
nothing changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dylanneve1
dylanneve1 merged commit e910ba4 into main Oct 23, 2026
1 check passed
@dylanneve1
dylanneve1 deleted the avf/scfb-damage branch November 2, 2026 01:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant