ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
fps.c
Go to the documentation of this file.
1
8#include <ascii-chat/common.h>
10#include <ascii-chat/log/log.h>
11
15static void log_fps_report(const char *tracker_name, double actual_fps, uint64_t frame_count, double elapsed_seconds) {
16 log_dev_every(4500 * US_PER_MS_INT, "[%s] %.1f fps (%llu frames in %.1fs)", tracker_name, actual_fps,
17 (unsigned long long)frame_count, elapsed_seconds);
18}
19
25static void log_lag_event(const char *tracker_name, const char *context, double late_ms, double expected_ms,
26 double actual_ms, double actual_fps) {
27 // Rate limit to once per second to avoid log spam
28 log_warn_every(NS_PER_MS_INT, "[%s] LAG: %s late by %.1fms (expected %.1fms, got %.1fms, %.2f fps)", tracker_name,
29 context, late_ms, expected_ms, actual_ms, actual_fps);
30}
31
32void fps_init(fps_t *tracker, int expected_fps, const char *name) {
33 // Default report interval: 1 second
34 fps_init_with_interval(tracker, expected_fps, name, 1 * NS_PER_SEC_INT);
35}
36
37void fps_init_with_interval(fps_t *tracker, int expected_fps, const char *name, uint64_t report_interval_ns) {
38 if (!tracker) {
39 return;
40 }
41
42 tracker->frame_count = 0;
43 tracker->expected_fps = expected_fps > 0 ? expected_fps : 60;
44 tracker->tracker_name = name ? name : "FPS";
45 tracker->report_interval_ns = report_interval_ns;
46
47 // Initialize timestamps to zero (will be set on first frame)
48 tracker->last_fps_report_ns = 0;
49 tracker->last_frame_time_ns = 0;
50}
51
52void fps_frame_ns(fps_t *tracker, uint64_t current_time_ns, const char *context) {
53 if (!tracker) {
54 return;
55 }
56
57 // Initialize on first frame
58 if (tracker->last_fps_report_ns == 0) {
59 tracker->last_fps_report_ns = current_time_ns;
60 tracker->last_frame_time_ns = current_time_ns;
61 }
62
63 tracker->frame_count++;
64
65 // Calculate time since last frame in nanoseconds
66 uint64_t frame_interval_ns = time_elapsed_ns(tracker->last_frame_time_ns, current_time_ns);
67 tracker->last_frame_time_ns = current_time_ns;
68
69 // Expected frame interval in nanoseconds
70 // For 60 FPS: 1 second / 60 = 16,666,666 ns per frame
71 uint64_t expected_interval_ns = NS_PER_SEC_INT / (uint64_t)tracker->expected_fps;
72 uint64_t lag_threshold_ns = expected_interval_ns + (expected_interval_ns / 2); // 50% over expected
73
74 // Log error if frame arrived too late (only after first frame)
75 if (tracker->frame_count > 1 && frame_interval_ns > lag_threshold_ns) {
76 const char *context_str = context ? context : "Frame";
77
78 // Convert to milliseconds for display (but calculations stay in nanoseconds)
79 double late_ms = time_ns_to_us(frame_interval_ns - expected_interval_ns) / 1000.0;
80 double expected_ms = time_ns_to_us(expected_interval_ns) / 1000.0;
81 double actual_ms = time_ns_to_us(frame_interval_ns) / 1000.0;
82 double actual_fps = 1e9 / (double)frame_interval_ns;
83
84 log_lag_event(tracker->tracker_name, context_str, late_ms, expected_ms, actual_ms, actual_fps);
85 }
86
87 // Report FPS every report_interval_ns
88 uint64_t elapsed_ns = time_elapsed_ns(tracker->last_fps_report_ns, current_time_ns);
89
90 if (elapsed_ns >= tracker->report_interval_ns) {
91 double elapsed_seconds = time_ns_to_s(elapsed_ns);
92 double actual_fps = (double)tracker->frame_count / elapsed_seconds;
93 log_fps_report(tracker->tracker_name, actual_fps, tracker->frame_count, elapsed_seconds);
94
95 // Reset counters for next interval
96 tracker->frame_count = 0;
97 tracker->last_fps_report_ns = current_time_ns;
98 }
99}
⚙️ Common definitions, error codes, macros, and types shared throughout the application
⏱️ FPS tracking utility for monitoring frame throughput across all threads
void fps_init_with_interval(fps_t *tracker, int expected_fps, const char *name, uint64_t report_interval_ns)
Initialize FPS tracker with custom report interval.
Definition fps.c:37
void fps_frame_ns(fps_t *tracker, uint64_t current_time_ns, const char *context)
Track a frame and detect lag conditions (nanosecond version - PRIMARY)
Definition fps.c:52
unsigned long long uint64_t
Definition common.h:59
void fps_init(fps_t *tracker, int expected_fps, const char *name)
Initialize FPS tracker.
Definition fps.c:32
#define NS_PER_SEC_INT
Definition time.h:157
#define NS_PER_MS_INT
Definition time.h:156
uint64_t time_elapsed_ns(uint64_t start_ns, uint64_t end_ns)
Calculate elapsed time with wraparound safety.
Definition util/time.c:150
#define US_PER_MS_INT
Definition time.h:160
📝 Logging API with multiple log levels and terminal output control
#define log_warn_every(interval_us, fmt,...)
Rate-limited WARN logging.
Definition log/log.h:708
#define log_dev_every(interval_us, fmt,...)
Rate-limited DEV logging.
Definition log/log.h:699
FPS tracking state.
Definition fps.h:52
const char * tracker_name
Definition fps.h:58
uint64_t frame_count
Definition fps.h:53
uint64_t report_interval_ns
Definition fps.h:57
uint64_t last_frame_time_ns
Definition fps.h:55
int expected_fps
Definition fps.h:56
uint64_t last_fps_report_ns
Definition fps.h:54
⏱️ High-precision timing utilities using sokol_time.h and uthash