fix: bound the density grid, and make [notrace] a reading instead of a flood
The plotter caps a density grid at kDensityCellCap now (deps/plotter), so a 2 s window with persistence on no longer scales the image with the window: the probe's four one-signal rows read 1 044 714 cells / 4 178 856 bytes where they read 2 226 150 / 8 904 600, and a moved frame uploads 1 044 714 bytes where it uploaded 2 226 150. The probe's own legs are unchanged (on peak=1.0000, step-acquisitions peak=1.5000, step-time ratio=0.367879). The paint probe no longer counts a frame the density is drawing as *traceless*. `Renderer::draw_traces()` returns while the ink is the image, so every frame of a persistence display stages no trace: the dump read `traceless paints: 653 (637 after the first bind)` for a run whose real figure is 4 (0), and the `[notrace]` line printed for each of those frames. It is now behind UDPSCOPE_PROBE_NOTRACE -- a per-paint line is a log flood and not a reading -- while the counters it details stay in every build, and the line stays reachable for the state it was written for (a bound row that draws nothing). Docs corrected where they stated the old rule: the README, the trigger invariants, the density probe's readings, the verification list (the new variable) and the manual page behind the panel's tooltip.
This commit is contained in:
1 parent
da826f2cb5
commit
ac054a30c9
11 files changed
+131
-76
No files matched your search
@@ -1271,8 +1271,10 @@ snapshots there and then, because a trigger that has stopped firing never reache
|
||||
|
||||
**Persistence: one image per signal, every acquisition.** The trigger panel's `Advanced` block
|
||||
carries the *other* display of the same acquisitions, and it is not a count at all: `persistence`
|
||||
turns on a **phosphor density** — the plotter's screen-sized intensity image (`Plot::set_density()`,
|
||||
one `f32` cell per device pixel of the axes rect **per trace, in that trace's own signal colour**)
|
||||
turns on a **phosphor density** — the plotter's intensity image (`Plot::set_density()`, the axes rect
|
||||
in device pixels **per trace, in that trace's own signal colour**, bounded by the plotter's
|
||||
`kDensityCellCap`: past **262 144 cells** — a mebibyte of counts — it scales the rect down uniformly
|
||||
and magnifies the image back over it with a linear filter)
|
||||
into which every triggered acquisition is deposited, the newest included, and which is drawn *in
|
||||
place of* the traces. The current acquisition is therefore a sweep *inside* the image and fades with
|
||||
the rest; no solid polyline is drawn over it, which is what a report of "the persistent image plus
|
||||
@@ -1280,20 +1282,24 @@ the last acquisition, and the last one never fades in time mode" turned out to b
|
||||
brightness is how many acquisitions passed through it — one sweep's ink is the trace's own colour,
|
||||
and where several agree it clamps there rather than going white — so the display brightens where the
|
||||
signal is steady and dims where it only passed, **with no depth to choose and no memory that grows
|
||||
with the acquisitions**: the cost is the screen's times the traces on it (2.2 MB over the probe's
|
||||
four one-signal rows; the default four signals in one 800x480 row are 6 MB) and a thousand
|
||||
acquisitions cost the same. Each signal is a separate image, so two signals agreeing in a cell read
|
||||
as two colours and not one blended grey. `fades by` picks how it decays: `acquisitions` (each
|
||||
acquisition keeps the factor of what was before it, 0.5 by default — the phosphor afterglow
|
||||
schedule) or `time` (a time constant in stream seconds, so the display fades while you watch
|
||||
whatever the trigger rate). It applies in **trigger mode only** — while a captured acquisition is
|
||||
on screen — and it goes away with the trigger, on a pause and on an opened file, because the image
|
||||
is an image *of* a stream of acquisitions. Like the invalid-span bands it reserves no layout space
|
||||
and nothing on it can be picked. The `[density-probe]` run that measured it is in
|
||||
`docs/claude/probe-readings.md`; what it costs is in the same place (`[density-probe] frame cost:`:
|
||||
tick 0.74 → 9.99 ms and draw 2.09 → 20.91 ms over the same run, at four rows and 2.2 M cells a
|
||||
frame, on llvmpipe — measured before the per-trace split, when the one image was still re-filled
|
||||
per row).
|
||||
with the acquisitions**: the cost is bounded, and the bound is the grid's — at most a mebibyte of
|
||||
counts a signal, so the app's four signals hold 4 MiB between them however wide the window, and the
|
||||
probe's four one-signal rows read `cells=1044714` (4 178 856 bytes, 1 044 714 of them uploaded on a
|
||||
moved frame) — and a thousand acquisitions cost the same. Each signal is a separate image, so two
|
||||
signals agreeing in a cell read as two colours and not one blended grey. `fades by` picks how it
|
||||
decays: `acquisitions` (each acquisition keeps the factor of what was before it, 0.5 by default —
|
||||
the phosphor afterglow schedule) or `time` (a time constant in stream seconds, so the display fades
|
||||
while you watch whatever the trigger rate). It applies in **trigger mode only** — while a captured
|
||||
acquisition is on screen — and it goes away with the trigger, on a pause and on an opened file,
|
||||
because the image is an image *of* a stream of acquisitions. Like the invalid-span bands it reserves
|
||||
no layout space and nothing on it can be picked. The `[density-probe]` run that measured it is in
|
||||
`docs/claude/probe-readings.md`; what it costs is there and in the plotter's
|
||||
`docs/data-and-performance.md`, where the density's own pass is priced headless at a fixed geometry —
|
||||
the app's in-run A/B of it is a mean against a mean and the "before" side includes the run's own
|
||||
startup frames. A 3040x1700 framebuffer with four rows of one trace and a 2 s window (the frozen
|
||||
configuration: at 2x device scale that is a 1520x850 window) read **4.5 M cells a trace, 12.9 ms of
|
||||
tick and 12.8 ms of draw a frame and 4.9 MB uploaded** on llvmpipe, and reads **1.0 M cells, 3.9 /
|
||||
5.6 ms and 1.0 MB** at the cap.
|
||||
|
||||
**And it says what it costs.** A retained acquisition is a whole window copied out of the ring, so
|
||||
the retention is bounded by two things: the depth, and **`--buffer-mb`** — persistence may hold at
|
||||
|
||||
Reference in new issue
Block a user