summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2025-04-07 02:37:35 +0200
committerMitya Selivanov <automainint@guattari.tech>2025-04-07 02:37:35 +0200
commit0150f3e65a00894e5ed2d4fe304311e47c835424 (patch)
tree6b3477f905fcdbcae15ef18802e9c3ed5554e407
parent1b72dceae8427a7e43bef44c7dbb47f53c0cb865 (diff)
downloadreduced_system_layer-0150f3e65a00894e5ed2d4fe304311e47c835424.zip
Simple profiling
-rwxr-xr-xreduced_system_layer.c170
1 files changed, 166 insertions, 4 deletions
diff --git a/reduced_system_layer.c b/reduced_system_layer.c
index 6473039..acd8cc6 100755
--- a/reduced_system_layer.c
+++ b/reduced_system_layer.c
@@ -53,7 +53,6 @@
#/ + [x] Requests cache
#/ + [x] Global anti-aliasing
#/ + [x] Fill triangles
-#/ - Profiling
#/ - Examples
#/ - Conway's Game of Life
#/ - Julia Set
@@ -139,6 +138,7 @@
#/ - Testing
#/ - Stackless coroutines
#/ - Allocator
+#/ - Profiling
#/ - Graphics
#/ - Font
#/ - Adaptive resolution
@@ -716,6 +716,11 @@ i64 network_send(u16 slot, Network_Address address, i64 size, u8 *data, u16 *loc
void dynamic_library_open (u16 slot, c8 *name);
void *dynamic_library_get_proc_address(u16 slot, c8 *proc);
+// Profiling
+void PROFILER_init(u32 slot, c8 *name);
+void PROFILER_begin(u32 slot);
+void PROFILER_end(u32 slot);
+
// NOTE: This will shutdown main window, networking, audio,
// and close all opened dynamic libraries.
// If g_platform.graceful_shutdown is 0, this does nothing.
@@ -748,6 +753,13 @@ extern Platform g_platform;
#ifndef REDUCED_SYSTEM_LAYER_IMPL_GUARD_
#define REDUCED_SYSTEM_LAYER_IMPL_GUARD_
+enum {
+ PROFILE_DOWNSCALE,
+ PROFILE_RESIZE,
+ PROFILE_WAITING,
+ PROFILE_FRAME,
+};
+
// ----------------------------------------------------------------
static void mem_set_(void *dst, u8 x, i64 size) {
@@ -1253,8 +1265,11 @@ static i64 _frame_duration [NUM_FRAMES_AVERAGED] = {0};
void run_main_window_event_loop(void) {
init_main_window();
#if !defined(__wasm__)
- while (!g_platform.done)
+ while (!g_platform.done) {
+ PROFILER_begin(PROFILE_FRAME);
update_and_render_frame();
+ PROFILER_end(PROFILE_FRAME);
+ }
shutdown_all_systems();
#endif
}
@@ -1461,6 +1476,117 @@ void resize_dynamic_array_capacity(i64 *num, i64 *capacity, void **data, i64 ele
// ================================================================
//
+// Profiling
+//
+// ================================================================
+
+typedef struct {
+ c8 *name;
+ i64 count;
+ i64 time_sec;
+ i64 time_nsec;
+ i64 begin_sec;
+ i64 begin_nsec;
+} Profiler_Slot_;
+
+i64 _profiler_num_slots = 0;
+Profiler_Slot_ *_profiler_slots = NULL;
+
+void PROFILER_init(u32 slot, c8 *name) {
+ if ((i64) (u64) slot >= _profiler_num_slots)
+ resize_dynamic_array_exact(&_profiler_num_slots, (void **) &_profiler_slots, sizeof *_profiler_slots, (i64) (u64) slot + 1);
+
+ if ((i64) (u64) slot >= _profiler_num_slots) {
+ LOG_ERROR("Invalid slot: %d", (i32) slot);
+ return;
+ }
+
+ mem_set_(_profiler_slots + slot, 0, sizeof *_profiler_slots);
+ _profiler_slots[slot].name = name;
+}
+
+void PROFILER_begin(u32 slot) {
+ if ((i64) (u64) slot >= _profiler_num_slots) {
+ LOG_ERROR("Invalid slot: %d", (i32) slot);
+ return;
+ }
+
+ if (_profiler_slots[slot].count < 0) {
+ LOG_ERROR("Sanity");
+ return;
+ }
+
+ ++_profiler_slots[slot].count;
+ if (_profiler_slots[slot].count != 1)
+ return;
+
+ current_utc_time_in_sec_and_nsec(
+ &_profiler_slots[slot].begin_sec,
+ &_profiler_slots[slot].begin_nsec
+ );
+}
+
+static void normalize_time_(i64 *sec, i64 *nsec) {
+ if (sec == NULL || nsec == NULL) {
+ LOG_ERROR("Sanity");
+ return;
+ }
+
+ if (*nsec < 0) {
+ *sec -= 1;
+ *nsec += 1000000000;
+ }
+
+ if (*nsec >= 1000000000) {
+ *sec += *nsec / 1000000000;
+ *nsec = *nsec % 1000000000;
+ }
+}
+
+void PROFILER_end(u32 slot) {
+ if ((i64) (u64) slot >= _profiler_num_slots) {
+ LOG_ERROR("Invalid slot: %d", (i32) slot);
+ return;
+ }
+
+ if (_profiler_slots[slot].count <= 0) {
+ LOG_ERROR("Sanity");
+ return;
+ }
+
+ --_profiler_slots[slot].count;
+ if (_profiler_slots[slot].count != 0)
+ return;
+
+ i64 sec, nsec;
+ current_utc_time_in_sec_and_nsec(&sec, &nsec);
+
+ sec -= _profiler_slots[slot].begin_sec;
+ nsec -= _profiler_slots[slot].begin_nsec;
+
+ normalize_time_(&sec, &nsec);
+
+ for (i64 i = 0; i < _profiler_num_slots; ++i) {
+ if (_profiler_slots[i].count == 0)
+ continue;
+
+ _profiler_slots[i].time_sec -= sec;
+ _profiler_slots[i].time_nsec -= nsec;
+
+ normalize_time_(&_profiler_slots[i].time_sec, &_profiler_slots[i].time_nsec);
+ }
+
+ _profiler_slots[slot].begin_sec = 0;
+ _profiler_slots[slot].begin_nsec = 0;
+
+ _profiler_slots[slot].time_sec += sec;
+ _profiler_slots[slot].time_nsec += nsec;
+
+ normalize_time_(&_profiler_slots[slot].time_sec, &_profiler_slots[slot].time_nsec);
+}
+
+// ================================================================
+//
// Platform
//
// ================================================================
@@ -1643,6 +1769,8 @@ static void convert_pixels_for_window_(void) {
return;
}
+ PROFILER_begin(PROFILE_DOWNSCALE);
+
f32 k = 1.f / (aa_scale * aa_scale);
vec4_f32 *s = g_platform.pixels;
u32 *d = _internal_pixels;
@@ -1671,6 +1799,8 @@ static void convert_pixels_for_window_(void) {
for (; d < d_end; ++d, ++im)
*d = rgb_u32_from_f32_((vec3_f32) { .x = im->x * k, .y = im->y * k, .z = im->z * k, }) | 0xff000000;
}
+
+ PROFILER_end(PROFILE_DOWNSCALE);
}
// Resize internal pixel buffer in-place.
@@ -1692,6 +1822,8 @@ static void convert_pixels_for_window_(void) {
return;
}
+ PROFILER_begin(PROFILE_RESIZE);
+
f64 di = ((f64) src_width) / dst_width;
f64 dj = ((f64) src_height) / dst_height;
@@ -1720,6 +1852,8 @@ static void convert_pixels_for_window_(void) {
*d = s[(i64) ii];
}
}
+
+ PROFILER_end(PROFILE_RESIZE);
}
}
@@ -1781,9 +1915,14 @@ void dynamic_library_open(u16 slot, c8 *name) {
return;
}
- if (slot >= _dynamic_libraries.num_slots)
+ if ((i64) (u64) slot >= _dynamic_libraries.num_slots)
resize_dynamic_array_exact(&_dynamic_libraries.num_slots, (void **) &_dynamic_libraries.slots, sizeof *_dynamic_libraries.slots, (i64) slot + 1);
+ if ((i64) (u64) slot >= _dynamic_libraries.num_slots) {
+ LOG_ERROR("Invalid slot: %d", (i32) slot);
+ return;
+ }
+
if (_dynamic_libraries.slots[slot].handle != NULL) {
dlclose(_dynamic_libraries.slots[slot].handle);
_dynamic_libraries.slots[slot].handle = NULL;
@@ -1801,7 +1940,7 @@ void dynamic_library_open(u16 slot, c8 *name) {
}
void *dynamic_library_get_proc_address(u16 slot, c8 *proc) {
- if (slot >= _dynamic_libraries.num_slots) {
+ if ((i64) (u64) slot >= _dynamic_libraries.num_slots) {
LOG_ERROR("Invalid slot: %d", (i32) slot);
return NULL;
}
@@ -1948,6 +2087,11 @@ static void network_cleanup_(void) {
b8 network_open(u16 slot, Network_Address address, u16 *local_port) {
network_init_(slot);
+ if ((i64) (u64) slot >= _num_sockets) {
+ LOG_ERROR("Invalid slot: %d", (i32) slot);
+ return 0;
+ }
+
b8 change_address =
!_sockets[slot].ready
|| _sockets[slot].address.protocol != address.protocol
@@ -2940,6 +3084,11 @@ void put_image_to_main_window_(void) {
}
void init_main_window(void) {
+ PROFILER_init(PROFILE_DOWNSCALE, "Downscale anti-aliasing");
+ PROFILER_init(PROFILE_RESIZE, "Resize in-place");
+ PROFILER_init(PROFILE_WAITING, "Waiting for events");
+ PROFILER_init(PROFILE_FRAME, "Update frame");
+
for (i64 i = 0; i < NUM_FRAMES_AVERAGED; ++i)
_frame_duration[i] = (MIN_FRAME_DURATION + MAX_FRAME_DURATION) / 2;
@@ -3165,6 +3314,16 @@ void init_main_window(void) {
}
void shutdown_all_systems(void) {
+ if (_profiler_num_slots > 0) {
+ printf("\nPROFILER REPORT\n\n");
+ for (i64 i = 0; i < _profiler_num_slots; ++i) {
+ if (_profiler_slots[i].name == NULL)
+ continue;
+ printf("%-31s %lld.%09lld\n", _profiler_slots[i].name, _profiler_slots[i].time_sec, _profiler_slots[i].time_nsec);
+ }
+ printf("\n");
+ }
+
g_platform.done = 1;
if (!g_platform.graceful_shutdown)
@@ -3725,6 +3884,8 @@ i32 handle_main_window_events(void) {
}
i32 wait_main_window_events(void) {
+ PROFILER_begin(PROFILE_WAITING);
+
i32 num_events = 0;
for (;;) {
@@ -3734,6 +3895,7 @@ i32 wait_main_window_events(void) {
usleep(0);
}
+ PROFILER_end(PROFILE_WAITING);
return num_events;
}