eliminate recursive version of final ui layout position pass

This commit is contained in:
Ryan Fleury
2025-04-25 08:29:44 -07:00
parent fe46e61acb
commit e0ba1155e8
2 changed files with 137 additions and 145 deletions
+42 -50
View File
@@ -1272,11 +1272,11 @@ ui_end_build(void)
root->rect = new_root_rect;
for(Axis2 axis = (Axis2)0; axis < Axis2_COUNT; axis = (Axis2)(axis + 1))
{
ui_calc_sizes_standalone__in_place_rec(root, axis);
ui_calc_sizes_upwards_dependent__in_place_rec(root, axis);
ui_calc_sizes_downwards_dependent__in_place_rec(root, axis);
ui_layout_enforce_constraints__in_place_rec(root, axis);
ui_layout_position__in_place_rec(root, axis);
ui_calc_sizes_standalone__in_place(root, axis);
ui_calc_sizes_upwards_dependent__in_place(root, axis);
ui_calc_sizes_downwards_dependent__in_place(root, axis);
ui_layout_enforce_constraints__in_place(root, axis);
ui_layout_position__in_place(root, axis);
}
}
}
@@ -1613,7 +1613,7 @@ ui_end_build(void)
}
internal void
ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis)
ui_calc_sizes_standalone__in_place(UI_Box *root, Axis2 axis)
{
ProfBeginFunction();
for(UI_Box *b = root; !ui_box_is_nil(b); b = ui_box_rec_df_pre(b, root).next)
@@ -1637,7 +1637,7 @@ ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis)
}
internal void
ui_calc_sizes_upwards_dependent__in_place_rec(UI_Box *root, Axis2 axis)
ui_calc_sizes_upwards_dependent__in_place(UI_Box *root, Axis2 axis)
{
ProfBeginFunction();
for(UI_Box *b = root; !ui_box_is_nil(b); b = ui_box_rec_df_pre(b, root).next)
@@ -1673,7 +1673,7 @@ ui_calc_sizes_upwards_dependent__in_place_rec(UI_Box *root, Axis2 axis)
}
internal void
ui_calc_sizes_downwards_dependent__in_place_rec(UI_Box *root, Axis2 axis)
ui_calc_sizes_downwards_dependent__in_place(UI_Box *root, Axis2 axis)
{
ProfBeginFunction();
UI_BoxRec rec = {0};
@@ -1710,19 +1710,17 @@ ui_calc_sizes_downwards_dependent__in_place_rec(UI_Box *root, Axis2 axis)
}
internal void
ui_layout_enforce_constraints__in_place_rec(UI_Box *root, Axis2 axis)
ui_layout_enforce_constraints__in_place(UI_Box *root, Axis2 axis)
{
ProfBeginFunction();
Temp scratch = scratch_begin(0, 0);
// NOTE(rjf): The "layout axis" is the direction in which children
// of some node are intended to be laid out.
//- rjf: fixup children sizes (if we're solving along the *non-layout* axis)
if(axis != root->child_layout_axis && !(root->flags & (UI_BoxFlag_AllowOverflowX << axis)))
for(UI_Box *box = root; !ui_box_is_nil(box); box = ui_box_rec_df_pre(box, root).next)
{
F32 allowed_size = root->fixed_size.v[axis];
for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next)
//- rjf: fixup children sizes (if we're solving along the *non-layout* axis)
if(axis != box->child_layout_axis && !(box->flags & (UI_BoxFlag_AllowOverflowX << axis)))
{
F32 allowed_size = box->fixed_size.v[axis];
for(UI_Box *child = box->first; !ui_box_is_nil(child); child = child->next)
{
if(!(child->flags & (UI_BoxFlag_FloatingX<<axis)))
{
@@ -1739,13 +1737,13 @@ ui_layout_enforce_constraints__in_place_rec(UI_Box *root, Axis2 axis)
}
//- rjf: fixup children sizes (in the direction of the layout axis)
if(axis == root->child_layout_axis && !(root->flags & (UI_BoxFlag_AllowOverflowX << axis)))
if(axis == box->child_layout_axis && !(box->flags & (UI_BoxFlag_AllowOverflowX << axis)))
{
// rjf: figure out total allowed size & total size
F32 total_allowed_size = root->fixed_size.v[axis];
F32 total_allowed_size = box->fixed_size.v[axis];
F32 total_size = 0;
F32 total_weighted_size = 0;
for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next)
for(UI_Box *child = box->first; !ui_box_is_nil(child); child = child->next)
{
if(!(child->flags & (UI_BoxFlag_FloatingX<<axis)))
{
@@ -1758,12 +1756,14 @@ ui_layout_enforce_constraints__in_place_rec(UI_Box *root, Axis2 axis)
F32 violation = total_size - total_allowed_size;
if(violation > 0 && total_weighted_size > 0)
{
Temp temp = temp_begin(scratch.arena);
// rjf: figure out how much we can take in totality
F32 child_fixup_sum = 0;
F32 *child_fixups = push_array(scratch.arena, F32, root->child_count);
F32 *child_fixups = push_array(temp.arena, F32, box->child_count);
{
U64 child_idx = 0;
for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next, child_idx += 1)
for(UI_Box *child = box->first; !ui_box_is_nil(child); child = child->next, child_idx += 1)
{
if(!(child->flags & (UI_BoxFlag_FloatingX<<axis)))
{
@@ -1778,7 +1778,7 @@ ui_layout_enforce_constraints__in_place_rec(UI_Box *root, Axis2 axis)
// rjf: fixup child sizes
{
U64 child_idx = 0;
for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next, child_idx += 1)
for(UI_Box *child = box->first; !ui_box_is_nil(child); child = child->next, child_idx += 1)
{
if(!(child->flags & (UI_BoxFlag_FloatingX<<axis)))
{
@@ -1788,46 +1788,44 @@ ui_layout_enforce_constraints__in_place_rec(UI_Box *root, Axis2 axis)
}
}
}
temp_end(temp);
}
}
//- rjf: fixup upwards-relative sizes
if(root->flags & (UI_BoxFlag_AllowOverflowX << axis))
if(box->flags & (UI_BoxFlag_AllowOverflowX << axis))
{
for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next)
for(UI_Box *child = box->first; !ui_box_is_nil(child); child = child->next)
{
if(child->pref_size[axis].kind == UI_SizeKind_ParentPct)
{
child->fixed_size.v[axis] = root->fixed_size.v[axis] * child->pref_size[axis].value;
child->fixed_size.v[axis] = box->fixed_size.v[axis] * child->pref_size[axis].value;
}
}
}
//- rjf: enforce clamps
for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next)
for(UI_Box *child = box->first; !ui_box_is_nil(child); child = child->next)
{
child->fixed_size.v[axis] = Max(child->fixed_size.v[axis], child->min_size.v[axis]);
}
//- rjf: recurse
for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next)
{
ui_layout_enforce_constraints__in_place_rec(child, axis);
}
scratch_end(scratch);
ProfEnd();
}
internal void
ui_layout_position__in_place_rec(UI_Box *root, Axis2 axis)
ui_layout_position__in_place(UI_Box *root, Axis2 axis)
{
ProfBeginFunction();
for(UI_Box *box = root; !ui_box_is_nil(box); box = ui_box_rec_df_pre(box, root).next)
{
F32 layout_position = 0;
//- rjf: lay out children
F32 bounds = 0;
for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next)
for(UI_Box *child = box->first; !ui_box_is_nil(child); child = child->next)
{
// rjf: grab original position
F32 original_position = Min(child->rect.p0.v[axis], child->rect.p1.v[axis]);
@@ -1836,7 +1834,7 @@ ui_layout_position__in_place_rec(UI_Box *root, Axis2 axis)
if(!(child->flags & (UI_BoxFlag_FloatingX<<axis)))
{
child->fixed_position.v[axis] = layout_position;
if(root->child_layout_axis == axis)
if(box->child_layout_axis == axis)
{
layout_position += child->fixed_size.v[axis];
bounds += child->fixed_size.v[axis];
@@ -1854,11 +1852,11 @@ ui_layout_position__in_place_rec(UI_Box *root, Axis2 axis)
{
child->fixed_position_animated = child->fixed_position;
}
child->rect.p0.v[axis] = root->rect.p0.v[axis] + child->fixed_position_animated.v[axis] - !(child->flags&(UI_BoxFlag_SkipViewOffX<<axis))*floor_f32(root->view_off.v[axis]);
child->rect.p0.v[axis] = box->rect.p0.v[axis] + child->fixed_position_animated.v[axis] - !(child->flags&(UI_BoxFlag_SkipViewOffX<<axis))*floor_f32(box->view_off.v[axis]);
}
else
{
child->rect.p0.v[axis] = root->rect.p0.v[axis] + child->fixed_position.v[axis] - !(child->flags&(UI_BoxFlag_SkipViewOffX<<axis))*floor_f32(root->view_off.v[axis]);
child->rect.p0.v[axis] = box->rect.p0.v[axis] + child->fixed_position.v[axis] - !(child->flags&(UI_BoxFlag_SkipViewOffX<<axis))*floor_f32(box->view_off.v[axis]);
}
child->rect.p1.v[axis] = child->rect.p0.v[axis] + child->fixed_size.v[axis];
child->rect.p0.x = floor_f32(child->rect.p0.x);
@@ -1875,15 +1873,9 @@ ui_layout_position__in_place_rec(UI_Box *root, Axis2 axis)
//- rjf: store view bounds
{
root->view_bounds.v[axis] = bounds;
box->view_bounds.v[axis] = bounds;
}
//- rjf: recurse
for(UI_Box *child = root->first; !ui_box_is_nil(child); child = child->next)
{
ui_layout_position__in_place_rec(child, axis);
}
ProfEnd();
}
@@ -1891,11 +1883,11 @@ internal void
ui_layout_root(UI_Box *root, Axis2 axis)
{
ProfBegin("ui layout pass (%s)", axis == Axis2_X ? "x" : "y");
ui_calc_sizes_standalone__in_place_rec(root, axis);
ui_calc_sizes_upwards_dependent__in_place_rec(root, axis);
ui_calc_sizes_downwards_dependent__in_place_rec(root, axis);
ui_layout_enforce_constraints__in_place_rec(root, axis);
ui_layout_position__in_place_rec(root, axis);
ui_calc_sizes_standalone__in_place(root, axis);
ui_calc_sizes_upwards_dependent__in_place(root, axis);
ui_calc_sizes_downwards_dependent__in_place(root, axis);
ui_layout_enforce_constraints__in_place(root, axis);
ui_layout_position__in_place(root, axis);
ProfEnd();
}
+5 -5
View File
@@ -862,11 +862,11 @@ internal UI_Box * ui_box_from_key(UI_Key key);
internal void ui_begin_build(OS_Handle window, UI_EventList *events, UI_IconInfo *icon_info, UI_Theme *theme, UI_AnimationInfo *animation_info, F32 real_dt, F32 animation_dt);
internal void ui_end_build(void);
internal void ui_calc_sizes_standalone__in_place_rec(UI_Box *root, Axis2 axis);
internal void ui_calc_sizes_upwards_dependent__in_place_rec(UI_Box *root, Axis2 axis);
internal void ui_calc_sizes_downwards_dependent__in_place_rec(UI_Box *root, Axis2 axis);
internal void ui_layout_enforce_constraints__in_place_rec(UI_Box *root, Axis2 axis);
internal void ui_layout_position__in_place_rec(UI_Box *root, Axis2 axis);
internal void ui_calc_sizes_standalone__in_place(UI_Box *root, Axis2 axis);
internal void ui_calc_sizes_upwards_dependent__in_place(UI_Box *root, Axis2 axis);
internal void ui_calc_sizes_downwards_dependent__in_place(UI_Box *root, Axis2 axis);
internal void ui_layout_enforce_constraints__in_place(UI_Box *root, Axis2 axis);
internal void ui_layout_position__in_place(UI_Box *root, Axis2 axis);
internal void ui_layout_root(UI_Box *root, Axis2 axis);
////////////////////////////////