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
+12
-3
@@ -56,10 +56,15 @@ void ChannelBuffer::acquire() noexcept {
|
||||
// The pyramid's window follows the ring's: sample index `base` is the oldest
|
||||
// one still retained. drop_before() is monotonic and cheap.
|
||||
pyramid_.drop_before(values_->base());
|
||||
// And the window's first stamp with it, here and nowhere else (see the member's note): the
|
||||
// window is pinned by the line above, so its origin is a fixed sample, and this is the one
|
||||
// place in the object's life where that sample's slot is safe to read.
|
||||
if (pyramid_.size() > 0) window_x0_ = time_of(absolute(0));
|
||||
}
|
||||
|
||||
void ChannelBuffer::invalidate() noexcept {
|
||||
published_ = 0;
|
||||
window_x0_ = 0.0f;
|
||||
pyramid_.clear();
|
||||
}
|
||||
|
||||
@@ -116,11 +121,16 @@ f64 ChannelBuffer::dx() const {
|
||||
|
||||
f64 ChannelBuffer::x0() const {
|
||||
if (pyramid_.size() == 0) return epoch_;
|
||||
return epoch_ + f64(time_of(absolute(0)));
|
||||
return epoch_ + f64(window_x0_);
|
||||
}
|
||||
|
||||
f64 ChannelBuffer::x_at(u64 i) const {
|
||||
if (i >= pyramid_.size()) return x0();
|
||||
// Sample 0 is served from the cache, never from the ring: it is the slot the producer is
|
||||
// overwriting, and `neighbours()` tests the asked-for x against this value, so a read one
|
||||
// ring-span too new made it refuse the whole visible range -- which left the renderer
|
||||
// gathering the entire ring at a coarse level and drawing it off the axis.
|
||||
if (i == 0) return x0();
|
||||
return epoch_ + f64(time_of(absolute(i)));
|
||||
}
|
||||
|
||||
@@ -161,8 +171,7 @@ u64 ChannelBuffer::snap_index(f64 x) const {
|
||||
plot::Range ChannelBuffer::x_bounds() const {
|
||||
const u64 n = pyramid_.size();
|
||||
if (n == 0) return plot::Range{epoch_, epoch_};
|
||||
return plot::Range{epoch_ + f64(time_of(absolute(0))),
|
||||
epoch_ + f64(time_of(absolute(n - 1)))};
|
||||
return plot::Range{x0(), epoch_ + f64(time_of(absolute(n - 1)))};
|
||||
}
|
||||
|
||||
plot::Range ChannelBuffer::y_bounds() const {
|
||||
|
||||
Reference in new issue
Block a user