perf: a frozen frame is not re-rendered sixty times a second

The tick queued a GL render unconditionally. In `Held` and `Paused` the rows
are bound to an immutable snapshot on a pinned axis, so a frame in which none
of the picture's own terms moved is the same frame again. The gate keys on a
coarse signature of what a frozen view can be re-framed by, opens for
`kSettleRenders` frames on a change because the figure lays out per render, and
has a floor that renders anyway every few ticks. The layout editor is excluded:
its buttons are placed from the last frame's rects, so a skipped frame there is
a stale widget rather than a stale picture. `skips=` in the probe dump is the
reading.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Martino FerrariandClaude Opus 4.6 committed 2026-10-13 14:50:55 +02:00
1 parent 84c158ff21
commit be71a1d4bb
5 files changed
+130 -4

No files matched your search

+12 -1
View File
@@ -148,7 +148,7 @@ precedent, not an exception.
- `UDPSCOPE_PROBE_PAUSE_MS` — pause acquisition mid-run so layout numbers are
measured on a still picture. It now also asserts what a pause *is*
(`[pause-probe] <action> paused=D ring_produced=N event_size=M frozen_x=[..] axis=[..]
glance=[..]` on stderr):
skips=N glance=[..]` on stderr):
it presses the **button**, not `Acquisition::set_paused()`, because pausing is a display
state as well as an acquisition one and the view snapshot and axis pin live in the
handler. Across the three lines **`ring_produced` must grow** (the producer never
@@ -168,6 +168,17 @@ precedent, not an exception.
stops while paused and "how long have I been looking at this" is a question about the user, not
about the stream; it is written through `format_elapsed()` so the field steps to a coarser unit
instead of growing digits (see the layout rule).
**`skips=` is the assertion for the render gate** (the end of `tick()`), cumulative over the
session: the `live` line must read **0** and the `paused` line must read **more than 0**. A
frozen view is bound to an immutable snapshot on a pinned axis, so a frame whose picture cannot
have changed is not drawn again — and this is the only line that can say whether that happened,
since a skipped frame is invisible in every other reading by construction. Non-zero on the
`live` line is the gate's condition inverted, which would cost dropped samples' worth of
picture; 0 on the `paused` line is the gate not engaging and the saving not being made.
The gate cannot stall the picture (`kStaticRenderEvery` renders every few ticks regardless),
so the renderer's own baselines below are unchanged by it: a measured run read `skips=0`,
then 33, then 45, with `columns == graded`, `render blank frames: 0`, and the layout floor
still converged (`y-gutter 104..104`).
- `UDPSCOPE_PROBE_COLOR_MS` — recolour one plotted signal and read the colour back out of the
trace and the chip, round-trip it through the session writer, then clear it. Schedule
`UDPSCOPE_ENABLE_ALL_MS` before it: with nothing bound it has no trace to recolour and asserts