fixed plot flicker, measurement cost and toolbar icons
The flicker ("no data" at no constant frequency, worse with the measurements
and cursors panes up) was a torn read of the window's first stamp: acquire()
pins the window to the ring's oldest slot, and reading it at paint time races
the producer lapping it, returning a stamp one ring span too new. x0() is the
origin every trace point is reconstructed from, so one torn read produced a
refused neighbours(), a filter that dropped three quarters of the points, and
a polyline shifted off its axis. It is cached by acquire() under the lock now.
EventSeries::neighbours() answered from the (x - x0)/dx grid, whose drift from
the real arrival stamps arrives as a constant offset in seconds -- a doubling
share of the screen per zoom step, which is the "zooming into a held event
clips it more from the left" report. Both series binary-search the stamps now.
The measurements pane went through the LOD pyramid rather than reading its
window raw (19.7 ms per recompute to 1.2 ms, 0.1% of a 2 M-sample window) and
recomputes on a cadence; the math engine lost a per-slot heap allocation, a
per-sample source lookup by name and a fetch_add that cost more than the
arithmetic it counted.
The cursors pane's mix mode drew a line per *named* slot, so a slot holding a
signal that can never produce a channel -- the stream's timestamp -- got a row
that could only read "--", and such names were re-saved every session. It
counts bound traces now and apply_layout() refuses them.
Four toolbar icons are drawn for this app and compiled in as a GResource: the
stock ones were a record dot for the trigger and three magnifiers for cursors,
measurements and math.
New probes and dump lines for all of it (trace ink, measure cost, math cost,
event zoom, toolbar icons); README and CLAUDE.md record what they cure.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
714d042809
commit
a92a6b5bf0
20 files changed
+1945
-243
No files matched your search
+19
-6
@@ -180,15 +180,28 @@ class EventSeries final : public plot::data::Series {
|
||||
if (last * span < e) emit_raw(last * span, e);
|
||||
}
|
||||
|
||||
/// Bracketing samples by **binary search over the stamps**, which are monotonic -- never
|
||||
/// through the `(x - x0()) / dx()` grid, for the same reason `ChannelBuffer` does not: `dx()`
|
||||
/// is the window's *mean* spacing and the stamps are an arrival clock, so the grid and the
|
||||
/// real stamps drift apart by however much the clock wandered. The renderer picks the visible
|
||||
/// index window from this call, so that drift came out as a **constant offset in data
|
||||
/// seconds** between the axis and the gathered geometry: a blank left margin whose *pixel*
|
||||
/// width doubles with every zoom step (374 px of a 716 px axis after seven), with the trace's
|
||||
/// ink pushed off the right-hand edge by the same amount and the crosshair -- which reads
|
||||
/// `x_at()`, the real stamp -- still correct everywhere. That is the "zooming into a held
|
||||
/// event clips it more and more from the left" report. A perfectly uniform source hides it
|
||||
/// completely, which is why the mock can jitter its clock (`--clock-jitter`).
|
||||
bool neighbours(f64 x, u64& i0, u64& i1) const override {
|
||||
const u64 n = size();
|
||||
if (n < 2) return false;
|
||||
const f64 step = dx();
|
||||
if (!(step > 0.0)) return false;
|
||||
f64 idx = (x - x0()) / step;
|
||||
if (idx < 0.0) idx = 0.0;
|
||||
if (idx > static_cast<f64>(n - 1)) idx = static_cast<f64>(n - 1);
|
||||
i0 = static_cast<u64>(idx);
|
||||
const auto& s = snap_->stamps;
|
||||
const auto begin = s.begin();
|
||||
const auto end = begin + static_cast<std::ptrdiff_t>(n);
|
||||
// The first stamp *greater* than x, so x itself brackets as [that - 1, that]: a pointer
|
||||
// exactly on a sample must not put the sample behind it.
|
||||
const auto it = std::upper_bound(begin, end, static_cast<f32>(x));
|
||||
const u64 above = static_cast<u64>(it - begin);
|
||||
i0 = above > 0 ? above - 1 : 0;
|
||||
i1 = i0 + 1 < n ? i0 + 1 : i0;
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user