From 16f4c5be220756808747bfb47739733d3f107634 Mon Sep 17 00:00:00 2001 From: Luke Hoersten Date: Sat, 20 Jun 2026 11:50:25 -0500 Subject: firmware: live-update last_paint_event_us_low so /state g2g reflects real frame age MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous Phase 4 implementation only published last_paint_event_us_low into the windowed-stats snapshot at every 30-frame roll (~1.5s at 20fps). Combined with the script's 5s /state poll cadence, the "freshest frame age" we could compute was up to ~6.5s stale before any actual lag — meaningless as a perf signal. Update s_stats.last_paint_event_us_low under portMUX on every painted v1 frame. The other window stats (recv/dec/paint/idle min/avg/max + fps/MBps) keep their roll cadence because they genuinely need a full window to compute; this single u32 just gets overwritten with the most recent value each paint. portENTER_CRITICAL on the ESP32-P4 is ~half a microsecond per side — at 20fps that's 20µs/s of overhead, immeasurable next to the 30-40ms recv per frame. Expected: g2g during a saturated stream drops from the previous 2-6s reading to single-digit hundreds of ms or lower, reflecting the actual emit→display lag. --- main/stream_server.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/main/stream_server.c b/main/stream_server.c index 1321f22..206c513 100644 --- a/main/stream_server.c +++ b/main/stream_server.c @@ -239,7 +239,18 @@ static void handle_client(int fd, const char *peer) viewport_state_unlock(); last_painted_seq = seq; - if (event_us_low != 0) last_event_us_low = event_us_low; + if (event_us_low != 0) { + last_event_us_low = event_us_low; + // Live update: /state needs this fresh on every painted + // frame so the script's g2g reflects the actual age of + // the currently-displayed frame, not the age at last + // window roll (which can be up to ~1.5s stale). The + // other window stats stay at roll cadence — they + // genuinely need a full window to compute. + portENTER_CRITICAL(&s_stats_mux); + s_stats.last_paint_event_us_low = event_us_low; + portEXIT_CRITICAL(&s_stats_mux); + } jpeg_decoder_unlock(); state_machine_frame_painted(); frames_decoded++; -- cgit v1.2.3