feat(ux)+fix(rings): release counter #N in the wordmark; all shared-frame rings 4->8 (#11)
Roll-forward of today-slices 6fd1d9c onto the slice-8 base, two-loop hunk dropped. Release counter (per-build GUID read as noise; +1 per commit from git rev-list, baseline 241 -> #13, generated by GenerateBuildStamp; GUID demotes to startup.log). Tests pinned to Label/#N >= 13; wordmark display test asserts the Label. Flash fix (take 14 finding): consumer holds must never outlive depth x source period — 4 slots at high refresh lap ~27ms vs a <=50ms compositor read, so a recycled slot flashed its new frame over the lagged old one. All shared rings 4->8 (OBS/overlay precedent for ring discipline). Camera producer now rotates an 8-deep ring + Epoch instead of a fresh ~3.7MB array per device frame (110-220MB/s LOH churn); WebView2 capture reuses a canvas scratch + 8-deep output ring + a reused WriteableBitmap instead of two fresh arrays + a fresh bitmap per 10Hz tick. Paste cache stays identity-keyed (Epoch).
This commit is contained in:
@@ -78,6 +78,13 @@ Both halves were solved by OBS/libyuv long ago; do not re-derive:
|
||||
remainder, SPIN the last ~2ms across the deadline. Diagnostic before touching the compositor again:
|
||||
period ≈ work + 15.6 → the SLEEP is the bug, not the work.
|
||||
|
||||
Related (take 14, 2026-09-04): **recycled ring buffers are a race you must SIZE, not just own.**
|
||||
Deepening shared frames to kill GC churn (a fresh 8.3MB/tick array) hands out REUSED memory — the
|
||||
ring's depth × source period must EXCEED the worst consumer hold (compositor read + lagged UI
|
||||
preview copy), not just "a few frames". 4 slots at 144Hz capture laps in ~27ms vs a ≤50ms read: half
|
||||
a new screen frame flashed over an old one in the recording ("bits flashing over other bits").
|
||||
Depth 8 everywhere (screen/camera/web output rings); the paste-cache Epoch still guards identity.
|
||||
|
||||
4. **Hermetic pacing test:** inject the delay seam to RECORD the requested TimeSpan and
|
||||
genuinely await it (`Task.Delay(d, ct)`) — a fake that returns
|
||||
`Task.CompletedTask` synchronously makes the whole pump loop run on `StartAsync`'s
|
||||
|
||||
Reference in New Issue
Block a user