box-targeted UI debug break cmd

This commit is contained in:
jacob 2026-04-03 11:42:25 -05:00
parent 48eb87aec8
commit d7ecdfb950
8 changed files with 2857 additions and 2636 deletions

View File

@ -14,7 +14,7 @@
//~ Tweakable definitions
#define G_D12_TearingIsAllowed 1
#define G_D12_FrameLatency 1
#define G_D12_FrameLatency 2
#define G_D12_SwapchainBufferCount 2
#define G_D12_SwapchainFlags ( \
((G_D12_TearingIsAllowed != 0) * DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING) | \

View File

@ -2163,6 +2163,9 @@ P_Frame *P_PushFrame(P_World *world, P_Frame *src_frame, i64 tick)
void P_StepFrame(P_Frame *frame)
{
TempArena scratch = BeginScratchNoConflict();
ProfZoneDF("Simulate world")
{
P_World *world = frame->world;
P_Frame *prev_frame = frame->prev;
@ -3725,6 +3728,6 @@ void P_StepFrame(P_Frame *frame)
//- End frame
frame->time_ns += sim_dt_ns;
}
EndScratch(scratch);
}

View File

@ -109,6 +109,7 @@ void S_TickForever(WaveLaneCtx *lane)
//////////////////////////////
//- Swap
ProfZoneDF("Swap sim state")
{
b32 swapin = IsSwappedIn();
b32 swapout = shutdown && IsSwappingOut();
@ -166,6 +167,7 @@ void S_TickForever(WaveLaneCtx *lane)
NET_Listen(net_pipe, port);
P_MsgList in_msgs = Zi;
ProfZoneDF("Pop net messages")
{
NET_MsgList net_msgs = NET_Swap(frame_arena, net_pipe);
for (NET_Msg *net_msg = net_msgs.first; net_msg; net_msg = net_msg->next)

View File

@ -3712,7 +3712,7 @@ void V_TickForever(WaveLaneCtx *lane)
b32 show_panels = frame->is_editing && !hide_editor_ui;
b32 show_panels = (frame->is_editing && !hide_editor_ui) || TweakBool("Show panels when not editing", 1);
@ -3734,32 +3734,134 @@ void V_TickForever(WaveLaneCtx *lane)
if (show_panels && V.root_panel)
{
Struct(DfsPanel) { DfsPanel *next; V_Panel *panel; };
DfsPanel *top_dfs_panel = PushStruct(frame->arena, DfsPanel);
top_dfs_panel->panel = V.root_panel;
for (DfsPanel *dfs_panel = top_dfs_panel; dfs_panel; dfs_panel = top_dfs_panel)
Struct(BfsPanel) { BfsPanel *next; V_Panel *panel; };
BfsPanel *first_bfs_panel = PushStruct(frame->arena, BfsPanel);
BfsPanel *last_bfs_panel = first_bfs_panel;
first_bfs_panel->panel = V.root_panel;
for (BfsPanel *parent_panel_bfs = first_bfs_panel; parent_panel_bfs; parent_panel_bfs = first_bfs_panel)
{
SllStackPop(top_dfs_panel);
V_Panel *panel = dfs_panel->panel;
SllQueuePop(first_bfs_panel, last_bfs_panel);
V_Panel *parent_panel = parent_panel_bfs->panel;
for (V_Panel *child = panel->first; child; child = child->next)
for (V_Panel *panel = parent_panel->first; panel; panel = panel->next)
{
DfsPanel *child_dfs = PushStruct(frame->arena, DfsPanel);
child_dfs->panel = child;
SllStackPush(top_dfs_panel, child_dfs);
BfsPanel *panel_bfs = PushStruct(frame->arena, BfsPanel);
panel_bfs->panel = panel;
SllQueuePush(first_bfs_panel, last_bfs_panel, panel_bfs);
UI_PushDF(Tag, panel->contents_box.v)
UI_PushDF(Parent, panel->contents_box)
{
//////////////////////////////
//- Build console panel
if (panel->flags & V_PanelFlag_Console)
ProfZoneDF("Build console panel")
{
//- Gather visible logs
Struct(VisLog)
{
VisLog *next;
LogEvent log_ev;
};
u64 display_logs_count = 0;
VisLog *first_vis_log = 0;
VisLog *last_vis_log = 0;
i32 max_log_level = LogLevel_Trace;
u32 max_display_logs = 30;
i64 max_time_ns = NsFromSeconds(1000);
LogEventsArray log_events = GetLogEvents();
{
b32 done = 0;
for (u64 log_event_idx = log_events.count; log_event_idx-- > 0 && display_logs_count < max_display_logs && !done;)
{
LogEvent ev = log_events.events[log_event_idx];
if (ev.time_ns > (frame->time_ns - max_time_ns))
{
if (ev.level <= max_log_level)
{
VisLog *vis_log = PushStruct(frame->arena, VisLog);
vis_log->log_ev = ev;
SllQueuePush(first_vis_log, last_vis_log, vis_log);
++display_logs_count;
}
}
else
{
done = 1;
}
}
}
//- Build log entries UI
UI_PushDF(ChildAlignment, UI_Region_BottomLeft)
// UI_PushDF(Anchor, UI_Region_BottomLeft)
// UI_SetNext(Height, UI_Shrink(0, 1));
UI_PushDF(Parent, UI_BuildColumn())
{
// UI_SetNext(BackgroundColor, VEC4(0.1, 0.5, 0.5, 0.8));
// UI_SetNext(Height, UI_Grow(1, 0));
// UI_BuildBox();
// UI_SetNext(Flags, UI_BoxFlag_Floating)
UI_SetNext(Height, UI_Shrink(0, 1));
UI_PushDF(Parent, UI_BuildColumn())
{
for (VisLog *vis_log = first_vis_log; vis_log; vis_log = vis_log->next)
{
LogEvent ev = vis_log->log_ev;
String log_msg = ev.msg;
String display_text = StringF(frame->arena, "%F", FmtString(log_msg));
// UI_BuildLabelF("%F", FmtString(text));
UI_SetNext(Height, UI_Shrink(0, 1));
UI_SetNext(Text, display_text);
// UI_SetNext(ChildAlignment, UI_Region_BottomLeft);
UI_SetNext(ChildAlignment, UI_Region_TopLeft);
UI_SetNext(Flags, UI_BoxFlag_DrawText);
UI_BuildBox();
}
}
}
}
//////////////////////////////
//- Build profiler
//- Build profiler panel
if (!TweakBool("Hide profiler", 0))
if (panel->flags & V_PanelFlag_Profiler)
ProfZoneDF("Build profiler panel")
{
// FIXME: Finalize
@ -3812,7 +3914,6 @@ void V_TickForever(WaveLaneCtx *lane)
//- Build profiler
UI_Key profiler_box = UI_KeyF("profiler");
ProfZoneDF("Build profiler")
UI_PushDF(Tag, profiler_box.v)
UI_PushDF(Parent, profiler_box)
{
@ -3828,7 +3929,9 @@ void V_TickForever(WaveLaneCtx *lane)
UI_Size graph_height = UI_Fnt(2, 1);
UI_Size main_height = UI_Grow(1, 0);
UI_Size zone_height = UI_Fnt(1.25, 0);
UI_Size track_height = UI_Fnt(10, 0);
// UI_Size track_height = UI_Fnt(10, 0);
UI_Size track_height = UI_Grow(1, 0);
// UI_Size track_height = UI_Shrink(0, 0);
f32 zone_text_padding_px = UI_Top(FontSize) * 0.2;
// Vec2 old_main_dims = DimsFromRng2(UI_Rect(main_box));
@ -4137,14 +4240,10 @@ void V_TickForever(WaveLaneCtx *lane)
visual_zone_start_px = MaxF64(visual_zone_start_px, parent_vis->start_px);
if (left_vis)
{
// visual_zone_start_px = MaxF64(visual_zone_start_px, CeilF64(left_vis->end_px));
visual_zone_start_px = MaxF64(visual_zone_start_px, left_vis->end_px);
}
// visual_zone_start_px = MinF64(visual_zone_start_px, visual_zone_end_px - min_zone_width_px);
// visual_zone_start_px = MaxF64(visual_zone_start_px, parent_vis->start_px);
// visual_zone_end_px = MaxF64(visual_zone_end_px, visual_zone_start_px + min_zone_width_px);
// visual_zone_end_px = MinF64(visual_zone_end_px, parent_vis->end_px);
visual_zone_start_px = RoundF32(visual_zone_start_px);
visual_zone_end_px = RoundF32(visual_zone_end_px);
}
// Push vis zone
@ -4215,6 +4314,7 @@ void V_TickForever(WaveLaneCtx *lane)
}
}
// Vec4 profiler_color = theme.col.window_bg;
Vec4 profiler_color = theme.col.window_bg;
f32 profiler_opacity = TweakFloat("Profiler opacity", 1, 0, 1);
@ -4332,6 +4432,9 @@ void V_TickForever(WaveLaneCtx *lane)
UI_PushDF(Tag, HashF("vis track %F", FmtUint(vis_track->id)))
UI_PushDF(Parent, UI_BuildColumn())
{
// UI_BuildSpacer(UI_Px(10, 0), Axis_Y);
// UI_BuildSpacer(UI_Grow(1, 0), Axis_Y);
//- Zone rows
UI_Key *zone_row_boxes = PushStructs(frame->arena, UI_Key, vis_track->rows_count);
for (u64 zone_row_box_idx = 0; zone_row_box_idx < vis_track->rows_count; ++zone_row_box_idx)
@ -4357,11 +4460,6 @@ void V_TickForever(WaveLaneCtx *lane)
{
hovered_zone_box = zone_box;
hovered_zone = zone;
// FIXME: Remove this
b32 raah = UI_HotAbsolute(main_box);
}
f32 zone_hovered = can_hover * UI_Hovered(zone_box) * UI_Hot(main_box);
@ -4536,13 +4634,15 @@ void V_TickForever(WaveLaneCtx *lane)
// Right collapsed lines
if (is_collapsed)
{
// Right zag
{
UI_SetNext(Width, UI_Grow(1, 0));
UI_SetNext(ZagColor, zone_line_color);
UI_BuildBox();
}
else
{
UI_SetNext(Width, UI_Px(3, 1));
UI_BuildBox();
}
}
}
@ -4760,6 +4860,8 @@ void V_TickForever(WaveLaneCtx *lane)
}
}
}
}
}
@ -4795,7 +4897,6 @@ void V_TickForever(WaveLaneCtx *lane)
UI_PushDF(Tag, HashF("vis panels"))
{
// FIXME: Remove this
//////////////////////////////
@ -4836,18 +4937,18 @@ void V_TickForever(WaveLaneCtx *lane)
}
}
//- Test panel
//- Test console panel
{
V_Panel *parent = subroot_row_panel;
V_Panel *panel = PushStruct(perm, V_Panel);
panel->parent = parent;
panel->axis = Axis_X;
DllQueuePush(parent->first, parent->last, panel);
panel->box = UI_KeyF("test raah panel");
panel->box = UI_KeyF("test raah console panel");
panel->contents_box = UI_KeyF("panel contents box %F", FmtUint(panel->box.v));
panel->resizer_box = UI_KeyF("panel resizer box %F", FmtUint(panel->box.v));
panel->flags |= V_PanelFlag_Profiler;
panel->pct = 0.25;
panel->flags |= V_PanelFlag_Console;
panel->pct = 0.5;
}
//- Vis screen panel
@ -4862,6 +4963,21 @@ void V_TickForever(WaveLaneCtx *lane)
panel->resizer_box = UI_KeyF("panel resizer box %F", FmtUint(panel->box.v));
panel->pct = 1;
}
//- Test profiler panel
{
V_Panel *parent = subroot_row_panel;
V_Panel *panel = PushStruct(perm, V_Panel);
panel->parent = parent;
panel->axis = Axis_X;
DllQueuePush(parent->first, parent->last, panel);
panel->box = UI_KeyF("test raah profiler panel");
panel->contents_box = UI_KeyF("panel contents box %F", FmtUint(panel->box.v));
panel->resizer_box = UI_KeyF("panel r esizer box %F", FmtUint(panel->box.v)); if (!TweakBool("Hide profiler", 0))
panel->flags |= V_PanelFlag_Profiler;
panel->pct = 0.5;
}
}
@ -4913,14 +5029,14 @@ void V_TickForever(WaveLaneCtx *lane)
{
SllQueuePop(first_panel_bfs, last_panel_bfs);
V_Panel *parent_panel = bfs_parent->panel;
UI_Key parent_contents_box = parent_panel->contents_box;
Axis parent_axis = parent_panel->axis;
Rng2 parent_rect = UI_Rect(parent_contents_box);
Rng2 parent_rect = UI_Rect(parent_panel->contents_box);
Vec2 parent_dims = DimsFromRng2(parent_rect);
f32 parent_contents_size_px = MaxF32(DimsFromRng2(UI_Rect(parent_contents_box)).v[parent_axis], 1);
f32 parent_contents_size_px = MaxF32(DimsFromRng2(UI_Rect(parent_panel->contents_box)).v[parent_axis], 1);
UI_PushDF(Parent, parent_contents_box)
UI_PushDF(Tag, parent_panel->contents_box.v)
UI_PushDF(Parent, parent_panel->contents_box)
{
f32 minimum_panel_pct = 0.05;
@ -5006,6 +5122,7 @@ void V_TickForever(WaveLaneCtx *lane)
// UI_SetNext(AxisSize, UI_Grow(panel_pct, 1), .axis = parent_axis);
UI_SetNext(AxisSize, UI_Grow(panel_pct, 0), .axis = parent_axis);
// UI_SetNext(AxisSize, UI_Px(panel_pct * parent_contents_size_px, 0), .axis = parent_axis);
UI_SetNext(AxisSize, UI_Grow(1, 0), .axis = !parent_axis);
UI_SetNext(ChildLayoutAxis, parent_axis);
UI_PushDF(Tag, panel_box.v)
@ -8131,7 +8248,14 @@ void V_TickForever(WaveLaneCtx *lane)
UI_Pop(FontSize);
}
UI_BuildLabelF(" Arenas: %F", FmtSint(GetGstat(NumArenas)));
if (PROFILING_ENABLED)
{
UI_BuildLabelF(" Arena memory committed: %F MiB (Collecting profiler samples, so perpetual growth is expected)", FmtFloat((f64)GetGstat(ArenaMemoryCommitted) / 1024 / 1024, .p = 3));
}
else
{
UI_BuildLabelF(" Arena memory committed: %F MiB", FmtFloat((f64)GetGstat(ArenaMemoryCommitted) / 1024 / 1024, .p = 3));
}
UI_BuildLabelF(" Arena memory reserved: %F TiB", FmtFloat((f64)GetGstat(ArenaMemoryReserved) / 1024 / 1024 / 1024 / 1024, .p = 3));
}
UI_BuildSpacer(UI_Px(padding, 1), Axis_Y);

