Feature/source plugins #1
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
|
**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`
|
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()`,
|
turns on a **phosphor density** — the plotter's intensity image (`Plot::set_density()`, the axes rect
|
||||||
one `f32` cell per device pixel of the axes rect **per trace, in that trace's own signal colour**)
|
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
|
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
|
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
|
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,
|
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
|
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
|
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
|
with the acquisitions**: the cost is bounded, and the bound is the grid's — at most a mebibyte of
|
||||||
four one-signal rows; the default four signals in one 800x480 row are 6 MB) and a thousand
|
counts a signal, so the app's four signals hold 4 MiB between them however wide the window, and the
|
||||||
acquisitions cost the same. Each signal is a separate image, so two signals agreeing in a cell read
|
probe's four one-signal rows read `cells=1044714` (4 178 856 bytes, 1 044 714 of them uploaded on a
|
||||||
as two colours and not one blended grey. `fades by` picks how it decays: `acquisitions` (each
|
moved frame) — and a thousand acquisitions cost the same. Each signal is a separate image, so two
|
||||||
acquisition keeps the factor of what was before it, 0.5 by default — the phosphor afterglow
|
signals agreeing in a cell read as two colours and not one blended grey. `fades by` picks how it
|
||||||
schedule) or `time` (a time constant in stream seconds, so the display fades while you watch
|
decays: `acquisitions` (each acquisition keeps the factor of what was before it, 0.5 by default —
|
||||||
whatever the trigger rate). It applies in **trigger mode only** — while a captured acquisition is
|
the phosphor afterglow schedule) or `time` (a time constant in stream seconds, so the display fades
|
||||||
on screen — and it goes away with the trigger, on a pause and on an opened file, because the image
|
while you watch whatever the trigger rate). It applies in **trigger mode only** — while a captured
|
||||||
is an image *of* a stream of acquisitions. Like the invalid-span bands it reserves no layout space
|
acquisition is on screen — and it goes away with the trigger, on a pause and on an opened file,
|
||||||
and nothing on it can be picked. The `[density-probe]` run that measured it is in
|
because the image is an image *of* a stream of acquisitions. Like the invalid-span bands it reserves
|
||||||
`docs/claude/probe-readings.md`; what it costs is in the same place (`[density-probe] frame cost:`:
|
no layout space and nothing on it can be picked. The `[density-probe]` run that measured it is in
|
||||||
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
|
`docs/claude/probe-readings.md`; what it costs is there and in the plotter's
|
||||||
frame, on llvmpipe — measured before the per-trace split, when the one image was still re-filled
|
`docs/data-and-performance.md`, where the density's own pass is priced headless at a fixed geometry —
|
||||||
per row).
|
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
|
**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
|
the retention is bounded by two things: the depth, and **`--buffer-mb`** — persistence may hold at
|
||||||
|
|||||||
Vendored
+1
-1
Submodule deps/plotter updated: 1b8b55d3ee...f79a97be9b.
@@ -379,13 +379,16 @@ Part of [CLAUDE.md](../../CLAUDE.md). These are rules that cost a defect to lear
|
|||||||
- **The phosphor density is the *trace*, and that is a different display from the layers above, not a
|
- **The phosphor density is the *trace*, and that is a different display from the layers above, not a
|
||||||
mode of them.** The trigger panel's `Advanced` block offers both, and the words matter: *multiple
|
mode of them.** The trigger panel's `Advanced` block offers both, and the words matter: *multiple
|
||||||
events* is `persist_depth` (N retained acquisitions, N traces, dimmer with age) while *persistence*
|
events* is `persist_depth` (N retained acquisitions, N traces, dimmer with age) while *persistence*
|
||||||
is `TriggerConfig::density` -- the plotter's `Plot::set_density()`, a screen-sized intensity grid
|
is `TriggerConfig::density` -- the plotter's `Plot::set_density()`, an intensity grid
|
||||||
**per trace, drawn in that trace's own colour**, every acquisition deposited into it, which fades
|
**per trace, drawn in that trace's own colour**, every acquisition deposited into it, which fades
|
||||||
either by a time constant or by a per-acquisition factor. There is **no depth** on the density and
|
either by a time constant or by a per-acquisition factor. There is **no depth** on the density and
|
||||||
no per-acquisition memory: the image is `traces * columns * rows * 4` bytes, one cell per device
|
no per-acquisition memory: the image is `traces * columns * rows * 4` bytes, and both factors are
|
||||||
pixel of the row's axes for every trace the row draws (the app's default four signals in one row
|
bounded -- the grid is the row's axes rect in device pixels **up to the plotter's
|
||||||
are four grids -- 6 MB at 800x480; the probe's one-signal-per-row run is 2.2 MB over four rows), so
|
`kDensityCellCap`**, and there is one grid a trace the row draws. Four traces in a row
|
||||||
a thousand acquisitions cost what one costs. A cell's value is a number of *sweeps*: the library
|
therefore hold at most 4 MiB between them, whoever dragged the window where (the probe's
|
||||||
|
one-signal-per-row run reads `cells=1044714`, 4 178 856 bytes), so a thousand acquisitions cost
|
||||||
|
what one costs and *neither* a wide window nor a long run can make the image grow. A cell's value
|
||||||
|
is a number of *sweeps*: the library
|
||||||
deposits a cell once per trace per sweep however many of that trace's own samples crossed it
|
deposits a cell once per trace per sweep however many of that trace's own samples crossed it
|
||||||
(`[density-probe] on` reads `peak=1.0000` for one sweep; a per-hit deposit read 18) -- dwell is
|
(`[density-probe] on` reads `peak=1.0000` for one sweep; a per-hit deposit read 18) -- dwell is
|
||||||
`Style::intensity_grading`'s question, not this one's. The colour is the trace's own
|
`Style::intensity_grading`'s question, not this one's. The colour is the trace's own
|
||||||
|
|||||||
@@ -1981,27 +1981,29 @@ ring's bindings, and a reading taken there says nothing about either.
|
|||||||
```
|
```
|
||||||
[density-probe] arming on 'square', window 0.5 s, display off
|
[density-probe] arming on 'square', window 0.5 s, display off
|
||||||
[density-probe] off enabled=0 fade=acquisitions tau=1.000 factor=0.500 rows=0 traces=0 cells=0 ink=0.0 peak=0.0000 ratio=1.000000
|
[density-probe] off enabled=0 fade=acquisitions tau=1.000 factor=0.500 rows=0 traces=0 cells=0 ink=0.0 peak=0.0000 ratio=1.000000
|
||||||
[density-probe] on enabled=1 fade=acquisitions tau=1.000 factor=0.500 rows=4 traces=4 cells=2226150 ink=226786.0 peak=1.0000 ratio=1.000000
|
[density-probe] on enabled=1 fade=acquisitions tau=1.000 factor=0.500 rows=4 traces=4 cells=1044714 ink=99403.0 peak=1.0000 ratio=1.000000
|
||||||
[density-probe] step-acquisitions enabled=1 fade=acquisitions tau=1.000 factor=0.500 rows=4 traces=4 cells=2226150 ink=313971.0 peak=1.5000 ratio=1.384437
|
[density-probe] step-acquisitions enabled=1 fade=acquisitions tau=1.000 factor=0.500 rows=4 traces=4 cells=1044714 ink=149104.5 peak=1.5000 ratio=1.500000
|
||||||
[density-probe] time-before enabled=1 fade=time tau=1.000 factor=0.500 rows=4 traces=4 cells=2226150 ink=458610.1 peak=2.1359 ratio=1.000000
|
[density-probe] time-before enabled=1 fade=time tau=1.000 factor=0.500 rows=4 traces=4 cells=1044714 ink=121738.0 peak=1.2247 ratio=1.000000
|
||||||
[density-probe] step-time enabled=1 fade=time tau=1.000 factor=0.500 rows=4 traces=4 cells=2226150 ink=168713.2 peak=0.7858 ratio=0.367879
|
[density-probe] step-time enabled=1 fade=time tau=1.000 factor=0.500 rows=4 traces=4 cells=1044714 ink=44784.9 peak=0.4505 ratio=0.367879
|
||||||
[density-probe] frame cost: tick before=0.62 ms (184 frames) after=6.96 ms (23 frames) draw before=2.02 ms (177) after=6.16 ms (18)
|
[density-probe] frame cost: tick before=3.75 ms (145 frames) after=3.59 ms (24 frames) draw before=3.93 ms (125) after=3.23 ms (6)
|
||||||
[udpscope] density: frames=748 rows=4 traces=4 cells=2226150 grid_bytes=8904600 ink=489400.2 peak=2.2 upload_bytes=2226150
|
[udpscope] density: frames=918 rows=4 traces=4 cells=1044714 grid_bytes=4178856 ink=279073.5 peak=2.2 upload_bytes=1044714
|
||||||
```
|
```
|
||||||
|
|
||||||
The **phosphor density** (`Plot::set_density()`, the trigger pane's `persistence` switch): one
|
The **phosphor density** (`Plot::set_density()`, the trigger pane's `persistence` switch): the axes
|
||||||
screen-sized intensity image **per trace**, in that trace's own signal colour, every acquisition
|
rect in device pixels **up to `kDensityCellCap`** (262 144 cells, 1 MiB of counts) as an intensity
|
||||||
accumulated into it (the newest included), drawn *in place of* the traces and fading by a count or by
|
image **per trace**, in that trace's own signal colour, every acquisition accumulated into it (the
|
||||||
the clock. The numbers are the plotter's own -- `DensityGrid::ink()`/`peak()` summed and maxed over the
|
newest included), drawn *in place of* the traces and fading by a count or by the clock. Past the cap
|
||||||
traces the display is on, which is the same source the library's tests read -- and the
|
the plotter scales the rect down uniformly and magnifies the image back over it with a linear
|
||||||
probe drives the panel's **own widgets** for the switch and the fade, so what it measures is this app's
|
filter, so the number this probe reports is bounded whatever the window is. The numbers are the
|
||||||
wiring.
|
plotter's own -- `DensityGrid::ink()`/`peak()` summed and maxed over the traces the display is on,
|
||||||
|
which is the same source the library's tests read -- and the probe drives the panel's **own
|
||||||
|
widgets** for the switch and the fade, so what it measures is this app's wiring.
|
||||||
|
|
||||||
- **`off` is the display without it**: `rows=0 traces=0`, so there is no grid at all and both numbers
|
- **`off` is the display without it**: `rows=0 traces=0`, so there is no grid at all and both numbers
|
||||||
are zero. That is also the run the frame cost is read against, and it is a plain run -- the density
|
are zero. That is also the run the frame cost is read against, and it is a plain run -- the density
|
||||||
is off by default and nothing draws it.
|
is off by default and nothing draws it.
|
||||||
- **`on` is one sweep**: `traces=4` -- one grid per signal, four rows of one signal each -- and
|
- **`on` is one sweep**: `traces=4` -- one grid per signal, four rows of one signal each -- and
|
||||||
`peak=1.0000` exactly, with `ink=226786` the cells that sweep covered. A cell takes **1.0 once per
|
`peak=1.0000` exactly, with `ink=99403` the cells that sweep covered. A cell takes **1.0 once per
|
||||||
trace per sweep** however many of the trace's own samples crossed it, which is what makes a sweep's
|
trace per sweep** however many of the trace's own samples crossed it, which is what makes a sweep's
|
||||||
peak *one* rather than the eighteen a per-hit deposit read on the same run -- and what makes the
|
peak *one* rather than the eighteen a per-hit deposit read on the same run -- and what makes the
|
||||||
sweeps behind it visible at all.
|
sweeps behind it visible at all.
|
||||||
@@ -2013,23 +2015,34 @@ wiring.
|
|||||||
twice.
|
twice.
|
||||||
- **`step-time` is `1/e` by construction**: one step of `dt = tau` through the plot's own `decay_density()`,
|
- **`step-time` is `1/e` by construction**: one step of `dt = tau` through the plot's own `decay_density()`,
|
||||||
so `ratio=0.367879` is `exp(-1)`. The leg before it (`time-before`) reads the same image under the time
|
so `ratio=0.367879` is `exp(-1)`. The leg before it (`time-before`) reads the same image under the time
|
||||||
fade (`peak=2.1359`), and the pair is the reading that says the *panel's* constant reaches the grid.
|
fade (a peak between 1 and 2, `1.2247` here), and the pair is the reading that says the *panel's* constant
|
||||||
|
reaches the grid.
|
||||||
- **`frame cost:` is the A/B inside one run**: the accumulators as of the tick the display was switched on
|
- **`frame cost:` is the A/B inside one run**: the accumulators as of the tick the display was switched on
|
||||||
against the frames after it, so both means are the same stream, the same layout and the same mock. At four
|
against the frames after it, so both means are the same stream, the same layout and the same mock. The
|
||||||
rows of 573x412 cells it reads **tick 0.62 -> 6.96 ms** and **draw 2.02 -> 6.16 ms**: the per-frame
|
"before" side is a mean that **includes the run's startup frames** (the first paints are the expensive
|
||||||
conversion, upload and deposit. It is llvmpipe, and the arithmetic is the grid's -- 2.2 M cells, one byte
|
ones), so it is a high-water mark and not a steady-state mean: at four rows of ~261 000 cells each (the
|
||||||
each, every frame the time fade moves it. The *draw* mean is now below the run before the per-trace
|
cap) the pair above reads `tick 3.75 -> 3.59 ms`, i.e. the switch is *inside* the startup noise, and a
|
||||||
split (2.02 -> 6.16 against 2.09 -> 20.91): the solid traces are no longer drawn over the image, so the
|
quiet machine reading the same line before the cap read `tick 0.62 -> 9.53 ms` at 2.2 M cells. **The
|
||||||
frame draws four quads where it used to draw four quads *and* every trace.
|
reading that prices a display at a given window is the library's**, taken headless and against a fixed
|
||||||
- **`cells`/`grid_bytes` are the per-signal memory figure**: 556 537 cells and 2.2 MB *per signal*, times
|
geometry, in the plotter's `docs/data-and-performance.md`: a 3040x1700 framebuffer with four rows of one
|
||||||
the four signals here (2 226 150 cells, 8 904 600 bytes). It is the axes rect's device pixels, so it is
|
trace and a 2 s window, where the grid pass alone was **12.9 ms of tick and 12.8 ms of draw a frame and
|
||||||
the screen and the trace count and nothing the trigger has done -- and the app's default layout, four
|
4.9 MB uploaded** before the cap and **3.9 / 5.6 ms and 1.0 MB** after it, over the same frames.
|
||||||
signals in one row, is four grids for that one row.
|
- **`cells`/`grid_bytes` are the per-signal memory figure**: at most **262 144 cells and 1 048 576 bytes
|
||||||
|
*per signal***, and the four signals here read 1 044 714 cells / 4 178 856 bytes because a 1349x424 device
|
||||||
|
axes rect is already past the cap. It is the cap and the trace count, and neither the trigger nor the
|
||||||
|
window beyond the cap has anything to say about it -- the app's default layout, four signals in one row,
|
||||||
|
is four grids for that one row and 4 MiB whoever dragged the window where.
|
||||||
- **The dump's `density:` line** is captured on the last tick the display was **on**, not read at exit: the
|
- **The dump's `density:` line** is captured on the last tick the display was **on**, not read at exit: the
|
||||||
exit probe switches the trigger off before it dumps, which takes the display with it, so a dump that asked
|
exit probe switches the trigger off before it dumps, which takes the display with it, so a dump that asked
|
||||||
the plots would say `rows=0` about a run whose tail had the image up. `upload_bytes` is the **most** any
|
the plots would say `rows=0` about a run whose tail had the image up. `upload_bytes` is the **most** any
|
||||||
one frame uploaded -- one byte a cell **per trace**, over the grids that moved -- and not the last frame's,
|
one frame uploaded -- one byte a cell **per trace**, over the grids that moved -- and not the last frame's,
|
||||||
for the same reason.
|
for the same reason.
|
||||||
|
- **A frame the display is drawing is not a `[notrace]` frame.** `Renderer::draw_traces()` returns while a
|
||||||
|
density is on, so every frame of a persistence display stages no trace; the paint probe skips its
|
||||||
|
traceless accounting for those (they are the display working, not "a frame asked to draw something it had
|
||||||
|
nothing for") and the `[notrace]` line -- one per frame, and so behind `UDPSCOPE_PROBE_NOTRACE` -- is not
|
||||||
|
printed for them. A density run's `traceless paints:` therefore no longer counts them: it read `653 (637
|
||||||
|
after the first bind)` for a run whose density was up six hundred frames.
|
||||||
|
|
||||||
**Read `peak` as the display's ceiling**: with the default `full_scale` of 1.0 a cell at 1.0 is full ink
|
**Read `peak` as the display's ceiling**: with the default `full_scale` of 1.0 a cell at 1.0 is full ink
|
||||||
(the trace's own colour), so a steady display under the acquisition fade sits between 1 and 2, and a `peak`
|
(the trace's own colour), so a steady display under the acquisition fade sits between 1 and 2, and a `peak`
|
||||||
|
|||||||
@@ -115,7 +115,9 @@ precedent, not an exception.
|
|||||||
schedule in use, oldest first — halves, and `1/2^age` at that. Both lines and the two exit-dump
|
schedule in use, oldest first — halves, and `1/2^age` at that. Both lines and the two exit-dump
|
||||||
lines are in [probe-readings.md](probe-readings.md).
|
lines are in [probe-readings.md](probe-readings.md).
|
||||||
- `UDPSCOPE_PROBE_DENSITY_MS` (+ `UDPSCOPE_PROBE_DENSITY_TAU`, default 1.0 s) — the **phosphor
|
- `UDPSCOPE_PROBE_DENSITY_MS` (+ `UDPSCOPE_PROBE_DENSITY_TAU`, default 1.0 s) — the **phosphor
|
||||||
density**: one screen-sized intensity image **per trace**, in that trace's own colour, every
|
density**: an intensity image **per trace**, in that trace's own colour, the axes rect in device
|
||||||
|
pixels up to the plotter's `kDensityCellCap` (past which it scales the rect down uniformly and
|
||||||
|
magnifies the image back over it with a linear filter), every
|
||||||
triggered acquisition accumulated into it (the newest included), drawn *in place of* the traces,
|
triggered acquisition accumulated into it (the newest included), drawn *in place of* the traces,
|
||||||
fading by a per-acquisition factor or by a time constant. It states the display
|
fading by a per-acquisition factor or by a time constant. It states the display
|
||||||
**off** through the panel's own switch first, so the `off` leg is the run without it, then arms the
|
**off** through the panel's own switch first, so the `off` leg is the run without it, then arms the
|
||||||
@@ -144,6 +146,15 @@ precedent, not an exception.
|
|||||||
one run), and the exit dump's `density:` line says what the last frame it was on held. Both lines
|
one run), and the exit dump's `density:` line says what the last frame it was on held. Both lines
|
||||||
and the dump line are in [probe-readings.md](probe-readings.md).
|
and the dump line are in [probe-readings.md](probe-readings.md).
|
||||||
|
|
||||||
|
- `UDPSCOPE_PROBE_NOTRACE` (no value; **not** a scheduled probe, and off unless it is set) — the
|
||||||
|
per-paint detail behind the exit dump's `traceless paints:` counter: one `[notrace]` line for each
|
||||||
|
of the first 40 paints after the first bind that staged no trace, naming the mode, the axis the
|
||||||
|
frame was asked for and every slot's bounds. It is behind a variable because a state that draws
|
||||||
|
nothing lasts as long as it lasts, so an ungated line is one per frame for the whole time -- and it
|
||||||
|
is *not* printed for a frame a phosphor density is drawing, which stages no trace by construction
|
||||||
|
(the frame's ink is the image) and would otherwise be counted as well. The counter itself is in
|
||||||
|
every build; see [probe-readings.md](probe-readings.md).
|
||||||
|
|
||||||
- `UDPSCOPE_PROBE_TRIGRENUM_MS` — the trigger's capture must survive a **renumbering of its own
|
- `UDPSCOPE_PROBE_TRIGRENUM_MS` — the trigger's capture must survive a **renumbering of its own
|
||||||
channel**. It sets the reported geometry through the real widgets (1 s window, 10 % pre share,
|
channel**. It sets the reported geometry through the real widgets (1 s window, 10 % pre share,
|
||||||
hold-off from `--holdoff`) on the mock's *square* alone, polls for a capture to open, and then
|
hold-off from `--holdoff`) on the mock's *square* alone, polls for a capture to open, and then
|
||||||
|
|||||||
@@ -133,9 +133,10 @@
|
|||||||
|
|
||||||
<p>Two things make it different from <gui>multiple events</gui> beside it, and the panel offers
|
<p>Two things make it different from <gui>multiple events</gui> beside it, and the panel offers
|
||||||
both because they answer different questions. <em>It never runs out of room</em>: each signal's
|
both because they answer different questions. <em>It never runs out of room</em>: each signal's
|
||||||
image is the size of the plot on screen, so a display of a thousand acquisitions costs what a
|
image is sized to the plot on screen and capped, so a display of a thousand acquisitions costs
|
||||||
display of one costs — one image per signal, whatever the plot's trace slots — and there is no
|
what a display of one costs — one image per signal, whatever the plot's trace slots, and a very
|
||||||
count to choose. <em>And it fades</em>, in one of two ways — <gui>fades by</gui> picks them:</p>
|
wide window does not make it grow — and there is no count to choose. <em>And it fades</em>, in
|
||||||
|
one of two ways — <gui>fades by</gui> picks them:</p>
|
||||||
<list>
|
<list>
|
||||||
<item><p><gui>acquisitions</gui>: every acquisition keeps
|
<item><p><gui>acquisitions</gui>: every acquisition keeps
|
||||||
<gui>per acquisition</gui> of what was there before it (0.5, the default, is the schedule a
|
<gui>per acquisition</gui> of what was there before it (0.5, the default, is the schedule a
|
||||||
|
|||||||
@@ -102,8 +102,8 @@ struct LayoutState {
|
|||||||
/// for: it is what the display does with the acquisitions, and there is no second switch.
|
/// for: it is what the display does with the acquisitions, and there is no second switch.
|
||||||
///
|
///
|
||||||
/// This is the **multiple event** display -- N retained acquisitions, drawn as N traces. The
|
/// This is the **multiple event** display -- N retained acquisitions, drawn as N traces. The
|
||||||
/// phosphor density beside it is a different display with a different cost (one screen-sized
|
/// phosphor density beside it is a different display with a different cost (one bounded image a
|
||||||
/// image against N window copies), which is why it has its own four fields below and why this
|
/// trace against N window copies), which is why it has its own four fields below and why this
|
||||||
/// one keeps the key it has always had: an older file's `trigger_persistence` is still the
|
/// one keeps the key it has always had: an older file's `trigger_persistence` is still the
|
||||||
/// multiple-event depth.
|
/// multiple-event depth.
|
||||||
int persistence = 1;
|
int persistence = 1;
|
||||||
|
|||||||
+2
-1
@@ -55,7 +55,8 @@ struct TriggerConfig {
|
|||||||
|
|
||||||
/// The **phosphor density** (the plotter's `Plot::set_density()`): off by default, and trigger
|
/// The **phosphor density** (the plotter's `Plot::set_density()`): off by default, and trigger
|
||||||
/// mode only. Where `persist_depth` keeps N whole acquisitions as N traces, this accumulates
|
/// mode only. Where `persist_depth` keeps N whole acquisitions as N traces, this accumulates
|
||||||
/// every acquisition into one screen-sized intensity image -- brightness is how often a trace
|
/// every acquisition into one intensity image **per trace** (the axes rect in device pixels,
|
||||||
|
/// bounded by the plotter's `kDensityCellCap`) -- brightness is how often a trace
|
||||||
/// passed a cell, so the cost of a display of a thousand acquisitions is the cost of one, and
|
/// passed a cell, so the cost of a display of a thousand acquisitions is the cost of one, and
|
||||||
/// there is no depth to get wrong. The image is drawn behind the traces, it is unpickable and it
|
/// there is no depth to get wrong. The image is drawn behind the traces, it is unpickable and it
|
||||||
/// reserves no layout space, exactly as the invalid-span bands do.
|
/// reserves no layout space, exactly as the invalid-span bands do.
|
||||||
|
|||||||
@@ -217,7 +217,7 @@
|
|||||||
|
|
||||||
Both displays live here and they are two different things: *multiple events* keeps the
|
Both displays live here and they are two different things: *multiple events* keeps the
|
||||||
last N acquisitions as N traces, dimmer with age, while *persistence* accumulates every
|
last N acquisitions as N traces, dimmer with age, while *persistence* accumulates every
|
||||||
acquisition into an image (one screen-sized grid per trace, in that trace's own colour,
|
acquisition into an image (one grid per trace, in that trace's own colour,
|
||||||
the plotter's `Plot::set_density()`), drawn in place of the traces. The first is a
|
the plotter's `Plot::set_density()`), drawn in place of the traces. The first is a
|
||||||
count and the second is a decay, which is why neither is a mode of the other. -->
|
count and the second is a decay, which is why neither is a mode of the other. -->
|
||||||
<object class="GtkExpander" id="advanced_exp">
|
<object class="GtkExpander" id="advanced_exp">
|
||||||
|
|||||||
+21
-1
@@ -40,6 +40,19 @@ int on_render_probe(GtkGLArea*, GdkGLContext*, gpointer user) {
|
|||||||
if (s.graded_traces > 0) ++app->dbg_graded_frames;
|
if (s.graded_traces > 0) ++app->dbg_graded_frames;
|
||||||
if (s.raw_traces > 0 || s.lod_traces > 0) check_frame_ink(*app);
|
if (s.raw_traces > 0 || s.lod_traces > 0) check_frame_ink(*app);
|
||||||
if (s.raw_traces == 0 && s.lod_traces == 0) {
|
if (s.raw_traces == 0 && s.lod_traces == 0) {
|
||||||
|
// **A frame the density is drawing is not a traceless one.** `Renderer::draw_traces()`
|
||||||
|
// returns while a plot's phosphor density is on -- the trace ink *is* the image -- so every
|
||||||
|
// frame of a persistence display stages no trace and would be counted here, which inflates
|
||||||
|
// the dump's reading and (with `UDPSCOPE_PROBE_NOTRACE` set below) prints a line per frame.
|
||||||
|
// That is the display working, not "what the frame was asked to draw" with nothing to draw
|
||||||
|
// it from. Read off the plots, because the frame's own stats can only say no trace was
|
||||||
|
// drawn and not why.
|
||||||
|
bool density_on = false;
|
||||||
|
for (int i = 0; i < app->rows->row_count() && !density_on; ++i) {
|
||||||
|
const plot::Plot* p = app->rows->row(i).plot;
|
||||||
|
density_on = p != nullptr && p->density().enabled;
|
||||||
|
}
|
||||||
|
if (!density_on) {
|
||||||
++app->dbg_notrace_frames;
|
++app->dbg_notrace_frames;
|
||||||
app->dbg_notrace_last = app->dbg_paint_n;
|
app->dbg_notrace_last = app->dbg_paint_n;
|
||||||
if (app->dbg_ever_bound) {
|
if (app->dbg_ever_bound) {
|
||||||
@@ -47,7 +60,13 @@ int on_render_probe(GtkGLArea*, GdkGLContext*, gpointer user) {
|
|||||||
// What the frame was asked to draw, beside what there was to draw it from: an axis
|
// What the frame was asked to draw, beside what there was to draw it from: an axis
|
||||||
// that left the data and a trace that had nothing bound are the same picture and
|
// that left the data and a trace that had nothing bound are the same picture and
|
||||||
// different bugs, so both are named here rather than inferred from the count.
|
// different bugs, so both are named here rather than inferred from the count.
|
||||||
if (app->dbg_notrace_after_bound <= 40) {
|
//
|
||||||
|
// **A per-paint line, so it is behind a variable** (`UDPSCOPE_PROBE_NOTRACE`), unlike
|
||||||
|
// the counters beside it: a state that draws nothing lasts as long as it lasts -- a
|
||||||
|
// `Waiting` tail, a bound row with no data -- and the line would be one per frame the
|
||||||
|
// whole time. The count in the dump is the reading; this is the detail behind it.
|
||||||
|
static const bool notrace_print = g_getenv("UDPSCOPE_PROBE_NOTRACE") != nullptr;
|
||||||
|
if (notrace_print && app->dbg_notrace_after_bound <= 40) {
|
||||||
const RowSet::Row& r = app->rows->row(0);
|
const RowSet::Row& r = app->rows->row(0);
|
||||||
const plot::Range ax = r.plot != nullptr ? r.plot->x_range(r.axis_x) : plot::Range{};
|
const plot::Range ax = r.plot != nullptr ? r.plot->x_range(r.axis_x) : plot::Range{};
|
||||||
std::fprintf(stderr, "[notrace] paint %d mode=%s axis=[%.6f..%.6f] segments=%u",
|
std::fprintf(stderr, "[notrace] paint %d mode=%s axis=[%.6f..%.6f] segments=%u",
|
||||||
@@ -65,6 +84,7 @@ int on_render_probe(GtkGLArea*, GdkGLContext*, gpointer user) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return FALSE; // same reason the adapter does: never stop the emission
|
return FALSE; // same reason the adapter does: never stop the emission
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -756,7 +756,7 @@ GtkWidget* build_trigger_panel(App& app) {
|
|||||||
"acquisitions are also bounded by the buffer's own size");
|
"acquisitions are also bounded by the buffer's own size");
|
||||||
app.trigger_persist_row = row_for(ui, "persistence_row", app.trigger_persist_spin);
|
app.trigger_persist_row = row_for(ui, "persistence_row", app.trigger_persist_spin);
|
||||||
|
|
||||||
// The phosphor *density*: one screen-sized image per trace, in that trace's own colour, every
|
// The phosphor *density*: one bounded image per trace, in that trace's own colour, every
|
||||||
// acquisition accumulated into it, drawn *in place of* the traces and fading by a time constant
|
// acquisition accumulated into it, drawn *in place of* the traces and fading by a time constant
|
||||||
// or by a per-acquisition factor -- the other display of the same acquisitions, and nothing like
|
// or by a per-acquisition factor -- the other display of the same acquisitions, and nothing like
|
||||||
// the multiple-event one above (an image per signal against N retained traces, and no count to
|
// the multiple-event one above (an image per signal against N retained traces, and no count to
|
||||||
@@ -772,7 +772,7 @@ GtkWidget* build_trigger_panel(App& app) {
|
|||||||
}
|
}
|
||||||
gtk_widget_set_tooltip_text(
|
gtk_widget_set_tooltip_text(
|
||||||
app.trigger_density_switch,
|
app.trigger_density_switch,
|
||||||
"accumulate every triggered acquisition into a screen-sized image per signal, in that "
|
"accumulate every triggered acquisition into an image per signal, in that "
|
||||||
"signal's own colour, drawn in place of the traces: brightness is how often a trace passed, "
|
"signal's own colour, drawn in place of the traces: brightness is how often a trace passed, "
|
||||||
"so an image of a thousand acquisitions costs what one costs. Trigger mode only, and cleared "
|
"so an image of a thousand acquisitions costs what one costs. Trigger mode only, and cleared "
|
||||||
"whenever the display leaves it");
|
"whenever the display leaves it");
|
||||||
|
|||||||
Reference in new issue
Block a user