summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitya Selivanov <automainint@guattari.tech>2025-04-07 05:53:55 +0200
committerMitya Selivanov <automainint@guattari.tech>2025-04-07 05:53:55 +0200
commit3a9715a7a5cc03fef0f99064601112c093ddaae1 (patch)
tree2ce1d676b04211a1bc8995dcffe073d3f78fcf56
parent0150f3e65a00894e5ed2d4fe304311e47c835424 (diff)
downloadreduced_system_layer-3a9715a7a5cc03fef0f99064601112c093ddaae1.zip
Refactor
-rw-r--r--examples/screenshot.c2
-rwxr-xr-xreduced_system_layer.c343
2 files changed, 195 insertions, 150 deletions
diff --git a/examples/screenshot.c b/examples/screenshot.c
index 9f10983..2e144ef 100644
--- a/examples/screenshot.c
+++ b/examples/screenshot.c
@@ -11,7 +11,7 @@ vec4_f32 pixels[MAX_NUM_PIXELS] = {0};
void update_and_render_frame(void) {
if (!has_screenshot) {
- take_screenshot(MAX_NUM_PIXELS, &width, &height, pixels);
+ take_screenshot(&width, &height, MAX_NUM_PIXELS, pixels);
has_screenshot = 1;
}
diff --git a/reduced_system_layer.c b/reduced_system_layer.c
index acd8cc6..7e0dcf7 100755
--- a/reduced_system_layer.c
+++ b/reduced_system_layer.c
@@ -701,7 +701,7 @@ void write_clipboard_image(i64 width, i64 height, vec4_f32 *pixels);
void write_clipboard_sound(i8 num_channels, i64 num_samples, f32 *frames);
// Take a screenshot
-void take_screenshot(i64 max_num_pixels, i64 *width, i64 *height, vec4_f32 *pixels);
+void take_screenshot(i64 *width, i64 *height, i64 max_num_pixels, vec4_f32 *pixels);
// Sound
void handle_primary_sound(void);
@@ -745,7 +745,7 @@ extern Platform g_platform;
// ================================================================
//
-// PLATFORM IMPLEMENTATION
+// PLATFORM INDEPENDENT CODE
//
// ================================================================
@@ -753,6 +753,8 @@ extern Platform g_platform;
#ifndef REDUCED_SYSTEM_LAYER_IMPL_GUARD_
#define REDUCED_SYSTEM_LAYER_IMPL_GUARD_
+Platform g_platform = {0};
+
enum {
PROFILE_DOWNSCALE,
PROFILE_RESIZE,
@@ -760,7 +762,11 @@ enum {
PROFILE_FRAME,
};
-// ----------------------------------------------------------------
+// ================================================================
+//
+// Misc.
+//
+// ================================================================
static void mem_set_(void *dst, u8 x, i64 size) {
for (i64 i = 0; i < size; ++i)
@@ -811,7 +817,7 @@ void log_error_impl(i32 file_len, c8 const *file, i32 line, i32 func_len, c8 con
// ================================================================
//
-// BLAKE2B
+// BLAKE2B
//
// ================================================================
@@ -1228,6 +1234,12 @@ i8 utf8_write(c32 c, c8 *buffer) {
return 0;
}
+// ================================================================
+//
+// Colors
+//
+// ================================================================
+
static u32 rgb_u32_from_f32_(vec3_f32 c) {
i32 ir = (i32) floor(c.x * 255. + .5);
i32 ig = (i32) floor(c.y * 255. + .5);
@@ -1249,32 +1261,6 @@ static vec3_f32 rgb_f32_from_u32_(u32 c) {
}
// ================================================================
-
-// FIXME: Move this to separate sections.
-
-Platform g_platform = {0};
-
-static i64 _sound_clock_time = 0;
-static i64 _sound_clock_carry = 0;
-static i64 _sound_position = 0;
-static i64 _frame_index = 0;
-
-static f32 _sound_ring [MAX_NUM_PRIMARY_SOUND_FRAMES] = {0};
-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) {
- PROFILER_begin(PROFILE_FRAME);
- update_and_render_frame();
- PROFILER_end(PROFILE_FRAME);
- }
- shutdown_all_systems();
-#endif
-}
-
-// ================================================================
//
// Memory buffer allocator
//
@@ -1482,6 +1468,7 @@ void resize_dynamic_array_capacity(i64 *num, i64 *capacity, void **data, i64 ele
typedef struct {
c8 *name;
+ i64 amount;
i64 count;
i64 time_sec;
i64 time_nsec;
@@ -1520,6 +1507,8 @@ void PROFILER_begin(u32 slot) {
if (_profiler_slots[slot].count != 1)
return;
+ ++_profiler_slots[slot].amount;
+
current_utc_time_in_sec_and_nsec(
&_profiler_slots[slot].begin_sec,
&_profiler_slots[slot].begin_nsec
@@ -1591,12 +1580,26 @@ void PROFILER_end(u32 slot) {
//
// ================================================================
-static i32 _internal_width = 0;
-static i32 _internal_height = 0;
-static i64 _internal_pixels_len = 0;
-static u32 *_internal_pixels = NULL;
-static i64 _internal_row_len = 0;
-static vec3_f32 *_internal_row = NULL;
+void run_main_window_event_loop(void) {
+ init_main_window();
+#if !defined(__wasm__)
+ while (!g_platform.done) {
+ PROFILER_begin(PROFILE_FRAME);
+ update_and_render_frame();
+ PROFILER_end(PROFILE_FRAME);
+ }
+ shutdown_all_systems();
+#endif
+}
+
+// ================================================================
+//
+// Frame
+//
+// ================================================================
+
+static i64 _frame_index = 0;
+static i64 _frame_duration[NUM_FRAMES_AVERAGED] = {0};
static i64 average_frame_duration_(i64 duration) {
_frame_duration[_frame_index] = duration;
@@ -1621,80 +1624,21 @@ static i64 average_frame_duration_(i64 duration) {
return durs[(i64) ((NUM_FRAMES_AVERAGED - 1) * AVERAGE_FRAME_BIAS)];
}
-static i64 sound_samples_elapsed_(void) {
- if (_sound_clock_time == 0) {
- _sound_clock_time = current_utc_time_in_milliseconds();
- _sound_clock_carry = 0;
- return 0;
- }
-
- i64 time_elapsed = current_utc_time_in_milliseconds() - _sound_clock_time;
- i64 delta = time_elapsed * PRIMARY_SOUND_SAMPLE_RATE + _sound_clock_carry;
- i64 num_samples = delta / 1000;
-
- _sound_clock_time += time_elapsed;
- _sound_clock_carry = delta % 1000;
-
- return num_samples;
-}
-
-static void drop_files_clean_(void) {
- g_platform.files_dragged = 0;
- g_platform.files_dropped = 0;
-
- for (i64 i = 0; i < g_platform.num_drop_files; ++i) {
- resize_dynamic_array_exact(&g_platform.drop_files[i].name_len, (void **) &g_platform.drop_files[i].name, 1, 0);
- resize_dynamic_array_exact(&g_platform.drop_files[i].data_size, (void **) &g_platform.drop_files[i].data, 1, 0);
- }
-
- resize_dynamic_array_exact(&g_platform.num_drop_files, (void **) &g_platform.drop_files, sizeof *g_platform.drop_files, 0);
-}
-
-static void drop_files_set_num_(i64 num) {
- if (num <= g_platform.num_drop_files) {
- LOG_ERROR("Sanity");
- return;
- }
-
- resize_dynamic_array_exact(&g_platform.num_drop_files, (void **) &g_platform.drop_files, sizeof *g_platform.drop_files, num);
-}
-
-static void drop_files_set_name_(i64 index, i64 name_len, c8 *name) {
- if (g_platform.drop_files == NULL) {
- LOG_ERROR("Sanity");
- return;
- }
-
- if (index < 0 || index >= g_platform.num_drop_files) {
- LOG_ERROR("Sanity");
- return;
- }
-
- Drop_File *f = g_platform.drop_files + index;
-
- resize_dynamic_array_exact(&f->name_len, (void **) &f->name, 1, name_len);
- if (name != NULL)
- mem_cpy_(f->name, name, f->name_len);
-}
-
-static void drop_files_set_data_(i64 index, i64 data_size) {
- if (g_platform.drop_files == NULL) {
- LOG_ERROR("Sanity");
- return;
- }
-
- if (index < 0 || index >= g_platform.num_drop_files) {
- LOG_ERROR("Sanity");
- return;
- }
-
- Drop_File *f = g_platform.drop_files + index;
+// ================================================================
+//
+// Graphics
+//
+// ================================================================
- resize_dynamic_array_exact(&f->data_size, (void **) &f->data, 1, data_size);
-}
+static i32 _internal_width = 0;
+static i32 _internal_height = 0;
+static i64 _internal_pixels_len = 0;
+static u32 *_internal_pixels = NULL;
+static i64 _internal_row_len = 0;
+static vec3_f32 *_internal_row = NULL;
-static i8 pixel_size_update_(i64 real_width, i64 real_height) {
- i8 size_changed = 0;
+static b8 pixel_size_update_(i64 real_width, i64 real_height) {
+ b8 size_changed = 0;
if (g_platform.antialiasing_scale <= 0) g_platform.antialiasing_scale = DEFAULT_ANTIALIASING_SCALE;
if (g_platform.pixel_size <= .0) g_platform.pixel_size = DEFAULT_PIXEL_SIZE;
@@ -1739,9 +1683,9 @@ static i8 pixel_size_update_(i64 real_width, i64 real_height) {
}
static void convert_pixels_for_window_(void) {
- i32 aa_scale = g_platform.antialiasing_scale;
+ u32 aa_scale = g_platform.antialiasing_scale;
- if (aa_scale <= 0) {
+ if (aa_scale == 0 || aa_scale > 1024) {
LOG_ERROR("Sanity");
return;
}
@@ -1750,9 +1694,9 @@ static void convert_pixels_for_window_(void) {
//
// FIXME: Check if the scale is 1:1.
{
- i64 dst_width = g_platform.frame_width / aa_scale;
- i64 dst_height = g_platform.frame_height / aa_scale;
- i64 src_width = g_platform.frame_width;
+ u32 dst_width = g_platform.frame_width / aa_scale;
+ u32 dst_height = g_platform.frame_height / aa_scale;
+ u32 src_width = g_platform.frame_width;
if (g_platform.num_pixels < src_width * g_platform.frame_height) {
LOG_ERROR("Sanity");
@@ -1775,10 +1719,10 @@ static void convert_pixels_for_window_(void) {
vec4_f32 *s = g_platform.pixels;
u32 *d = _internal_pixels;
- for (i64 j = 0; j < dst_height; ++j) {
+ for (u32 j = 0; j < dst_height; ++j) {
mem_set_(_internal_row, 0, dst_width * sizeof *_internal_row);
- for (i64 jj = 0; jj < aa_scale; ++jj) {
+ for (u32 jj = 0; jj < aa_scale; ++jj) {
vec3_f32 *im = _internal_row;
vec3_f32 *im_end = im + dst_width;
@@ -1824,34 +1768,31 @@ static void convert_pixels_for_window_(void) {
PROFILER_begin(PROFILE_RESIZE);
- f64 di = ((f64) src_width) / dst_width;
- f64 dj = ((f64) src_height) / dst_height;
-
- if (src_len < dst_len) {
- f64 jj = src_height - dj * .5;
- for (i64 j = dst_height - 1; j >= 0; --j, jj -= dj) {
- if (jj < 0 || jj >= src_height) continue;
- u32 *d_first = _internal_pixels + j * dst_width;
- u32 *d = d_first + dst_width - 1;
- u32 *s = _internal_pixels + (i64) jj * src_width;
- f64 ii = src_width - di * .5;
- if (ii < 0 || ii >= src_width) continue;
- for (; d >= d_first; --d, ii -= di)
- *d = s[(i64) ii];
+ // TODO, PERF: Improve performance.
+
+ u32 x_ratio = (src_width << 16) / dst_width;
+ u32 y_ratio = (src_height << 16) / dst_height;
+
+ if (src_len < dst_len)
+ for (u32 j = dst_height - 1;; --j) {
+ u32 jj_w = ((j * y_ratio) >> 16) * src_width;
+ u32 j_w = j * dst_width;
+ for (u32 i = dst_width - 1;; --i) {
+ u32 ii = (i * x_ratio) >> 16;
+ _internal_pixels[j_w + i] = _internal_pixels[jj_w + ii];
+ if (i == 0) break;
+ }
+ if (j == 0) break;
}
- } else {
- f64 jj = dj * .5;
- for (i64 j = 0; j < dst_height; ++j, jj += dj) {
- if (jj < 0 || jj >= src_height) continue;
- u32 *d = _internal_pixels + j * dst_width;
- u32 *d_end = d + dst_width;
- u32 *s = _internal_pixels + (i64) jj * src_width;
- f64 ii = di * .5;
- if (ii < 0 || ii >= src_width) continue;
- for (; d < d_end; ++d, ii += di)
- *d = s[(i64) ii];
+ else
+ for (u32 j = 0; j < dst_height; ++j) {
+ u32 jj_w = ((j * y_ratio) >> 16) * src_width;
+ u32 j_w = j * dst_width;
+ for (u32 i = 0; i < dst_width; ++i) {
+ u32 ii = (i * x_ratio) >> 16;
+ _internal_pixels[j_w + i] = _internal_pixels[jj_w + ii];
+ }
}
- }
PROFILER_end(PROFILE_RESIZE);
}
@@ -1877,6 +1818,102 @@ static void cleanup_pixel_buffers_(void) {
resize_dynamic_array_exact(&g_platform.num_pixels, (void **) &g_platform.pixels, sizeof *g_platform.pixels, 0);
}
+// ================================================================
+//
+// Sound
+//
+// ================================================================
+
+static i64 _sound_clock_time = 0;
+static i64 _sound_clock_carry = 0;
+static i64 _sound_position = 0;
+
+static f32 _sound_ring[MAX_NUM_PRIMARY_SOUND_FRAMES] = {0};
+
+static i64 sound_samples_elapsed_(void) {
+ if (_sound_clock_time == 0) {
+ _sound_clock_time = current_utc_time_in_milliseconds();
+ _sound_clock_carry = 0;
+ return 0;
+ }
+
+ i64 time_elapsed = current_utc_time_in_milliseconds() - _sound_clock_time;
+ i64 delta = time_elapsed * PRIMARY_SOUND_SAMPLE_RATE + _sound_clock_carry;
+ i64 num_samples = delta / 1000;
+
+ _sound_clock_time += time_elapsed;
+ _sound_clock_carry = delta % 1000;
+
+ return num_samples;
+}
+
+// ================================================================
+//
+// Drop files
+//
+// ================================================================
+
+static void drop_files_clean_(void) {
+ g_platform.files_dragged = 0;
+ g_platform.files_dropped = 0;
+
+ for (i64 i = 0; i < g_platform.num_drop_files; ++i) {
+ resize_dynamic_array_exact(&g_platform.drop_files[i].name_len, (void **) &g_platform.drop_files[i].name, 1, 0);
+ resize_dynamic_array_exact(&g_platform.drop_files[i].data_size, (void **) &g_platform.drop_files[i].data, 1, 0);
+ }
+
+ resize_dynamic_array_exact(&g_platform.num_drop_files, (void **) &g_platform.drop_files, sizeof *g_platform.drop_files, 0);
+}
+
+static void drop_files_set_num_(i64 num) {
+ if (num <= g_platform.num_drop_files) {
+ LOG_ERROR("Sanity");
+ return;
+ }
+
+ resize_dynamic_array_exact(&g_platform.num_drop_files, (void **) &g_platform.drop_files, sizeof *g_platform.drop_files, num);
+}
+
+static void drop_files_set_name_(i64 index, i64 name_len, c8 *name) {
+ if (g_platform.drop_files == NULL) {
+ LOG_ERROR("Sanity");
+ return;
+ }
+
+ if (index < 0 || index >= g_platform.num_drop_files) {
+ LOG_ERROR("Sanity");
+ return;
+ }
+
+ Drop_File *f = g_platform.drop_files + index;
+
+ resize_dynamic_array_exact(&f->name_len, (void **) &f->name, 1, name_len);
+ if (name != NULL)
+ mem_cpy_(f->name, name, f->name_len);
+}
+
+static void drop_files_set_data_(i64 index, i64 data_size) {
+ if (g_platform.drop_files == NULL) {
+ LOG_ERROR("Sanity");
+ return;
+ }
+
+ if (index < 0 || index >= g_platform.num_drop_files) {
+ LOG_ERROR("Sanity");
+ return;
+ }
+
+ Drop_File *f = g_platform.drop_files + index;
+
+ resize_dynamic_array_exact(&f->data_size, (void **) &f->data, 1, data_size);
+}
+
+// ================================================================
+//
+// Clipboard
+//
+// ================================================================
+
static void store_clipboard_text_(i64 size, c8 *data) {
if (size < 0 || data == NULL)
return;
@@ -1992,6 +2029,10 @@ void *dynamic_library_get_proc_address(u16 slot, c8 *proc) {
// ================================================================
//
+// PLATFORM-SPECIFIC CODE
+//
+// ================================================================
+//
// Unix
//
// ================================================================
@@ -2855,7 +2896,7 @@ b8 check_format_(i32 format) {
return 0;
}
-b8 wayland_screenshot_(i64 max_num_pixels, i64 *width, i64 *height, vec4_f32 *pixels) {
+b8 wayland_screenshot_(i64 *width, i64 *height, i64 max_num_pixels, vec4_f32 *pixels) {
b8 ok = 0;
WL_State_ state = { .ok = 1, };
@@ -3319,7 +3360,9 @@ void shutdown_all_systems(void) {
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);
+ f64 k = 1. / _profiler_slots[i].amount;
+ f64 f = ((f64) _profiler_slots[i].time_sec) * k + ((f64 )_profiler_slots[i].time_nsec * .000000001) * k;
+ printf("%-31s %3lld.%09lld / %4lld = %g\n", _profiler_slots[i].name, _profiler_slots[i].time_sec, _profiler_slots[i].time_nsec, _profiler_slots[i].amount, f);
}
printf("\n");
}
@@ -3700,8 +3743,10 @@ i32 handle_main_window_events(void) {
} else if (ev.xselection.target == XA_STRING || ev.xselection.target == _text_plain || ev.xselection.target == _utf8_string) {
if (g_platform.enable_clipboard_text) {
resize_dynamic_array_exact(&g_platform.clipboard_text_len, (void **) &g_platform.clipboard_text, 1, len + 1);
- mem_cpy_(g_platform.clipboard_text, data, len);
- g_platform.clipboard_text[len] = '\0';
+ if (g_platform.clipboard_text_len == len + 1) {
+ mem_cpy_(g_platform.clipboard_text, data, len);
+ g_platform.clipboard_text[len] = '\0';
+ }
}
_requested_clipboard = 0;
} else if (ev.xselection.target == _image_bmp) {
@@ -3940,7 +3985,7 @@ b8 x11_get_root_(void) {
return 1;
}
-b8 x11_screenshot_(i64 max_num_pixels, i64 *width, i64 *height, vec4_f32 *pixels) {
+b8 x11_screenshot_(i64 *width, i64 *height, i64 max_num_pixels, vec4_f32 *pixels) {
if (_display == NULL) {
LOG_ERROR("No display.");
return 0;
@@ -3989,19 +4034,19 @@ b8 x11_screenshot_(i64 max_num_pixels, i64 *width, i64 *height, vec4_f32 *pixels
// ================================================================
#if defined(__linux__) && (ENABLE_X11 || ENABLE_WAYLAND)
-void take_screenshot(i64 max_num_pixels, i64 *width, i64 *height, vec4_f32 *pixels) {
+void take_screenshot(i64 *width, i64 *height, i64 max_num_pixels, vec4_f32 *pixels) {
if (width == NULL || height == NULL) {
LOG_ERROR("Invalid arguments.");
return;
}
#if ENABLE_X11
- if (x11_screenshot_(max_num_pixels, width, height, pixels))
+ if (x11_screenshot_(width, height, max_num_pixels, pixels))
return;
#endif
#if ENABLE_WAYLAND
- if (wayland_screenshot_(max_num_pixels, width, height, pixels))
+ if (wayland_screenshot_(width, height, max_num_pixels, pixels))
return;
#endif