Profiling (Pixel 7 + SM-T819) showed the chart CPU-bound in Skia
analytic-AA path fill plus a full-buffer copy on every frame.
- LineSignalRenderer: draw the signal polyline with anti-aliasing off,
via a cached common Paint + drawIntoCanvas (KMP-safe, no nativeCanvas).
Flips Skia from CPU coverage-mask raster to GPU tessellation;
configured strokeWidth still honored. Removes the old Stroke cache.
- TieredBuffer/CircularBuffer: replace the full ~60k-sample copy+scan in
the draw hot path with an O(log n) bisect window read (copyWindow).
Output byte-identical (equivalence tests incl. ring-wrap + edges).
- RealtimeChart: split the single Canvas into a cold layer (Y-axis line,
grid, labels) and a hot layer (signal, X-axis, crosshair) so per-frame
TextMeasurer layout stops running every frame. Y range stabilized to
the tick grid and shared by both layers (signal never clips).
- minSdk 26 -> 24.
Renderer unit test moved commonTest -> iosTest (Compose Paint delegates
to a non-mockable android.graphics.Paint stub on the JVM host; Skiko
backs it for real). Verified on SM-T819 (release): frame time 150ms ->
48ms, ~10 -> ~31 fps at full 8x200 Hz load.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Dirty-flag render: dataVersion counter in RealtimeChartState, skip Canvas draw
when no new data since last frame (zero GPU work when sensor idle)
- targetFps=30 default in ChartConfig (pass null for max display refresh rate)
- iOS targets: iosX64, iosArm64, iosSimulatorArm64 + Platform.ios.kt actual
- KDoc: RealtimeChart params, dataVersion, ChartConfig.targetFps, LodMode entries,
AxisLabelMode entries
- README: fixed Maven coords, added LoD/AxisLabels/Material3 sections, updated
feature list and performance notes
- Tests: RealtimeChartStateTest (17 tests, dataVersion + signal lifecycle)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- TieredBuffer: replace MEAN binning with MIN_MAX (min+max per bin).
Mathematically composable: MIN(bin_mins)=global_MIN, MAX(bin_maxes)=global_MAX.
Eliminates tier-boundary visual artifacts. TIER1/TIER2 capacity doubled (2 samples/bin).
- LodMode: remove MEAN. Only MIN_MAX and LTTB remain.
MEAN introduced values never present in raw signal — disinformation for sensor data.
- ChartConfig: default lodMode changed to MIN_MAX.
- Version: 0.4.1-SNAPSHOT → 0.5.0-SNAPSHOT
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>