diff options
author | Mitya Selivanov <automainint@guattari.tech> | 2025-02-09 09:46:39 +0100 |
---|---|---|
committer | Mitya Selivanov <automainint@guattari.tech> | 2025-02-09 09:46:39 +0100 |
commit | e5b0ce30cb80abeeb1aeb0c510c095084af883ce (patch) | |
tree | f5f3e857a933da7e4396be188295afb4482100a2 | |
parent | a8d7b8b5d90b0251f5e37e98d079c1d88498f697 (diff) | |
download | reduced_system_layer-e5b0ce30cb80abeeb1aeb0c510c095084af883ce.zip |
Buffers (work in progress)
-rwxr-xr-x | reduced_system_layer.c | 374 |
1 files changed, 152 insertions, 222 deletions
diff --git a/reduced_system_layer.c b/reduced_system_layer.c index b1bb8ce..50f676f 100755 --- a/reduced_system_layer.c +++ b/reduced_system_layer.c @@ -257,43 +257,6 @@ i32 main(i32 argc, c8 **argv); #define MEMORY_CHUNK_SIZE 1024 #endif -// ---------------------------------------------------------------- -// TEMP: Static buffers. - -#ifndef MAX_NUM_PIXELS -#define MAX_NUM_PIXELS (4 * 1024 * 1024) -#endif - -#ifndef MAX_INPUT_SIZE -#define MAX_INPUT_SIZE 256 -#endif - -#ifndef MAX_CLIPBOARD_SIZE -#define MAX_CLIPBOARD_SIZE (2 * 1024 * 1024) -#endif - -#ifndef MAX_NUM_SOCKETS -#if defined(__wasm__) -#define MAX_NUM_SOCKETS 0 -#else -#define MAX_NUM_SOCKETS 64 -#endif -#endif - -#ifndef MAX_NUM_KEYS -#define MAX_NUM_KEYS 512 -#endif - -#ifndef MAX_NUM_PRIMARY_SOUND_FRAMES -#define MAX_NUM_PRIMARY_SOUND_FRAMES (4 * 2 * 44100) -#endif - -#ifndef DROP_FILES_BUFFER_SIZE -#define DROP_FILES_BUFFER_SIZE (8 * 1024 * 1024) -#endif - -// ---------------------------------------------------------------- - #ifndef MIN_PIXEL_SIZE #define MIN_PIXEL_SIZE (1.0) #endif @@ -333,6 +296,10 @@ i32 main(i32 argc, c8 **argv); #define AVERAGE_FRAME_BIAS (0.02) #endif +#ifndef MAX_NUM_KEYS +#define MAX_NUM_KEYS 512 +#endif + #ifndef NUM_PRIMARY_SOUND_CHANNELS #define NUM_PRIMARY_SOUND_CHANNELS 2 #endif @@ -341,6 +308,10 @@ i32 main(i32 argc, c8 **argv); #define PRIMARY_SOUND_SAMPLE_RATE 44100 #endif +#ifndef MAX_NUM_PRIMARY_SOUND_FRAMES +#define MAX_NUM_PRIMARY_SOUND_FRAMES (10 * PRIMARY_SOUND_SAMPLE_RATE * NUM_PRIMARY_SOUND_CHANNELS) +#endif + #ifndef PRIMARY_SOUND_AVAIL_MIN #define PRIMARY_SOUND_AVAIL_MIN 512 #endif @@ -627,21 +598,16 @@ typedef struct { i32 frame_width; i32 frame_height; f64 pixel_size; - b8 exact_resolution; - b8 graceful_shutdown; - - b8 done; - b8 has_focus; - b8 has_cursor; - b8 files_dragged; - b8 files_dropped; + b8 exact_resolution : 1; + b8 graceful_shutdown : 1; + + b8 done : 1; + b8 has_focus : 1; + b8 has_cursor : 1; + b8 files_dragged : 1; + b8 files_dropped : 1; i32 real_width; i32 real_height; - i64 input_size; - i64 clipboard_text_len; - i64 clipboard_image_width; - i64 clipboard_image_height; - i64 num_clipboard_sound_samples; i32 cursor_x; i32 cursor_y; i32 cursor_dx; @@ -650,17 +616,30 @@ typedef struct { f64 wheel_dy; i64 num_sound_samples_elapsed; - i64 num_drop_files; + i64 num_pixels; + i64 sketch_len; + i64 input_len; + i64 num_drop_files; + i64 clipboard_text_len; + i64 clipboard_image_width; + i64 clipboard_image_height; + i64 clipboard_image_len; + i64 num_clipboard_sound_samples; + i64 clipboard_sound_len; + + i64 pixels_capacity; + i64 input_capacity; + + vec4_f32 *pixels; + vec4_f32 *sketch; + Input_Key *input; Drop_File *drop_files; + c8 *clipboard_text; + vec4_f32 *clipboard_image; + f32 *clipboard_sound; - vec4_f32 pixels [MAX_NUM_PIXELS]; - vec4_f32 sketch [MAX_NUM_PIXELS]; - Input_Key input [MAX_INPUT_SIZE]; - c8 clipboard_text [MAX_CLIPBOARD_SIZE]; - vec4_f32 clipboard_image [MAX_CLIPBOARD_SIZE]; - f32 clipboard_sound [MAX_CLIPBOARD_SIZE]; - b8 key_down [MAX_NUM_KEYS]; - b8 key_pressed [MAX_NUM_KEYS]; + b8 key_down [MAX_NUM_KEYS]; + b8 key_pressed [MAX_NUM_KEYS]; i64 memory_buffer_size; u8 *memory_buffer; @@ -733,14 +712,15 @@ extern Platform g_platform; 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 i64 _sound_clock_time = 0; +static i64 _sound_clock_carry = 0; +static i64 _sound_position = 0; +static i64 _frame_index = 0; +static i64 _drop_files_buffer_len = 0; +static u8 *_drop_files_buffer = NULL; -static f32 _sound_ring [MAX_NUM_PRIMARY_SOUND_FRAMES] = {0}; -static u8 _drop_files_buffer [DROP_FILES_BUFFER_SIZE] = {0}; -static i64 _frame_duration [NUM_FRAMES_AVERAGED] = {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(); @@ -750,6 +730,16 @@ void run_main_window_event_loop(void) { #endif } +static void mem_set_(void *dst, u8 x, u32 size) { + for (u32 i = 0; i < size; ++i) + ((u8 *) dst)[i] = x; +} + +static void mem_cpy_(void *dst, void *src, u32 size) { + for (u32 i = 0; i < size; ++i) + ((u8 *) dst)[i] = ((u8 *) src)[i]; +} + // ================================================================ // // Log @@ -896,7 +886,12 @@ void *memory_buffer_allocate(i64 size, i64 alignment, i64 previous_size, void *p return dst; } -void memory_buffer_wrap(i64 *num, void **data, i64 element_size, i64 new_num) { +void wrap_dynamic_array_exact(i64 *num, void **data, i64 element_size, i64 new_num) { + if (num == NULL || data == NULL) { + LOG_ERROR("Sanity"); + return; + } + void *new_data = memory_buffer_allocate( new_num * element_size, element_size, @@ -911,6 +906,18 @@ void memory_buffer_wrap(i64 *num, void **data, i64 element_size, i64 new_num) { *data = new_data; } +void wrap_dynamic_array_capacity(i64 *num, i64 *capacity, void **data, i64 element_size, i64 new_num) { + if (num == NULL || capacity == NULL || data == NULL) { + LOG_ERROR("Sanity"); + return; + } + + if (new_num > *capacity) + wrap_dynamic_array_exact(capacity, data, element_size, new_num); + + *num = new_num; +} + // ================================================================ // // BLAKE2B @@ -970,16 +977,6 @@ static u8 blake2b_sigma[12][16] = { { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } }; -static void mem_set_(void *dst, u8 x, u32 size) { - for (u32 i = 0; i < size; ++i) - ((u8 *) dst)[i] = x; -} - -static void mem_cpy_(void *dst, void *src, u32 size) { - for (u32 i = 0; i < size; ++i) - ((u8 *) dst)[i] = ((u8 *) src)[i]; -} - static b8 native_little_endian_(void) { return ((u8 *) &(u32) { 1 })[0] == 1; } @@ -1504,35 +1501,20 @@ static i64 sound_samples_elapsed_(void) { } static void drop_files_clean_(void) { - g_platform.files_dragged = 0; - g_platform.files_dropped = 0; - g_platform.num_drop_files = 0; - g_platform.drop_files = NULL; -} + g_platform.files_dragged = 0; + g_platform.files_dropped = 0; -static i64 align_size_(i64 x) { - return (x + 7) & ~7ll; -} - -static i64 drop_files_data_size_(i64 num) { - if (num > g_platform.num_drop_files) { - LOG_ERROR("Sanity"); - return 0; + for (i64 i = 0; i < g_platform.num_drop_files; ++i) { + wrap_dynamic_array_exact(&g_platform.drop_files[i].name_len, (void **) &g_platform.drop_files[i].name, 1, 0); + wrap_dynamic_array_exact(&g_platform.drop_files[i].data_size, (void **) &g_platform.drop_files[i].data, 1, 0); } - if (num > 0 && g_platform.drop_files == NULL) { - LOG_ERROR("Sanity"); - return 0; - } - - i64 data_size = 0; - - for (i64 i = 0; i < num; ++i) - data_size += - align_size_(g_platform.drop_files[i].name_len) + - align_size_(g_platform.drop_files[i].data_size); + wrap_dynamic_array_exact(&g_platform.num_drop_files, (void **) &g_platform.drop_files, sizeof *g_platform.drop_files, 0); + wrap_dynamic_array_exact(&_drop_files_buffer_len, (void **) &_drop_files_buffer, 1, 0); +} - return data_size; +static i64 align_size_(i64 x) { + return (x + 7) & ~7ll; } static void drop_files_set_num_(i64 num) { @@ -1541,55 +1523,11 @@ static void drop_files_set_num_(i64 num) { return; } - i64 available = DROP_FILES_BUFFER_SIZE - drop_files_data_size_(g_platform.num_drop_files); - if (available < num * (i64) sizeof(Drop_File)) - return; - - i64 src_size = (i64) sizeof(Drop_File) * g_platform.num_drop_files; - i64 dst_size = (i64) sizeof(Drop_File) * num; - - u8 *src = _drop_files_buffer + (DROP_FILES_BUFFER_SIZE - src_size); - u8 *dst = _drop_files_buffer + (DROP_FILES_BUFFER_SIZE - num * (i64) sizeof(Drop_File)); + i64 prev_num = g_platform.num_drop_files; - for (i64 i = 0; i < src_size; ++i) - dst[i] = src[i]; - for (i64 i = src_size; i < dst_size; ++i) - dst[i] = 0; + wrap_dynamic_array_exact(&g_platform.num_drop_files, (void **) &g_platform.drop_files, sizeof *g_platform.drop_files, num); - g_platform.num_drop_files = num; - g_platform.drop_files = (Drop_File *) dst; -} - -static void drop_files_empty_after_(i64 index) { - if (g_platform.drop_files == NULL) { - LOG_ERROR("Sanity"); - return; - } - - for (i64 i = index + 1; i < g_platform.num_drop_files; ++i) { - if (g_platform.drop_files[i].name_len != 0) { - LOG_ERROR("Sanity"); - g_platform.drop_files[i].name_len = 0; - } - - if (g_platform.drop_files[i].data_size != 0) { - LOG_ERROR("Sanity"); - g_platform.drop_files[i].data_size = 0; - } - } -} - -static void drop_files_empty_data_after_(i64 index) { - if (g_platform.drop_files == NULL) { - LOG_ERROR("Sanity"); - return; - } - - for (i64 i = index + 1; i < g_platform.num_drop_files; ++i) - if (g_platform.drop_files[i].data_size != 0) { - LOG_ERROR("Sanity"); - g_platform.drop_files[i].data_size = 0; - } + mem_set_(g_platform.drop_files + prev_num, 0, sizeof *g_platform.drop_files * (g_platform.num_drop_files - prev_num)); } static void drop_files_set_name_(i64 index, i64 name_len, c8 *name) { @@ -1598,22 +1536,15 @@ static void drop_files_set_name_(i64 index, i64 name_len, c8 *name) { return; } - drop_files_empty_after_(index); - - i64 offset = drop_files_data_size_(index); - i64 available = DROP_FILES_BUFFER_SIZE - offset - g_platform.num_drop_files * sizeof(Drop_File); - - if (available < name_len + 1) { - LOG_ERROR("Out of memory"); + if (index < 0 || index >= g_platform.num_drop_files) { + LOG_ERROR("Sanity"); return; } - g_platform.drop_files[index].name_len = name_len + 1; - g_platform.drop_files[index].name = (c8 *) _drop_files_buffer + offset; + Drop_File *f = g_platform.drop_files + index; - for (i64 i = 0; i < name_len; ++i) - g_platform.drop_files[index].name[i] = name[i]; - g_platform.drop_files[index].name[name_len] = '\0'; + wrap_dynamic_array_exact(&f->name_len, (void **) &f->name, 1, name_len); + mem_cpy_(f->name, name, f->name_len); } static void drop_files_set_data_(i64 index, i64 data_size) { @@ -1622,20 +1553,14 @@ static void drop_files_set_data_(i64 index, i64 data_size) { return; } - drop_files_empty_data_after_(index); - - g_platform.drop_files[index].data_size = 0; - - i64 offset = drop_files_data_size_(index + 1); - i64 available = DROP_FILES_BUFFER_SIZE - offset - g_platform.num_drop_files * sizeof(Drop_File); - - if (available < data_size) { - LOG_ERROR("Out of memory"); + if (index < 0 || index >= g_platform.num_drop_files) { + LOG_ERROR("Sanity"); return; } - g_platform.drop_files[index].data_size = data_size; - g_platform.drop_files[index].data = _drop_files_buffer + offset; + Drop_File *f = g_platform.drop_files + index; + + wrap_dynamic_array_exact(&f->data_size, (void **) &f->data, 1, data_size); } static i8 pixel_size_update_(i32 real_width, i32 real_height) { @@ -1742,19 +1667,27 @@ typedef struct { IP_Address address; } Socket_Slot; -static b8 _network_ready = 0; -static Socket_Slot _sockets[MAX_NUM_SOCKETS] = {0}; +static b8 _network_ready = 0; +static i64 _num_sockets = 0; +static Socket_Slot *_sockets = NULL; -static void network_init_(void) { - if (_network_ready) - return; +static void network_init_(u16 slot) { + if (!_network_ready) { + signal(SIGPIPE, SIG_IGN); + _network_ready = 1; + } - signal(SIGPIPE, SIG_IGN); - _network_ready = 1; + i64 num = (i64) (u64) slot; + i64 prev_num = _num_sockets; + + if (num > prev_num) { + wrap_dynamic_array_exact(&_num_sockets, (void **) &_sockets, sizeof *_sockets, num); + mem_set_(_sockets + prev_num, 0, num - prev_num); + } } static void network_cleanup_(void) { - for (i64 i = 0; i < MAX_NUM_SOCKETS; ++i) + for (i64 i = 0; i < _num_sockets; ++i) if (_sockets[i].ready) { close(_sockets[i].socket); _sockets[i].ready = 0; @@ -1762,7 +1695,7 @@ static void network_cleanup_(void) { } static b8 network_open_(u16 slot, IP_Address address, u16 *local_port) { - network_init_(); + network_init_(slot); b8 change_address = !_sockets[slot].ready @@ -1838,11 +1771,6 @@ static b8 network_open_(u16 slot, IP_Address address, u16 *local_port) { } i64 network_recv(u16 slot, IP_Address address, i64 size, u8 *data, u16 *local_port, IP_Address *remote_address) { - if (slot >= MAX_NUM_SOCKETS) { - LOG_ERROR("Invalid slot %d.", (i32) (u32) slot); - return 0; - } - if (address.protocol != IPv4_UDP && address.protocol != IPv6_UDP) { LOG_ERROR("Invalid address protocol %d.", (i32) (u32) address.protocol); return 0; @@ -1901,11 +1829,6 @@ i64 network_recv(u16 slot, IP_Address address, i64 size, u8 *data, u16 *local_po } i64 network_send(u16 slot, IP_Address address, i64 size, u8 *data, u16 *local_port) { - if (slot >= MAX_NUM_SOCKETS) { - LOG_ERROR("Invalid slot %d.", (i32) (u32) slot); - return 0; - } - if (address.protocol != IPv4_UDP && address.protocol != IPv6_UDP) { LOG_ERROR("Invalid address protocol %d.", (i32) (u32) address.protocol); return 0; @@ -2728,12 +2651,14 @@ static Atom _text_uri_list = 0; static Window _dnd_source = 0; static b8 _mapped = 0; static b8 _requested_clipboard = 0; +static i64 _pixels_scaled_len = 0; +static u32 * _pixels_scaled = NULL; +static i64 _pixels_internal_len = 0; +static u32 * _pixels_internal = NULL; -static i16 _key_table [MAX_NUM_KEYS] = {0}; -static b8 _key_repeat [MAX_NUM_KEYS] = {0}; -static u32 _pixels_scaled [MAX_NUM_PIXELS] = {0}; -static u32 _pixels_internal [MAX_NUM_PIXELS] = {0}; -static c8 _error_buffer [4096] = {0}; +static i16 _key_table [MAX_NUM_KEYS] = {0}; +static b8 _key_repeat [MAX_NUM_KEYS] = {0}; +static c8 _error_buffer [4096] = {0}; static b8 sub_str_eq_(c8 *a, c8 *b, i64 len) { for (i64 i = 0; i < len; ++i) @@ -3007,11 +2932,12 @@ i32 handle_main_window_events(void) { memset(g_platform.key_pressed, 0, sizeof g_platform.key_pressed); memset(_key_repeat, 0, sizeof _key_repeat); - g_platform.input_size = 0; - g_platform.cursor_dx = 0; - g_platform.cursor_dy = 0; - g_platform.wheel_dx = 0; - g_platform.wheel_dy = 0; + wrap_dynamic_array_capacity(&g_platform.input_len, &g_platform.input_capacity, (void **) &g_platform.input, sizeof *g_platform.input, 0); + + g_platform.cursor_dx = 0; + g_platform.cursor_dy = 0; + g_platform.wheel_dx = 0; + g_platform.wheel_dy = 0; XEvent ev; @@ -3089,9 +3015,12 @@ i32 handle_main_window_events(void) { g_platform.key_down[MOD_SCROLL] = !!(ev.xkey.state & Mod3Mask); g_platform.key_down[MOD_META] = !!(ev.xkey.state & Mod4Mask); - if (g_platform.input_size < MAX_INPUT_SIZE) { + i64 n = g_platform.input_len; + wrap_dynamic_array_capacity(&g_platform.input_len, &g_platform.input_capacity, (void **) &g_platform.input, sizeof *g_platform.input, n + 1); + + if (n < g_platform.input_len) { if (k < 32 || k >= 128) - g_platform.input[g_platform.input_size++] = (Input_Key) { + g_platform.input[n] = (Input_Key) { .ctrl = !!(ev.xkey.state & ControlMask), .shift = !!(ev.xkey.state & ShiftMask), .alt = !!(ev.xkey.state & Mod1Mask), @@ -3106,7 +3035,7 @@ i32 handle_main_window_events(void) { c8 buf[16]; i32 len = Xutf8LookupString(_ic, &ev.xkey, buf, sizeof buf - 1, NULL, NULL); if (len > 0) - g_platform.input[g_platform.input_size++] = (Input_Key) { + g_platform.input[n] = (Input_Key) { .ctrl = !!(ev.xkey.state & ControlMask), .shift = !!(ev.xkey.state & ShiftMask), .alt = !!(ev.xkey.state & Mod1Mask), @@ -3226,7 +3155,7 @@ i32 handle_main_window_events(void) { ev.xselection.requestor, _dnd_selection, 0, - DROP_FILES_BUFFER_SIZE, + g_platform.memory_buffer_size, False, ev.xselection.target, &(Atom) {0}, @@ -3281,7 +3210,7 @@ i32 handle_main_window_events(void) { _window, _clipboard, 0, - MAX_CLIPBOARD_SIZE / 4, + g_platform.memory_buffer_size, False, AnyPropertyType, &(Atom) {0}, @@ -3334,11 +3263,8 @@ i32 handle_main_window_events(void) { if (target_text == None && target_image == None && target_sound == None) _requested_clipboard = 0; } else if (ev.xselection.target == XA_STRING || ev.xselection.target == _text_plain || ev.xselection.target == _utf8_string) { - if (len >= MAX_CLIPBOARD_SIZE) - len = MAX_CLIPBOARD_SIZE - 1; - g_platform.clipboard_text_len = len; - if (len > 0) - memcpy(g_platform.clipboard_text, data, len); + wrap_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'; _requested_clipboard = 0; } else if (ev.xselection.target == _image_bmp) { @@ -3506,7 +3432,7 @@ i32 handle_main_window_events(void) { XWindowAttributes attrs; XGetWindowAttributes(_display, _window, &attrs); - if (attrs.width > 0 && attrs.height > 0 && attrs.width * attrs.height <= MAX_NUM_PIXELS) { + if (attrs.width > 0 && attrs.height > 0) { _image.width = attrs.width; _image.height = attrs.height; _image.bytes_per_line = _image.width * 4; @@ -3539,6 +3465,12 @@ void render_main_window_frame(void) { _mapped = 1; } + i64 num_pixels = g_platform.frame_width * g_platform.frame_height; + if (_pixels_scaled_len < num_pixels) + wrap_dynamic_array_exact(&_pixels_scaled_len, (void **) &_pixels_scaled, sizeof *_pixels_scaled, num_pixels); + if (_pixels_internal_len < num_pixels) + wrap_dynamic_array_exact(&_pixels_internal_len, (void **) &_pixels_internal, sizeof *_pixels_internal, num_pixels); + if (g_platform.frame_width == _image.width && g_platform.frame_height == _image.height) { i64 size = g_platform.frame_width * g_platform.frame_height; for (i64 i = 0; i < size; ++i) @@ -3564,17 +3496,15 @@ void render_main_window_frame(void) { } void write_clipboard_text(i64 size, c8 *data) { - if (size > MAX_CLIPBOARD_SIZE) { - LOG_ERROR("Size is too big %lld.", size); - return; - } - XSetSelectionOwner(_display, _clipboard, _window, CurrentTime); - g_platform.clipboard_text_len = size < MAX_CLIPBOARD_SIZE ? size : MAX_CLIPBOARD_SIZE - 1; - if (g_platform.clipboard_text_len > 0) - memcpy(g_platform.clipboard_text, data, g_platform.clipboard_text_len); - g_platform.clipboard_text[g_platform.clipboard_text_len] = '\0'; + wrap_dynamic_array_exact(&g_platform.clipboard_text_len, (void **) &g_platform.clipboard_text, 1, size + 1); + + i64 len = g_platform.clipboard_text_len - 1; + if (len >= 0) { + mem_cpy_(g_platform.clipboard_text, data, len); + g_platform.clipboard_text[len] = '\0'; + } } b8 x11_screenshot_(i64 max_num_pixels, i64 *width, i64 *height, vec4_f32 *pixels) { @@ -3638,7 +3568,7 @@ void take_screenshot(i64 max_num_pixels, i64 *width, i64 *height, vec4_f32 *pixe *width = 0; *height = 0; - } +} #endif // defined(__linux__) && (ENABLE_X11 || ENABLE_WAYLAND) // ================================================================ |