ogl_beamforming

Ultrasound Beamforming Implemented with OpenGL
git clone anongit@rnpnr.xyz:ogl_beamforming.git
Log | Files | Refs | Feed | Submodules | LICENSE

Commit: 265d5101cec1ac4b68c5919ba87989def6b1f68a
Parent: 3949a765b9b1de627570a9bc4e316950a21647c1
Author: Randy Palamar
Date:   Tue,  1 Apr 2025 06:09:47 -0600

ui: use a dynamic array for region draw stack

This is more robust since its only size constraint is remaining
space in the arena. Also a small initial region stack is allocated
on the stack so in most cases the regions will never even touch
the arena.

Diffstat:
Mui.c | 38+++++++++++++++++---------------------
Mutil.c | 25+++++++++++++++++++++++++
2 files changed, 42 insertions(+), 21 deletions(-)

diff --git a/ui.c b/ui.c @@ -1805,26 +1805,28 @@ draw_layout_variable(BeamformerUI *ui, Variable *var, Rect draw_rect, v2 mouse) static void draw_ui_regions(BeamformerUI *ui, Rect window, v2 mouse) { - struct region_stack_item { + struct region_frame { Variable *var; Rect rect; - } *region_stack; + } init[16]; - TempArena arena_savepoint = begin_temp_arena(&ui->arena); - i32 stack_index = 0; + struct { + struct region_frame *data; + iz count; + iz capacity; + } stack = {init, 0, ARRAY_COUNT(init)}; - region_stack = alloc(&ui->arena, typeof(*region_stack), 256); - region_stack[0].var = ui->regions; - region_stack[0].rect = window; + TempArena arena_savepoint = begin_temp_arena(&ui->arena); - while (stack_index != -1) { - struct region_stack_item *rsi = region_stack + stack_index--; - Rect rect = rsi->rect; - draw_layout_variable(ui, rsi->var, rect, mouse); + *da_push(&ui->arena, &stack) = (struct region_frame){ui->regions, window}; + while (stack.count) { + struct region_frame *top = stack.data + --stack.count; + Rect rect = top->rect; + draw_layout_variable(ui, top->var, rect, mouse); - if (rsi->var->type == VT_UI_REGION_SPLIT) { + if (top->var->type == VT_UI_REGION_SPLIT) { Rect first, second; - RegionSplit *rs = &rsi->var->u.region_split; + RegionSplit *rs = &top->var->u.region_split; switch (rs->direction) { case RSD_VERTICAL: { split_rect_vertical(rect, rs->fraction, &first, &second); @@ -1834,15 +1836,9 @@ draw_ui_regions(BeamformerUI *ui, Rect window, v2 mouse) } break; } - stack_index++; - region_stack[stack_index].var = rs->right; - region_stack[stack_index].rect = second; - stack_index++; - region_stack[stack_index].var = rs->left; - region_stack[stack_index].rect = first; + *da_push(&ui->arena, &stack) = (struct region_frame){rs->right, second}; + *da_push(&ui->arena, &stack) = (struct region_frame){rs->left, first}; } - - ASSERT(stack_index < 256); } end_temp_arena(arena_savepoint); diff --git a/util.c b/util.c @@ -73,6 +73,31 @@ alloc_(Arena *a, iz len, iz align, iz count) return mem_clear(p, 0, count * len); } +enum { DA_INITIAL_CAP = 8 }; + +#define da_push(a, s) \ + ((s)->count == (s)->capacity \ + ? (s)->data = da_push_((a), (s)->data, &(s)->capacity, \ + _Alignof(typeof(*(s)->data)), sizeof(*(s)->data)), \ + (s)->data + (s)->count++ \ + : (s)->data + (s)->count++) + +static void * +da_push_(Arena *a, void *data, iz *capacity, iz align, iz size) +{ + iz cap = *capacity; + if (!data || a->beg != (u8 *)data + cap * size) { + void *copy = alloc_(a, size, align, cap); + if (data) mem_copy(copy, data, cap * size); + data = copy; + } + + iz extend = cap ? cap : DA_INITIAL_CAP; + alloc_(a, size, align, extend); + *capacity = cap + extend; + return data; +} + static Arena sub_arena(Arena *a, iz len, iz align) {