View File

@ -317,6 +317,7 @@ Enum(V_PanelFlag)
V_PanelFlag_None = 0,
V_PanelFlag_Spawn = (1 << 0),
V_PanelFlag_Profiler = (1 << 1),
V_PanelFlag_Console = (1 << 2),
};
Struct(V_Panel)

View File

@ -762,7 +762,8 @@ ComputeShader(V_CompositeCS)
Vec4 backdrop_color = 0;
{
if (!frame.is_editing || !is_in_world)
// if (!frame.is_editing || !is_in_world)
if (1)
{
backdrop_color = backdrop.SampleLevel(bilinear_sampler, screen_uv, 0);
}

View File

@ -514,6 +514,19 @@ void UI_SetRawTexture(UI_Key key, G_TextureRef tex, Rng2 uv)
SllQueuePush(frame->first_cmd_node, frame->last_cmd_node, n);
}
void UI_DebugBreak(UI_Key key, UI_DebugBreakFlag debug_break_flags)
{
UI_Frame *frame = UI_CurrentFrame();
UI_CmdNode *n = PushStruct(frame->arena, UI_CmdNode);
n->cmd.kind = UI_CmdKind_DebugBreak;
{
n->cmd.debug_break.key = key;
n->cmd.debug_break.flags = debug_break_flags;
}
++frame->cmds_count;
SllQueuePush(frame->first_cmd_node, frame->last_cmd_node, n);
}
////////////////////////////////////////////////////////////
//~ Begin frame
@ -562,7 +575,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
}
frame->window_frame = WND_BeginFrame(G_Format_R16G16B16A16_Float, WND_BackbufferSizeMode_MatchMonitor);
ProfZoneDF("Begin UI")
ProfZoneDF("Prepare UI")
{
UI.cl = G_PrepareCommandList(G_QueueKind_Direct);
ResetArena(frame->arena);
@ -617,7 +630,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
for (u64 pre_index = UI.boxes_count; pre_index-- > 0;)
{
UI_Box *box = prev_frame->boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_CheckCursorHover);
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_CheckCursorHover);
//- Reset state
{
box->child_mouse_hovered = 0;
@ -810,7 +823,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
UI_Box *box = prev_frame->boxes_pre[pre_index];
UI_Box *parent = box->parent;
UI_Feedback *feedback = &box->feedback;
UI_DebugBreak(box, UI_DebugBreakFlag_BuildFeedback);
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_BuildFeedback);
// Propagate capture state upwards
box->child_mouse_hovered = box->mouse_hovered || box->child_mouse_hovered;
@ -1159,7 +1172,7 @@ GC_Run UI_ScaleRun(Arena *arena, GC_Run unscaled_run, Vec2 scale)
void UI_EndFrame(UI_Frame *frame, i32 vsync)
{
TempArena scratch = BeginScratchNoConflict();
ProfZoneDF("End UI")
ProfZoneDF("Commit UI")
{
UI_BoxIter box_iter = Zi;
@ -1174,6 +1187,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
//////////////////////////////
//- Create boxes from build cmds
ProfZoneDF("Create boxes")
for (UI_CmdNode *cmd_node = frame->first_cmd_node; cmd_node; cmd_node = cmd_node->next)
{
UI_Cmd cmd = cmd_node->cmd;
@ -1217,8 +1231,9 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
}
//////////////////////////////
//- Update boxes from cmds
//- Apply build cmds
ProfZoneDF("Apply build cmds")
for (UI_CmdNode *cmd_node = frame->first_cmd_node; cmd_node; cmd_node = cmd_node->next)
{
UI_Cmd cmd = cmd_node->cmd;
@ -1294,9 +1309,31 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
}
}
//////////////////////////////
//- Apply debug break cmds
if (UI_IsDebugBreakEnabled)
{
ProfZoneDF("Apply debug break cmds")
for (UI_CmdNode *cmd_node = frame->first_cmd_node; cmd_node; cmd_node = cmd_node->next)
{
UI_Cmd cmd = cmd_node->cmd;
if (cmd.kind == UI_CmdKind_DebugBreak)
{
UI_Key key = cmd.debug_break.key;
UI_Box *box = UI_BoxFromKey(key);
if (box)
{
box->desc.debug_break_flags |= cmd.debug_break.flags;
}
}
}
}
//////////////////////////////
//- Prune cached boxes
ProfZoneDF("Prune boxes")
{
u64 prunes_count = 0;
UI_Box **prunes = PushStructsNoZero(scratch.arena, UI_Box *, UI.boxes_count);
@ -1355,12 +1392,15 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
//////////////////////////////
//- Layout
// Prepare layout data
u64 boxes_count = UI.boxes_count;
UI_Box **boxes_pre = PushStructsNoZero(frame->arena, UI_Box *, boxes_count);
UI_Box **boxes_post = PushStructsNoZero(frame->arena, UI_Box *, boxes_count);
frame->boxes_pre = boxes_pre;
frame->boxes_post = boxes_post;
ProfZoneDF("Layout UI")
{
//- Prepare layout data
ProfZoneDF("Layout prepass")
{
u64 pre_index = 0;
u64 post_index = 0;
@ -1369,7 +1409,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
UI_Box *box = ir.box;
if (ir.pre)
{
UI_DebugBreak(box, UI_DebugBreakFlag_PrepLayout);
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_PrepLayout);
box->pre_index = pre_index;
boxes_pre[pre_index] = box;
@ -1403,18 +1443,26 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
Assert(post_index == boxes_count);
}
// Solve independent sizes
//- Solve independent sizes
ProfZoneDF("Solve independent sizes")
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_IndependentSolve);
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_IndependentSolve);
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
{
UI_Size size = box->desc.pref_semantic_dims[axis];
if (size.kind == UI_SizeKind_Pixel)
{
if (TweakBool("RAAAAAAAAAAAAAH", 1))
{
box->solved_dims.v[axis] = size.v;
}
else
{
box->solved_dims.v[axis] = CeilF32(size.v);
}
}
else if (size.kind == UI_SizeKind_Shrink)
{
if (AnyBit(box->desc.flags, UI_BoxFlag_DrawText))
@ -1428,21 +1476,36 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
{
text_size = box->glyph_run.font_ascent + box->glyph_run.font_descent;
}
if (TweakBool("RAAAAAAAAAAAAAH", 1))
{
box->solved_dims.v[axis] = text_size + (size.v * 2);
}
else
{
box->solved_dims.v[axis] = CeilF32(text_size + (size.v * 2));
}
}
else if (!SPR_IsSheetKeyNil(box->desc.sprite_sheet))
{
if (TweakBool("RAAAAAAAAAAAAAH", 1))
{
box->solved_dims.v[axis] = box->sprite.tex_rect.p1.v[axis] - box->sprite.tex_rect.p0.v[axis] + (size.v * 2);
}
else
{
box->solved_dims.v[axis] = CeilF32(box->sprite.tex_rect.p1.v[axis] - box->sprite.tex_rect.p0.v[axis] + (size.v * 2));
}
}
}
}
}
// Solve upwards-dependent sizes along layout axis
//- Solve upwards-dependent sizes along layout axis
ProfZoneDF("Solve upwards-dependent sizes (along layout-axis)")
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_UpwardsDependentSolveLayoutAxis);
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_UpwardsDependentSolveLayoutAxis);
if (box->parent)
{
Axis axis = box->parent->desc.child_layout_axis;
@ -1455,8 +1518,10 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
{
UI_Size ancestor_size = ancestor->desc.pref_semantic_dims[axis];
if (
ancestor_size.kind == UI_SizeKind_Pixel || (
ancestor_size.kind == UI_SizeKind_Shrink && (
ancestor_size.kind == UI_SizeKind_Pixel ||
(
ancestor_size.kind == UI_SizeKind_Shrink &&
(
AnyBit(box->desc.flags, UI_BoxFlag_DrawText) ||
!SPR_IsSheetKeyNil(box->desc.sprite_sheet)
)
@ -1473,11 +1538,12 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
}
}
// Solve downwards-dependent sizes
//- Solve downwards-dependent sizes
ProfZoneDF("Solve downwards-dependent sizes")
for (u64 post_index = 0; post_index < boxes_count; ++post_index)
{
UI_Box *box = boxes_post[post_index];
UI_DebugBreak(box, UI_DebugBreakFlag_DownwardsDependentSolve);
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_DownwardsDependentSolve);
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
{
UI_Size size = box->desc.pref_semantic_dims[axis];
@ -1499,16 +1565,18 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
}
}
}
box->solved_dims.v[axis] = CeilF32(accum + (size.v * 2));
// box->solved_dims.v[axis] = CeilF32(accum + (size.v * 2));
box->solved_dims.v[axis] = accum + (size.v * 2);
}
}
}
// Solve upwards-dependent sizes along non-layout axis
//- Solve upwards-dependent sizes along non-layout axis
ProfZoneDF("Solve upwards-dependent sizes (along non-layout-axis)")
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_UpwardsDependentSolveNonLayoutAxis);
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_UpwardsDependentSolveNonLayoutAxis);
if (box->parent)
{
Axis axis = !box->parent->desc.child_layout_axis;
@ -1520,11 +1588,12 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
}
}
// Solve violations
//- Solve violations
ProfZoneDF("Solve violations")
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_SolveViolations);
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_SolveViolations);
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
{
f32 box_size = box->solved_dims.v[axis];
@ -1539,7 +1608,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
b32 is_floating = AnyBit(child->desc.flags, UI_BoxFlag_Floating);
if (!is_floating)
{
f32 size = child->solved_dims.v[axis];
f32 size = RoundF32(child->solved_dims.v[axis]);
f32 strictness = child->desc.pref_semantic_dims[axis].strictness;
f32 flex = size * (1.0 - strictness);
if (axis == box->desc.child_layout_axis)
@ -1562,7 +1631,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
for (UI_Box *child = box->first; child; child = child->next)
{
b32 is_floating = AnyBit(child->desc.flags, UI_BoxFlag_Floating);
f32 unconstrained_size = child->solved_dims.v[axis];
f32 unconstrained_size = RoundF32(child->solved_dims.v[axis]);
f32 strictness = child->desc.pref_semantic_dims[axis].strictness;
f32 flex = unconstrained_size * (1.0 - strictness);
f32 new_size = unconstrained_size;
@ -1593,7 +1662,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
}
if (!is_floating)
{
size_accum += new_size;
size_accum += RoundF32(new_size);
}
child->solved_dims.v[axis] = new_size;
}
@ -1603,11 +1672,12 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
}
}
// Solve final positions
//- Solve final positions
ProfZoneDF("Solve final screen positions")
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_FinalSolve);
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_FinalSolve);
UI_Box *parent = box->parent;
@ -1620,14 +1690,14 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
b32 is_floating = AnyBit(box->desc.flags, UI_BoxFlag_Floating);
// Apply scale
//- Apply scale
for (Axis axis = 0; axis < Axis_COUNTXY; ++axis)
{
f32 unscaled_size = box->solved_dims.v[axis];
f32 scaled_size = 0;
if (box->solved_scale.v[axis] == 1)
{
scaled_size = RoundF32(unscaled_size);
scaled_size = RoundF32(unscaled_size); // Can cause layout issues
// scaled_size = unscaled_size;
}
else
@ -1637,7 +1707,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
box->solved_dims.v[axis] = scaled_size;
}
// Compute anchor offset
//- Compute anchor offset
Vec2 anchor_offset = Zi;
{
UI_RegionPair anchor_region = UI_PairFromRegion(box->desc.anchor);
@ -1680,7 +1750,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
// box->cursor = FloorF32(box->cursor);
}
// Solve screen rect
//- Solve screen rect
{
// Compute offset
Vec2 offset = Zi;
@ -1718,17 +1788,9 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
}
}
}
if (box->solved_scale.x == 1)
{
offset.x = RoundF32(offset.x);
}
if (box->solved_scale.y == 1)
{
offset.y = RoundF32(offset.y);
}
}
// Compute rect
//- Compute rect
Vec2 screen_pos = parent ? AddVec2(parent->screen_rect.p0, offset) : VEC2(0, 0);
if (is_floating)
{
@ -1744,8 +1806,21 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
screen_pos.y = MaxF32(parent->screen_rect.p0.y, screen_pos.y - overshoot.y);
}
}
box->screen_rect.p0 = screen_pos;
box->screen_rect.p1 = AddVec2(box->screen_rect.p0, box->solved_dims);
if (box->solved_scale.x == 1)
{
box->screen_rect.p0.x = RoundF32(box->screen_rect.p0.x);
box->screen_rect.p1.x = RoundF32(box->screen_rect.p1.x);
}
if (box->solved_scale.y == 1)
{
box->screen_rect.p0.y = RoundF32(box->screen_rect.p0.y);
box->screen_rect.p1.y = RoundF32(box->screen_rect.p1.y);
}
box->screen_anchor = AddVec2(box->screen_rect.p0, anchor_offset);
// Update parent cursor
@ -1755,7 +1830,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
}
}
// Solve scissor
//- Solve scissor
{
box->solved_scissor = Rng2Inf;
if (box->desc.flags & UI_BoxFlag_Scissor || !parent)
@ -1768,7 +1843,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
}
}
// Solve screen rounding
//- Solve screen rounding
{
UI_Round rounding = box->desc.rounding;
Vec2 half_dims = MulVec2(SubVec2(box->screen_rect.p1, box->screen_rect.p0), 0.5);
@ -1819,6 +1894,8 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
box->gen = box->old_gen;
}
}
//////////////////////////////
//- Render
@ -1830,11 +1907,11 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
//- Build render data
// Build GPU rect data
ProfZoneDF("Build UI GPU rects")
ProfZoneDF("Build GPU rects")
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
UI_DebugBreak(box, UI_DebugBreakFlag_BuildGpuData);
UI_ExecuteDebugBreak(box, UI_DebugBreakFlag_BuildGpuData);
GC_Run raw_run_unscaled = box->glyph_run;
GC_Run raw_run = UI_ScaleRun(frame->arena, raw_run_unscaled, box->solved_scale);
@ -1879,6 +1956,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
UI_AxisRegion y_alignment = child_alignment.v[Axis_Y];
// Box rect
ProfZoneDF("GPU box rect")
{
UI_GpuRect *rect = PushStruct(frame->rects_arena, UI_GpuRect);
rect->bounds = box->screen_rect;
@ -1909,7 +1987,9 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
}
}
// Text rects
if (should_upload_text || AnyBit(frame->frame_flags, UI_FrameFlag_Debug))
ProfZoneDF("GPU text rects")
{
f32 max_baseline_length = CeilF32(DimsFromRng2(box->screen_rect).x);
b32 should_truncate = FloorF32(raw_run.baseline_length) > max_baseline_length && !AnyBit(box->desc.flags, UI_BoxFlag_DontTruncateText);
@ -2037,7 +2117,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
//////////////////////////////
//- Upload data to GPU
ProfZoneDF("UI GPU upload")
ProfZoneDF("Upload boxes to GPU")
G_ProfZoneDF(UI.cl, "UI GPU upload")
{
// Target

View File

@ -262,6 +262,7 @@ Enum(UI_CmdKind)
{
UI_CmdKind_None,
UI_CmdKind_BuildBox,
UI_CmdKind_DebugBreak,
UI_CmdKind_SetRawTexture,
};
@ -312,6 +313,11 @@ Struct(UI_Cmd)
{
UI_BoxDesc box;
struct
{
UI_Key key;
UI_DebugBreakFlag flags;
} debug_break;
struct
{
UI_Key key;
G_TextureRef tex;
@ -568,12 +574,16 @@ UI_Checkpoint UI_TopCp(void);
UI_Key UI_BuildBoxEx(UI_Key semantic_key);
#define UI_BuildBox() UI_BuildBoxEx(UI_NilKey)
void UI_DebugBreak(UI_Key key, UI_DebugBreakFlag debug_break_flags);
void UI_SetRawTexture(UI_Key key, G_TextureRef tex, Rng2 uv);
#if IsRtcEnabled
#define UI_DebugBreak(box, target_flags) do { if (box->desc.debug_break_flags & target_flags) { DEBUGBREAK; } } while (0)
#define UI_IsDebugBreakEnabled IsRtcEnabled
#if UI_IsDebugBreakEnabled
#define UI_ExecuteDebugBreak(box, target_flags) do { if ((box)->desc.debug_break_flags & (target_flags)) { DEBUGBREAK; } } while (0)
#else
#define UI_DebugBreak(...)
#define UI_ExecuteDebugBreak(...)
#endif
////////////////////////////////////////////////////////////