ui violation pass

This commit is contained in:
jacob 2025-11-02 11:08:22 -06:00
parent 6a5f65d291
commit 5d87cc2a0e
5 changed files with 273 additions and 129 deletions

View File

@ -115,6 +115,9 @@ void PushGameUiStyle(void)
UI_Push(BorderColor, Rgba32F(0.6, 0.6, 0.6, 1));
UI_Push(Width, UI_FILL(1, 0));
UI_Push(Height, UI_FILL(1, 0));
UI_Push(LayoutAxis, Axis_Y);
}
@ -359,12 +362,32 @@ void DrawDebugConsole(b32 minimized)
UI_Box *console_box = 0;
{
UI_SetNext(LayoutAxis, Axis_Y);
UI_SetNext(Tint, 0);
console_box = UI_BuildBox(0, UI_NilKey);
// UI_SetNext(Tint, 0);
// UI_SetNext(BorderColor, Rgba32F(1, 1, 1, 0.25));
UI_SetNext(Border, 0);
// UI_SetNext(Width, UI_FIT(1));
if (minimized)
{
UI_SetNext(BackgroundColor, 0);
UI_SetNext(Width, UI_PIX(500, 1));
UI_SetNext(Height, UI_FIT(1));
}
else
{
UI_SetNext(BackgroundColor, Rgba32F(1, 1, 1, 0.02));
UI_SetNext(Width, UI_FILL(1, 0));
UI_SetNext(Height, UI_FILL(0.33, 1));
}
console_box = UI_BuildBox(0, UI_NilKey);
UI_Push(Parent, console_box);
UI_Push(Width, UI_TextSize(0));
UI_Push(Height, UI_TextSize(0));
if (!minimized)
{
UI_BuildSpacer(UI_FILL(1, 0));
}
}
// UI_Push(Width, UI_TXT(0));
UI_Push(Width, UI_FIT(1));
UI_Push(Height, UI_FIT(1));
UI_Push(BorderColor, Rgba32F(0.25, 0.25, 0.25, 1));
UI_Push(Rounding, 0);
UI_Push(TextPadding, 6);
@ -420,8 +443,29 @@ void DrawDebugConsole(b32 minimized)
u32 color = colors[log->level][log->color_index];
UI_SetNext(BackgroundColor, color);
UI_SetNext(Tint, Alpha32F(0xFFFFFFFF, opacity));
UI_Box *log_box = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey);
UI_SetDisplayText(log_box, text);
UI_SetNext(LayoutAxis, Axis_X);
UI_Box *log_box = UI_BuildBox(UI_BoxFlag_None, UI_NilKey);
UI_PushCheckpoint();
{
UI_Push(Parent, log_box);
UI_Push(BackgroundColor, 0);
UI_Push(Border, 0);
f32 spacer = 50;
{
// UI_BuildSpacer(UI_PIX(spacer, 0));
}
{
UI_SetNext(Width, UI_FILL(1, 1));
UI_SetNext(Height, UI_TXT(1));
UI_Box *log_textbox = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey);
UI_SetDisplayText(log_textbox, text);
}
// {
// UI_BuildSpacer(UI_PIX(spacer, 0));
// }
UI_Pop(Parent, log_box);
}
UI_PopCheckpoint();
}
}
Unlock(&lock);
@ -2060,14 +2104,24 @@ void UpdateUser(void)
GPU_Stats gpu_stats = GPU_QueryStats();
/* Draw console */
{
b32 console_minimized = !g->debug_console;
DrawDebugConsole(console_minimized);
}
/* Draw debug info */
if (g->debug_draw)
{
__profn("Draw debug info");
UI_BuildSpacer(UI_FILL(1, 0));
UI_SetNext(LayoutAxis, Axis_Y);
UI_SetNext(BackgroundColor, 0);
UI_SetNext(BorderColor, 0);
UI_SetNext(Width, UI_FIT(1));
UI_SetNext(Height, UI_FIT(1));
UI_Box *dbg_box = UI_BuildBox(0, UI_NilKey);
UI_PushCheckpoint();
{
@ -2080,7 +2134,7 @@ void UpdateUser(void)
UI_BuildLabelF("blended world tick: %F", FmtUint(g->ss_blended->tick));
UI_BuildLabelF("blended world time: %F", FmtFloat(SecondsFromNs(g->ss_blended->sim_time_ns)));
UI_BuildSpacer(UI_PixelSize(20, 0));
UI_BuildSpacer(UI_PIX(20, 0));
UI_BuildLabelF("average local sim publish dt: %F", FmtFloat(SecondsFromNs(g->average_local_to_user_snapshot_publish_dt_ns)));
UI_BuildLabelF("local sim last known tick: %F", FmtUint(g->local_sim_last_known_tick));
@ -2091,7 +2145,7 @@ void UpdateUser(void)
UI_BuildLabelF("render time: %F", FmtFloat(SecondsFromNs(g->render_time_ns)));
UI_BuildLabelF("local player: [%F]", FmtUid(local_player->id.uid));
UI_BuildSpacer(UI_PixelSize(20, 0));
UI_BuildSpacer(UI_PIX(20, 0));
Vec2 world_cursor = g->world_cursor;
UI_BuildLabelF("cursor world: %F, %F", FmtFloat(world_cursor.x), FmtFloat(world_cursor.y));
@ -2104,7 +2158,7 @@ void UpdateUser(void)
Vec2I32 tile_chunk_cursor = TileChunkIndexFromWorldTileIndex(world_tile_cursor);
UI_BuildLabelF("cursor tile chunk: %F, %F", FmtSint(tile_chunk_cursor.x), FmtSint(tile_chunk_cursor.y));
UI_BuildSpacer(UI_PixelSize(20, 0));
UI_BuildSpacer(UI_PIX(20, 0));
UI_BuildLabelF("Network read: %F mbit/s", FmtFloat((f64)g->net_bytes_read.last_second * 8 / 1000 / 1000));
@ -2113,18 +2167,18 @@ void UpdateUser(void)
UI_BuildLabelF("Ping (real): %F ms", FmtFloat(SecondsFromNs(local_player->player_last_rtt_ns) * 1000));
UI_BuildLabelF("Ping (average): %F ms", FmtFloat(local_player->player_average_rtt_seconds * 1000));
UI_BuildSpacer(UI_PixelSize(20, 0));
UI_BuildSpacer(UI_PIX(20, 0));
UI_BuildLabelF("Memory committed: %F MiB", FmtFloat((f64)GetGstat(GSTAT_MEMORY_COMMITTED) / 1024 / 1024));
UI_BuildLabelF("Virtual memory reserved: %F TiB", FmtFloat((f64)GetGstat(GSTAT_MEMORY_RESERVED) / 1024 / 1024 / 1024 / 1024));
UI_BuildLabelF("Arenas allocated: %F", FmtUint(GetGstat(GSTAT_NUM_ARENAS)));
UI_BuildSpacer(UI_PixelSize(20, 0));
UI_BuildSpacer(UI_PIX(20, 0));
UI_BuildLabelF("GPU dedicated memory usage: %F MiB", FmtFloat((f64)gpu_stats.local_committed / 1024 / 1024));
UI_BuildLabelF("GPU shared memory usage: %F MiB", FmtFloat((f64)gpu_stats.non_local_committed / 1024 / 1024));
UI_BuildSpacer(UI_PixelSize(20, 0));
UI_BuildSpacer(UI_PIX(20, 0));
UI_BuildLabelF("GPU resources: %F", FmtUint(gpu_stats.driver_resources_allocated));
UI_BuildLabelF("GPU descriptors: %F", FmtUint(gpu_stats.driver_descriptors_allocated));
@ -2132,7 +2186,7 @@ void UpdateUser(void)
//UI_BuildLabelF(\n"));
#if RtcIsEnabled
UI_BuildSpacer(UI_PixelSize(20, 0));
UI_BuildSpacer(UI_PIX(20, 0));
UI_BuildLabelF("Debug steps: %F", FmtUint(GetGstat(GSTAT_DEBUG_STEPS)));
//UI_BuildLabelF(\n"));
#endif
@ -2140,12 +2194,6 @@ void UpdateUser(void)
UI_PopCheckpoint();
}
/* Draw console */
{
b32 console_minimized = !g->debug_console;
DrawDebugConsole(console_minimized);
}
//////////////////////////////
//- Render

View File

@ -1096,7 +1096,8 @@ void StepSim(SimStepCtx *ctx)
}
if (flags & ControlFlag_SpawnTest1)
{
P_LogDebugF("Spawn test 1");
// P_LogDebugF("Spawn test 1");
P_LogDebugF("Spawn test 1 ****************************************************************************************************************************************************************");
u32 count = 1;
f32 spread = 0;
for (u32 j = 0; j < count; ++j)

View File

@ -4,8 +4,8 @@
UI_Box *UI_BuildLabel(String text)
{
UI_Key key = UI_KeyFromString(0, text);
UI_SetNext(Width, UI_TextSize(0));
UI_SetNext(Height, UI_TextSize(0));
UI_SetNext(Width, UI_TXT(0));
UI_SetNext(Height, UI_TXT(0));
UI_Box *box = UI_BuildBox(UI_BoxFlag_DrawText, UI_NilKey);
UI_SetDisplayText(box, text);
return box;
@ -32,9 +32,16 @@ UI_Box *UI_BuildLabelF_(char *fmt_cstr, ...)
UI_Box *UI_BuildSpacer(UI_Size size)
{
UI_SetNext(Tint, 0);
/* FIXME: Only set size in parent layout direction */
if (UI_PeekTop(Parent)->layout_axis == Axis_X)
{
UI_SetNext(Width, size);
UI_SetNext(Height, UI_FILL(1, 0));
}
else
{
UI_SetNext(Width, UI_FILL(1, 0));
UI_SetNext(Height, size);
}
UI_Box *box = UI_BuildBox(0, UI_NilKey);
return box;
}

View File

@ -289,8 +289,8 @@ void UI_BeginBuild(void)
}
g->style_tops[UI_StyleKind_Tag]->style.Tag = HashFnv64(Fnv64Basis, Lit("root"));
g->style_tops[UI_StyleKind_Parent]->style.Parent = g->root_box;
g->style_tops[UI_StyleKind_Width]->style.Width = UI_RatioSize(1, 0);
g->style_tops[UI_StyleKind_Height]->style.Height = UI_RatioSize(1, 0);
g->style_tops[UI_StyleKind_Width]->style.Width = UI_FILL(1, 0);
g->style_tops[UI_StyleKind_Height]->style.Height = UI_FILL(1, 0);
g->style_tops[UI_StyleKind_Font]->style.Font = UI_GetDefaultFontResource();
g->style_tops[UI_StyleKind_FontSize]->style.FontSize = 12.0f;
g->style_tops[UI_StyleKind_Tint]->style.Tint = 0xFFFFFFFF;
@ -388,7 +388,7 @@ i64 UI_EndBuild(GPU_Resource *render_target)
{
box->solved_dims[axis] = pref_size.v;
}
else if (pref_size.kind == UI_SizeKind_Text)
else if (pref_size.kind == UI_SizeKind_TextContents)
{
/* TODO: Distinguish between baseline alignment & visual alignment */
f32 text_size = 0;
@ -420,14 +420,14 @@ i64 UI_EndBuild(GPU_Resource *render_target)
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
{
UI_Size pref_size = box->pref_size[axis];
if (pref_size.kind == UI_SizeKind_Ratio)
if (pref_size.kind == UI_SizeKind_Fill)
{
UI_Box *ancestor = box->parent;
f32 ancestor_size = 0;
for (; ancestor; ancestor = ancestor->parent)
{
UI_Size tmp = ancestor->pref_size[axis];
if (tmp.kind == UI_SizeKind_Pixel || tmp.kind == UI_SizeKind_Text)
if (tmp.kind == UI_SizeKind_Pixel || tmp.kind == UI_SizeKind_TextContents)
{
ancestor_size = ancestor->solved_dims[axis];
break;
@ -438,6 +438,127 @@ i64 UI_EndBuild(GPU_Resource *render_target)
}
}
/* Calculate downwards-dependent sizes */
for (u64 post_index = 0; post_index < boxes_count; ++post_index)
{
UI_Box *box = boxes_post[post_index];
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
{
UI_Size pref_size = box->pref_size[axis];
if (pref_size.kind == UI_SizeKind_Fit)
{
f32 accum = 0;
for (UI_Box *child = box->first; child; child = child->next)
{
if (axis == box->layout_axis)
{
accum += child->solved_dims[axis];
}
else
{
accum = MaxF32(child->solved_dims[axis], accum);
}
}
box->solved_dims[axis] = accum;
}
}
}
/* TODO: Remove this */
#if 0
/* Calculate upwards-dependent sizes */
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
{
UI_Size pref_size = box->pref_size[axis];
if (pref_size.kind == UI_SizeKind_Fill)
{
UI_Box *ancestor = box->parent;
f32 ancestor_size = 0;
for (; ancestor; ancestor = ancestor->parent)
{
UI_Size tmp = ancestor->pref_size[axis];
if (tmp.kind == UI_SizeKind_Pixel || tmp.kind == UI_SizeKind_TextContents)
{
ancestor_size = ancestor->solved_dims[axis];
break;
}
}
box->solved_dims[axis] = pref_size.v * ancestor_size;
}
}
}
/* Calculate downwards-dependent sizes */
for (u64 post_index = 0; post_index < boxes_count; ++post_index)
{
UI_Box *box = boxes_post[post_index];
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
{
UI_Size pref_size = box->pref_size[axis];
if (pref_size.kind == UI_SizeKind_Fit)
{
f32 accum = 0;
for (UI_Box *child = box->first; child; child = child->next)
{
if (axis == box->layout_axis)
{
accum += child->solved_dims[axis];
}
else
{
accum = MaxF32(child->solved_dims[axis], accum);
}
}
box->solved_dims[axis] = accum;
}
}
}
#endif
/* Solve violations */
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
for (Axis axis = 0; axis < Axis_CountXY; ++axis)
{
f32 size_accum = 0;
f32 flex_accum = 0;
for (UI_Box *child = box->first; child; child = child->next)
{
f32 size = child->solved_dims[axis];
f32 strictness = child->pref_size[axis].strictness;
f32 flex = size * (1.0 - strictness);
if (axis == box->layout_axis)
{
size_accum += size;
flex_accum += flex;
}
else
{
size_accum = MaxF32(size_accum, size);
flex_accum = MaxF32(flex_accum, flex);
}
}
f32 violation = size_accum - box->solved_dims[axis];
if (violation > 0 && flex_accum > 0)
{
for (UI_Box *child = box->first; child; child = child->next)
{
f32 size = child->solved_dims[axis];
f32 strictness = child->pref_size[axis].strictness;
f32 flex = size * (1.0 - strictness);
f32 chopoff = MinF32(flex, violation * (flex / flex_accum));
f32 new_size = size - chopoff;
child->solved_dims[axis] = new_size;
}
}
}
}
/* Calculate final positions */
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
@ -455,49 +576,6 @@ i64 UI_EndBuild(GPU_Resource *render_target)
box->p1 = AddVec2(box->p0, final_size);
}
/* TODO: Remove this */
#if 0
{
Struct(BoxNode) { BoxNode *next; UI_Box *box; };
BoxNode *first_dfs = 0;
BoxNode *first_dfs_reverse = 0;
/* Constrain layout downwards */
UI_Box *box = g->root_box;
while (box)
{
/* Push to reverse stack */
{
BoxNode *n = PushStruct(scratch.arena, BoxNode);
n->box = box;
StackPush(first_dfs_reverse, n);
}
{
}
/* Push children to dfs stack (in reverse) */
for (UI_Box *child = box->last; child; child = child->prev)
{
BoxNode *n = PushStruct(scratch.arena, BoxNode);
n->box = child;
StackPush(first_dfs, n);
}
/* Pop dfs stack */
if (first_dfs)
{
box = first_dfs->box;
StackPop(first_dfs);
}
else
{
box = 0;
}
}
}
#endif
//////////////////////////////
//- Build render data
@ -515,6 +593,12 @@ i64 UI_EndBuild(GPU_Resource *render_target)
for (u64 pre_index = 0; pre_index < boxes_count; ++pre_index)
{
UI_Box *box = boxes_pre[pre_index];
b32 is_visible = 1;
is_visible = is_visible && ((box->tint & 0xFF000000) != 0);
is_visible = is_visible && (box->p1.x > box->p0.x);
is_visible = is_visible && (box->p1.y > box->p0.y);
if (is_visible)
{
/* Push box rect */
{
UI_RectInstance *rect = PushStruct(g->draw_rects_arena, UI_RectInstance);
@ -572,6 +656,7 @@ i64 UI_EndBuild(GPU_Resource *render_target)
}
}
}
}
//////////////////////////////
//- Render

