From 2481c3bae4885c8c0b9aa3c4c18f78e54f7c4490 Mon Sep 17 00:00:00 2001 From: mikael-lovqvists-claude-agent Date: Sun, 29 Mar 2026 19:33:22 +0000 Subject: [PATCH] Refactor no-signal timing to integer milliseconds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace double wall-time with uint64_t monotonic milliseconds for last_frame_ms and last_no_signal_ms. Integer ms is the right type for a threshold comparison — no floating point needed. Co-Authored-By: Claude Sonnet 4.6 --- src/node/main.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/node/main.c b/src/node/main.c index 2676978..e300f12 100644 --- a/src/node/main.c +++ b/src/node/main.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -186,9 +187,9 @@ struct Display_Slot { int frame_ready; /* No-signal animation */ - int no_signal_fps; /* 0 → default 15 */ - double last_frame_t; /* wall time of last successfully displayed frame */ - double last_no_signal_t; + int no_signal_fps; /* 0 → default 15 */ + uint64_t last_frame_ms; /* monotonic ms of last successfully displayed frame */ + uint64_t last_no_signal_ms; /* monotonic ms of last no-signal render */ /* Viewer — created and used only on the main thread */ Xorg_Viewer *viewer; @@ -524,24 +525,26 @@ static void display_loop_tick(struct Node *node) struct timespec _ts; clock_gettime(CLOCK_MONOTONIC, &_ts); - double now = (double)_ts.tv_sec + (double)_ts.tv_nsec * 1e-9; + uint64_t now_ms = (uint64_t)_ts.tv_sec * 1000u + + (uint64_t)_ts.tv_nsec / 1000000u; if (fdata) { struct Proto_Video_Frame vf; if (APP_IS_OK(proto_read_video_frame(fdata, flen, &vf))) { xorg_viewer_push_mjpeg(d->viewer, vf.data, vf.data_len); - d->last_frame_t = now; + d->last_frame_ms = now_ms; } free(fdata); } /* Render no-signal only when stream has been silent for ≥1 s */ - if (now - d->last_frame_t >= 1.0) { - double interval = 1.0 / (double)(d->no_signal_fps > 0 ? d->no_signal_fps : 15); - if (now - d->last_no_signal_t >= interval) { - /* Wrap to [0, 1000) to preserve float32 fractional precision */ - xorg_viewer_render_no_signal(d->viewer, (float)fmod(now, 1000.0), 80.0f); - d->last_no_signal_t = now; + if (now_ms - d->last_frame_ms >= 1000u) { + uint64_t interval_ms = 1000u / (uint64_t)(d->no_signal_fps > 0 ? d->no_signal_fps : 15); + if (now_ms - d->last_no_signal_ms >= interval_ms) { + /* shader time: wrap ms to [0, 1000000) → [0, 1000) s, preserving float32 precision */ + float shader_t = (float)(now_ms % 1000000u) / 1000.0f; + xorg_viewer_render_no_signal(d->viewer, shader_t, 80.0f); + d->last_no_signal_ms = now_ms; } }