Refactor no-signal timing to integer milliseconds

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 <noreply@anthropic.com>
This commit is contained in:
2026-03-29 19:33:22 +00:00
parent 8460841e8e
commit 2481c3bae4

View File

@@ -7,6 +7,7 @@
#include <pthread.h> #include <pthread.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <stdint.h>
#include <time.h> #include <time.h>
#include <math.h> #include <math.h>
#include <sys/sysmacros.h> #include <sys/sysmacros.h>
@@ -186,9 +187,9 @@ struct Display_Slot {
int frame_ready; int frame_ready;
/* No-signal animation */ /* No-signal animation */
int no_signal_fps; /* 0 → default 15 */ int no_signal_fps; /* 0 → default 15 */
double last_frame_t; /* wall time of last successfully displayed frame */ uint64_t last_frame_ms; /* monotonic ms of last successfully displayed frame */
double last_no_signal_t; uint64_t last_no_signal_ms; /* monotonic ms of last no-signal render */
/* Viewer — created and used only on the main thread */ /* Viewer — created and used only on the main thread */
Xorg_Viewer *viewer; Xorg_Viewer *viewer;
@@ -524,24 +525,26 @@ static void display_loop_tick(struct Node *node)
struct timespec _ts; struct timespec _ts;
clock_gettime(CLOCK_MONOTONIC, &_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) { if (fdata) {
struct Proto_Video_Frame vf; struct Proto_Video_Frame vf;
if (APP_IS_OK(proto_read_video_frame(fdata, flen, &vf))) { if (APP_IS_OK(proto_read_video_frame(fdata, flen, &vf))) {
xorg_viewer_push_mjpeg(d->viewer, vf.data, vf.data_len); xorg_viewer_push_mjpeg(d->viewer, vf.data, vf.data_len);
d->last_frame_t = now; d->last_frame_ms = now_ms;
} }
free(fdata); free(fdata);
} }
/* Render no-signal only when stream has been silent for ≥1 s */ /* Render no-signal only when stream has been silent for ≥1 s */
if (now - d->last_frame_t >= 1.0) { if (now_ms - d->last_frame_ms >= 1000u) {
double interval = 1.0 / (double)(d->no_signal_fps > 0 ? d->no_signal_fps : 15); uint64_t interval_ms = 1000u / (uint64_t)(d->no_signal_fps > 0 ? d->no_signal_fps : 15);
if (now - d->last_no_signal_t >= interval) { if (now_ms - d->last_no_signal_ms >= interval_ms) {
/* Wrap to [0, 1000) to preserve float32 fractional precision */ /* shader time: wrap ms to [0, 1000000) → [0, 1000) s, preserving float32 precision */
xorg_viewer_render_no_signal(d->viewer, (float)fmod(now, 1000.0), 80.0f); float shader_t = (float)(now_ms % 1000000u) / 1000.0f;
d->last_no_signal_t = now; xorg_viewer_render_no_signal(d->viewer, shader_t, 80.0f);
d->last_no_signal_ms = now_ms;
} }
} }