diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2025-04-07 05:53:55 +0200 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2025-04-07 05:53:55 +0200 |
commit | 3a9715a7a5cc03fef0f99064601112c093ddaae1 (patch) | |
tree | 2ce1d676b04211a1bc8995dcffe073d3f78fcf56 | |
parent | 0150f3e65a00894e5ed2d4fe304311e47c835424 (diff) | |
download | reduced_system_layer-3a9715a7a5cc03fef0f99064601112c093ddaae1.zip |
Refactor
-rw-r--r-- | examples/screenshot.c | 2 | ||||
-rwxr-xr-x | reduced_system_layer.c | 343 |
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 |