View File

@ -14,10 +14,10 @@ Struct(UI_Key)
Enum(UI_SizeKind)
{
UI_SizeKind_Children,
UI_SizeKind_Ratio,
UI_SizeKind_Fit,
UI_SizeKind_Fill,
UI_SizeKind_Pixel,
UI_SizeKind_Text,
UI_SizeKind_TextContents,
};
Struct(UI_Size)
@ -226,10 +226,13 @@ UI_Style UI_StyleFromTopNode(UI_StyleKind kind, b32 use);
////////////////////////////////////////////////////////////
//~ Size helpers
#define UI_ChildrenSize(_strictness) ((UI_Size) { .kind = UI_SizeKind_Children, .strictness = strictness_ })
#define UI_RatioSize(_ratio, _strictness) ((UI_Size) { .kind = UI_SizeKind_Ratio, .v = _ratio, .strictness = _strictness })
#define UI_PixelSize(_pixels, _strictness) ((UI_Size) { .kind = UI_SizeKind_Pixel, .v = _pixels, .strictness = _strictness })
#define UI_TextSize(_strictness) ((UI_Size) { .kind = UI_SizeKind_Text, .strictness = _strictness })
#define UI_SIZE(_kind, _v, _s) (UI_Size) { .kind = (_kind), .v = (_v), .strictness = (_s) }
#define UI_PIX(_v, _s) UI_SIZE(UI_SizeKind_Pixel, (_v), (_s))
#define UI_FIT(_s) UI_SIZE(UI_SizeKind_Fit, 0, (_s))
#define UI_FILL(_v, _s) UI_SIZE(UI_SizeKind_Fill, (_v), (_s))
#define UI_TXT(_s) UI_SIZE(UI_SizeKind_TextContents, 0, (_s))
#define UI_EM(_v, _s) UI_SIZE(UI_SizeKind_Pixel, (f32)UI_PeekTop(FontSize) * (_v), (_s))
////////////////////////////////////////////////////////////
//~ Box