profiler ruler

This commit is contained in:
jacob 2026-03-31 18:36:58 -05:00
parent db3f0e6b2d
commit d627409f30
3 changed files with 374 additions and 298 deletions

View File

@ -5402,10 +5402,6 @@ void V_TickForever(WaveLaneCtx *lane)
// FIXME: Remove this
i64 highest_current_sample_ns = NsFromSeconds(10);
@ -5569,17 +5565,28 @@ void V_TickForever(WaveLaneCtx *lane)
// TODO: Drag in px units for sharper resolution
if (UI_Downs(main_box, Button_M1) || UI_Downs(main_box, Button_M2) || UI_Downs(main_box, Button_M3))
if (UI_Downs(main_box, Button_M2) || UI_Downs(main_box, Button_M3))
{
profiler->drag_view_ns = profiler->view_ns;
profiler->drag_cursor_px = cursor_px;
}
// Drag ruler
b32 is_measuring = 0;
if (UI_Downs(main_box, Button_M1))
{
profiler->ruler_start_ns = profiler->cursor_ns;
}
if (UI_Held(main_box, Button_M1))
{
// profiler->
is_measuring = 1;
profiler->target_ruler_opacity = 1;
}
else
{
profiler->target_ruler_opacity = 0;
}
profiler->ruler_opacity = LerpF32(profiler->ruler_opacity, profiler->target_ruler_opacity, prof_lerp_rate);
// Drag view
if (UI_Held(main_box, Button_M2) || UI_Held(main_box, Button_M3))
@ -5611,8 +5618,13 @@ void V_TickForever(WaveLaneCtx *lane)
Vec4 profiler_color = theme.col.window_bg;
f32 profiler_opacity = TweakFloat("Profiler opacity", 1, 0, 1);
Vec4 timeline_cursor_color = theme.col.window_bd;
timeline_cursor_color.a = UI_Hot(main_box) * 0.5;
UI_Size timeline_cursor_width = UI_Fnt(0.15, 1);
UI_Key hovered_zone_box = Zi;
V_ZoneDesc *hovered_zone = 0;
f64 ruler_len_ns = 0;
Vec4 main_color = profiler_color;
main_color.r *= 0.75;
@ -5634,6 +5646,110 @@ void V_TickForever(WaveLaneCtx *lane)
UI_BuildSpacer(window_padding, Axis_X);
UI_SetDF(Parent, UI_BuildColumn())
{
//- Collect tracks
i64 highest_sample_ns = 0;
V_ZoneTrack *first_zone_track = 0;
V_ZoneTrack *last_zone_track = 0;
{
RegisteredProfTracksArray prof_tracks = FetchRegisteredProfTracks(frame->arena);
for (u64 track_idx = 0; track_idx < prof_tracks.count; ++track_idx)
{
// FIXME: Remove this
// if (track_idx == 0) continue;
V_ZoneTrack *zone_track = PushStruct(frame->arena, V_ZoneTrack);
DllQueuePush(first_zone_track, last_zone_track, zone_track);
ProfTrack *prof_track = prof_tracks.tracks[track_idx];
// FIXME: Atomic
u64 track_top_sample_seq = Atomic64Fetch(&prof_track->top_sample_seq);
ProfSample *samples = prof_track->samples;
u64 samples_start_seq = track_top_sample_seq - MinU64(track_top_sample_seq, ProfTrackSamplesCap);
u64 samples_end_seq = track_top_sample_seq;
samples_end_seq = MinU64(samples_end_seq, samples_start_seq + 512);
// samples_end_seq = MinU64(samples_end_seq, samples_start_seq + 64);
// samples_end_seq = MinU64(samples_end_seq, samples_start_seq + Kibi(16));
// u64 zones_count = samples_end_seq - samples_start_seq;
// zones_count = MinU64(zones_count, 1000);
// V_ZoneDesc *zones = PushStructs(frame->arena, V_ZoneDesc, zones_count);
//- Create zones
{
// FIXME: Clamp depth
// u64 zone_idx = 0;
u64 depth = 0;
for (u64 sample_seq = 0; sample_seq < samples_end_seq; ++sample_seq)
{
ProfSample *sample = &samples[sample_seq % ProfTrackSamplesCap];
// u64 elapsed_ns = NsFromTsc
i64 time_ns = (sample->tsc - GetStartupTsc()) * GetNsPerTsc();
b32 is_end = !!(sample->flags & ProfSampleFlag_EndZone);
if (is_end)
{
depth -= 1;
V_ZoneDesc *zone = zone_track->last_zone;
// FIXME: OOB
for (; zone->depth > depth;)
{
zone = zone->prev;
}
zone->end_ns = time_ns;
zone->end_sample_seq = sample_seq;
highest_sample_ns = MaxI64(highest_sample_ns, time_ns);
}
else
{
V_ZoneDesc *zone = PushStruct(frame->arena, V_ZoneDesc);
zone->start_ns = time_ns;
DllQueuePush(zone_track->first_zone, zone_track->last_zone, zone);
char *name_cstr = sample->name_cstr_lit;
String name = StringFromCstrNoLimit(name_cstr);
// TODO: Also factor in sample source code location
u64 seed = HashString(name);
// u64 seed = MixU64((u64)name_cstr);
f32 h = (Norm16(seed >> 0) * 1) * 360;
f32 s = TweakFloat("Profiler zone saturation", 0.85, 0, 1);
f32 v = TweakFloat("Profiler zone brightness", 0.50, 0, 1);
zone->color = SrgbFromHsv(h, s, v);
zone->start_sample_seq = sample_seq;
zone->name = name;
zone->depth = depth;
depth += 1;
zone_track->zone_rows_count = MaxU64(depth, zone_track->zone_rows_count);
}
}
}
//- Push zones to rows
zone_track->zone_rows = PushStructs(frame->arena, V_ZoneRow, zone_track->zone_rows_count);
for (V_ZoneDesc *zone = zone_track->first_zone; zone; zone = zone->next)
{
V_ZoneRow *row = &zone_track->zone_rows[zone->depth];
row->count += 1;
DllQueuePushNP(row->first_zone, row->last_zone, zone, next_in_row, prev_in_row);
}
}
}
//- Header
// UI_SetDF(BackgroundColor, Color_Red)
// UI_SetNext(BorderColor, Color_Red);
@ -5656,11 +5772,6 @@ void V_TickForever(WaveLaneCtx *lane)
// UI_BuildDivider(UI_Px(1, 1), theme.col.divider, Axis_Y);
//- Main area
if (do_break)
{
// UI_SetNext(DebugBreakFlags, UI_DebugBreakFlag_BuildFeedback);
}
UI_SetNext(Text, Lit("MAIN"));
UI_SetNext(BackgroundColor, main_color);
UI_SetNext(Height, main_height);
UI_SetNext(Rounding, UI_Rpx(4));
@ -5668,300 +5779,229 @@ void V_TickForever(WaveLaneCtx *lane)
// UI_SetNext(Flags, UI_BoxFlag_CaptureMouse);
UI_SetDF(Parent, UI_BuildColumnEx(main_box))
{
RegisteredProfTracksArray tracks = FetchRegisteredProfTracks(frame->arena);
for (u64 track_idx = 0; track_idx < tracks.count; ++track_idx)
//- Ruler
UI_SetDF(Opacity, profiler->ruler_opacity)
{
// FIXME: Remove this
// if (track_idx != 0) continue;
UI_Key track_box = UI_KeyF("track %F", FmtUint(track_idx));
UI_SetNext(Height, track_height);
// UI_SetNext(Flags, UI_BoxFlag_CaptureMouse);
UI_SetDF(Tag, track_box.v)
UI_SetDF(Parent, UI_BuildColumnEx(track_box))
{
ProfTrack *track = tracks.tracks[track_idx];
f64 ruler_left_ns = MinF64(profiler->ruler_start_ns, profiler->cursor_ns);
f64 ruler_right_ns = MaxF64(profiler->ruler_start_ns, profiler->cursor_ns);
// u64 zones_count = 64;
// V_ZoneDesc *zones = PushStructs(frame->arena, V_ZoneDesc, zones_count);
// for (u64 zone_idx = 0; zone_idx < zones_count; ++zone_idx)
// {
// V_ZoneDesc *zone = &zones[zone_idx];
ruler_len_ns = ruler_right_ns - ruler_left_ns;
f64 ruler_len_px = ruler_len_ns / profiler->ns_per_px;
// // zone->color = VEC4(0.5, 0.2, 0.2, 0.5);
// // zone->color.r += 0.5 * Norm24(MixU64(zone_idx));
f64 ruler_cursor_offset_px = (profiler->ruler_start_ns - profiler->view_ns) / profiler->ns_per_px;
f32 ruler_offset_px = (ruler_left_ns - profiler->view_ns) / profiler->ns_per_px;
Vec2 ruler_cursor_pos = VEC2(ruler_cursor_offset_px, 0);
Vec2 ruler_pos = VEC2(ruler_offset_px, 0);
UI_Size ruler_width = UI_Px(ruler_len_px, 1);
// u64 seed0 = MixU64(zone_idx + 1);
// u64 seed1 = MixU64(seed0);
// u64 seed2 = MixU64(seed1);
// u64 seed3 = MixU64(seed2);
Vec4 ruler_color = VEC4(0.25, 0.25, 0.25, 0.25);
// zone->color = VEC4(Norm24(seed0), Norm24(seed1), Norm24(seed2), 1);
// zone->color.r += (1.0 - zone->color.r) * 0.25;
// zone->start_ns = NsFromSeconds(zone_idx * 2);
// zone->end_ns = NsFromSeconds(zone_idx * 2 + 1);
// };
// // Binary search to find samples range
// // FIXME: Atomic
// ProfSample *samples = track->samples;
// u64 samples_start_seq = track->top_sample_seq - MinU64(track->top_sample_seq, ProfTrackSamplesCap);
// u64 samples_end_seq = track->new_sample_seq;
// {
// // i64 search_seq = samples_start_seq + (samples_end_seq - samples_start_seq) / 2;
// i64 search_start_seq = samples_start_seq;
// i64 search_end_seq = samples_end_seq;
// while (search_end_seq > search_start_seq)
// {
// if (samples[search_start_seq % ProfTrackSamplesCap].
// }
// samples_start_seq = search_start_seq;
// }
// FIXME: Atomic
u64 track_top_sample_seq = Atomic64Fetch(&track->top_sample_seq);
ProfSample *samples = track->samples;
u64 samples_start_seq = track_top_sample_seq - MinU64(track_top_sample_seq, ProfTrackSamplesCap);
u64 samples_end_seq = track_top_sample_seq;
samples_end_seq = MinU64(samples_end_seq, samples_start_seq + 512);
// samples_end_seq = MinU64(samples_end_seq, samples_start_seq + 64);
// samples_end_seq = MinU64(samples_end_seq, samples_start_seq + Kibi(16));
// u64 zones_count = samples_end_seq - samples_start_seq;
// zones_count = MinU64(zones_count, 1000);
// V_ZoneDesc *zones = PushStructs(frame->arena, V_ZoneDesc, zones_count);
//- Create zones
V_ZoneDesc *first_zone = 0;
V_ZoneDesc *last_zone = 0;
u64 zone_rows_count = 0;
// Ruler rect
{
// FIXME: Clamp depth
// u64 zone_idx = 0;
u64 depth = 0;
for (u64 sample_seq = 0; sample_seq < samples_end_seq; ++sample_seq)
{
ProfSample *sample = &samples[sample_seq % ProfTrackSamplesCap];
// u64 elapsed_ns = NsFromTsc
i64 time_ns = (sample->tsc - GetStartupTsc()) * GetNsPerTsc();
b32 is_end = !!(sample->flags & ProfSampleFlag_EndZone);
if (is_end)
{
depth -= 1;
V_ZoneDesc *zone = last_zone;
// FIXME: OOB
for (; zone->depth > depth;)
{
zone = zone->prev;
}
zone->end_ns = time_ns;
zone->end_sample_seq = sample_seq;
}
else
{
V_ZoneDesc *zone = PushStruct(frame->arena, V_ZoneDesc);
zone->start_ns = time_ns;
DllQueuePush(first_zone, last_zone, zone);
char *name_cstr = sample->name_cstr_lit;
String name = StringFromCstrNoLimit(name_cstr);
// TODO: Also factor in sample source code location
u64 seed = HashString(name);
// u64 seed = MixU64((u64)name_cstr);
f32 h = (Norm16(seed >> 0) * 1) * 360;
f32 s = TweakFloat("Profiler zone saturation", 0.85, 0, 1);
f32 v = TweakFloat("Profiler zone brightness", 0.50, 0, 1);
zone->color = SrgbFromHsv(h, s, v);
zone->start_sample_seq = sample_seq;
zone->name = name;
zone->depth = depth;
depth += 1;
zone_rows_count = MaxU64(depth, zone_rows_count);
}
}
// UI_SetNext(BorderSize, 1);
// UI_SetNext(BorderColor, Color_White);
// UI_SetDF(Opacity, profiler->ruler_opacity)
UI_SetNext(Width, ruler_width);
UI_SetNext(FloatingPos, ruler_pos);
UI_SetNext(BackgroundColor, ruler_color);
UI_SetNext(Flags, UI_BoxFlag_Floating);
UI_BuildBoxEx(UI_KeyF("ruler"));
}
Struct(V_ZoneRow)
// Ruler cursor
{
u64 count;
V_ZoneDesc *first_zone;
V_ZoneDesc *last_zone;
};
//- Push zones to rows
V_ZoneRow *zone_rows = PushStructs(frame->arena, V_ZoneRow, zone_rows_count);
for (V_ZoneDesc *zone = first_zone; zone; zone = zone->next)
{
V_ZoneRow *row = &zone_rows[zone->depth];
row->count += 1;
DllQueuePushNP(row->first_zone, row->last_zone, zone, next_in_row, prev_in_row);
// UI_SetNext(BorderSize, 1);
// UI_SetNext(BorderColor, Color_White);
UI_SetNext(BackgroundColor, timeline_cursor_color);
UI_SetNext(Width, timeline_cursor_width);
UI_SetNext(FloatingPos, ruler_cursor_pos);
UI_SetNext(Anchor, UI_Region_Top);
UI_SetNext(Flags, UI_BoxFlag_Floating);
UI_BuildBoxEx(UI_KeyF("ruler cursor"));
}
}
}
//- Zone tracks
{
u64 zone_track_idx = 0;
for (V_ZoneTrack *zone_track = first_zone_track; zone_track; zone_track = zone_track->next)
{
// FIXME: Remove this
// if (track_idx != 0) continue;
UI_Key track_box = UI_KeyF("track %F", FmtUint(zone_track_idx));
UI_SetNext(Height, track_height);
// UI_SetNext(Flags, UI_BoxFlag_CaptureMouse);
UI_SetDF(Tag, track_box.v)
UI_SetDF(Parent, UI_BuildColumnEx(track_box))
{
for (u64 zone_row_idx = 0; zone_row_idx < zone_rows_count; ++zone_row_idx)
{
V_ZoneRow *row = &zone_rows[zone_row_idx];
//- Zone row
// UI_SetNext(Height, zone_height);
UI_SetNext(Height, zone_height);
UI_SetDF(Parent, UI_BuildRow())
// // Binary search to find samples range
// // FIXME: Atomic
// ProfSample *samples = track->samples;
// u64 samples_start_seq = track->top_sample_seq - MinU64(track->top_sample_seq, ProfTrackSamplesCap);
// u64 samples_end_seq = track->new_sample_seq;
// {
// // i64 search_seq = samples_start_seq + (samples_end_seq - samples_start_seq) / 2;
// i64 search_start_seq = samples_start_seq;
// i64 search_end_seq = samples_end_seq;
// while (search_end_seq > search_start_seq)
// {
// if (samples[search_start_seq % ProfTrackSamplesCap].
// }
// samples_start_seq = search_start_seq;
// }
// Build zone rows
{
for (u64 zone_row_idx = 0; zone_row_idx < zone_track->zone_rows_count; ++zone_row_idx)
{
//- Zones in row
u64 zone_idx = 0;
for (V_ZoneDesc *zone = row->first_zone; zone; zone = zone->next_in_row)
V_ZoneRow *row = &zone_track->zone_rows[zone_row_idx];
//- Zone row
// UI_SetNext(Height, zone_height);
UI_SetNext(Height, zone_height);
UI_SetDF(Parent, UI_BuildRow())
{
if (zone->end_ns > zone->start_ns)
//- Zones in row
u64 zone_idx = 0;
for (V_ZoneDesc *zone = row->first_zone; zone; zone = zone->next_in_row)
{
UI_Key zone_box = UI_KeyF("Zone %F", FmtUint(zone->start_sample_seq));
if (UI_HotAbsolute(zone_box))
if (zone->end_ns > zone->start_ns)
{
hovered_zone_box = zone_box;
hovered_zone = zone;
UI_Key zone_box = UI_KeyF("Zone %F", FmtUint(zone->start_sample_seq));
if (UI_HotAbsolute(zone_box))
{
hovered_zone_box = zone_box;
hovered_zone = zone;
}
// TODO: Dim in HSV space
Vec4 zone_color = zone->color;
// Vec4 zone_color_bd = Zi;
Vec4 zone_color_bd = zone_color;
// Vec4 zone_color_dim = VEC4(0.15, 0.15, 0.15, 0);
// zone_color_bd.r -= zone_color_dim.r;
// zone_color_bd.g -= zone_color_dim.g;
// zone_color_bd.b -= zone_color_dim.b;
zone_color_bd = MulVec4(zone_color_bd, 0.65);
zone_color_bd.a = 1;
Vec4 zone_text_color = UI_Top(TextColor);
zone_text_color.a *= 0.75;
// zone_color_bd = LerpSrgb(zone_color_bd, theme.col.button_selected, UI_Hot(zone_box));
// zone_color_bd = LerpSrgb(zone_color_bd, theme.col.button_active, UI_Hot(zone_box));
zone_color_bd = LerpSrgb(zone_color_bd, Color_White, UI_Hot(zone_box));
f64 zone_len_ns = zone->end_ns - zone->start_ns;
f64 zone_len_px = zone_len_ns / profiler->ns_per_px;
f32 zone_offset_px = (zone->start_ns - profiler->view_ns) / profiler->ns_per_px;
Vec2 zone_pos = VEC2(zone_offset_px, 0);
UI_Size zone_width = UI_Px(zone_len_px, 1);
// TODO: Remove this
UI_SetNext(Text, StringF(frame->arena, "ZONE %F", FmtUint(zone_idx)));
// if (do_break && UI_IsMouseHovered(zone_box))
if (do_break && zone_idx == 0)
{
// UI_SetNext(DebugBreakFlags, UI_DebugBreakFlag_BuildFeedback | UI_DebugBreakFlag_CheckCursorHover);
}
UI_SetNext(Width, zone_width);
UI_SetNext(Height, UI_Grow(1, 0));
UI_SetNext(BackgroundColor, zone_color);
UI_SetNext(BorderColor, zone_color_bd);
UI_SetNext(BorderSize, 1);
UI_SetNext(FloatingPos, zone_pos);
UI_SetNext(ChildAlignment, UI_Region_Center);
UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_DontClampFloatingX | UI_BoxFlag_DontClampFloatingY | UI_BoxFlag_CaptureMouse | UI_BoxFlag_Scissor);
// UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_DontClampFloatingX | UI_BoxFlag_DontClampFloatingY);
UI_SetDF(Parent, UI_BuildRowEx(zone_box))
{
UI_BuildSpacer(UI_Px(zone_text_padding_px, 0.25), Axis_X);
UI_SetNext(Width, UI_Shrink(1, 0));
UI_SetNext(ChildAlignment, UI_Region_Left);
UI_SetNext(FontSize, UI_Top(FontSize) * theme.h5);
UI_SetNext(TextColor, zone_text_color);
UI_SetNext(Text, zone->name);
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_DontTruncateText);
// UI_SetNext(Flags, UI_BoxFlag_DrawText);
UI_BuildRow();
UI_BuildSpacer(UI_Px(zone_text_padding_px, 1), Axis_X);
}
zone_idx += 1;
}
// TODO: Dim in HSV space
Vec4 zone_color = zone->color;
// Vec4 zone_color_bd = Zi;
Vec4 zone_color_bd = zone_color;
// Vec4 zone_color_dim = VEC4(0.15, 0.15, 0.15, 0);
// zone_color_bd.r -= zone_color_dim.r;
// zone_color_bd.g -= zone_color_dim.g;
// zone_color_bd.b -= zone_color_dim.b;
zone_color_bd = MulVec4(zone_color_bd, 0.65);
zone_color_bd.a = 1;
Vec4 zone_text_color = UI_Top(TextColor);
zone_text_color.a *= 0.75;
// zone_color_bd = LerpSrgb(zone_color_bd, theme.col.button_selected, UI_Hot(zone_box));
// zone_color_bd = LerpSrgb(zone_color_bd, theme.col.button_active, UI_Hot(zone_box));
zone_color_bd = LerpSrgb(zone_color_bd, Color_White, UI_Hot(zone_box));
f64 zone_len_ns = zone->end_ns - zone->start_ns;
f64 zone_len_px = zone_len_ns / profiler->ns_per_px;
f32 zone_offset_px = (zone->start_ns - profiler->view_ns) / profiler->ns_per_px;
Vec2 zone_pos = VEC2(zone_offset_px, 0);
UI_Size zone_width = UI_Px(zone_len_px, 1);
UI_SetNext(Text, StringF(frame->arena, "ZONE %F", FmtUint(zone_idx)));
// if (do_break && UI_IsMouseHovered(zone_box))
if (do_break && zone_idx == 0)
{
// UI_SetNext(DebugBreakFlags, UI_DebugBreakFlag_BuildFeedback | UI_DebugBreakFlag_CheckCursorHover);
}
UI_SetNext(Width, zone_width);
UI_SetNext(Height, UI_Grow(1, 0));
UI_SetNext(BackgroundColor, zone_color);
UI_SetNext(BorderColor, zone_color_bd);
UI_SetNext(BorderSize, 1);
UI_SetNext(FloatingPos, zone_pos);
UI_SetNext(ChildAlignment, UI_Region_Center);
UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_DontClampFloatingX | UI_BoxFlag_DontClampFloatingY | UI_BoxFlag_CaptureMouse | UI_BoxFlag_Scissor);
// UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_DontClampFloatingX | UI_BoxFlag_DontClampFloatingY);
UI_SetDF(Parent, UI_BuildRowEx(zone_box))
{
UI_BuildSpacer(UI_Px(zone_text_padding_px, 0.25), Axis_X);
UI_SetNext(Width, UI_Shrink(1, 0));
UI_SetNext(ChildAlignment, UI_Region_Left);
UI_SetNext(FontSize, UI_Top(FontSize) * theme.h5);
UI_SetNext(TextColor, zone_text_color);
UI_SetNext(Text, zone->name);
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_DontTruncateText);
// UI_SetNext(Flags, UI_BoxFlag_DrawText);
UI_BuildRow();
UI_BuildSpacer(UI_Px(zone_text_padding_px, 1), Axis_X);
}
zone_idx += 1;
}
}
}
}
// for (u64 zone_idx = 0; zone_idx < zones_count; ++zone_idx)
// {
// V_ZoneDesc *zone = &zones[zone_idx];
// UI_Key zone_box = UI_KeyF("Zone %F", FmtUint(zone_idx));
// Vec4 zone_color = zone->color;
// zone_color = LerpSrgb(zone_color, Color_Cyan, UI_Hot(zone_box));
// // Vec4 zone_color_bd = Zi;
// // zone_color_bd
// i64 zone_len_ns = zone->end_ns - zone->start_ns;
// f32 zone_len_px = zone_len_ns / profiler->ns_per_px;
// // i6
// f32 zone_offset_px = (zone->start_ns - profiler->view_ns) / profiler->ns_per_px;
// Vec2 zone_pos = VEC2(zone_offset_px, 0);
// UI_Size zone_width = UI_Px(zone_len_px, 1);
// UI_SetNext(Text, StringF(frame->arena, "ZONE %F", FmtUint(zone_idx)));
// // if (do_break && UI_IsMouseHovered(zone_box))
// if (do_break && zone_idx == 0)
// {
// UI_SetNext(DebugBreakFlags, UI_DebugBreakFlag_BuildFeedback | UI_DebugBreakFlag_CheckCursorHover);
// }
// UI_SetNext(Width, zone_width);
// UI_SetNext(Height, zone_height);
// UI_SetNext(BackgroundColor, zone_color);
// UI_SetNext(FloatingPos, zone_pos);
// UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_DontClampFloatingX | UI_BoxFlag_DontClampFloatingY | UI_BoxFlag_CaptureMouse);
// // UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_DontClampFloatingX | UI_BoxFlag_DontClampFloatingY);
// UI_SetDF(Parent, UI_BuildBoxEx(zone_box))
// {
// }
// }
}
// for (u64 zone_idx = 0; zone_idx < zones_count; ++zone_idx)
// {
// V_ZoneDesc *zone = &zones[zone_idx];
// UI_Key zone_box = UI_KeyF("Zone %F", FmtUint(zone_idx));
// Vec4 zone_color = zone->color;
// zone_color = LerpSrgb(zone_color, Color_Cyan, UI_Hot(zone_box));
// // Vec4 zone_color_bd = Zi;
// // zone_color_bd
// i64 zone_len_ns = zone->end_ns - zone->start_ns;
// f32 zone_len_px = zone_len_ns / profiler->ns_per_px;
// // i6
// f32 zone_offset_px = (zone->start_ns - profiler->view_ns) / profiler->ns_per_px;
// Vec2 zone_pos = VEC2(zone_offset_px, 0);
// UI_Size zone_width = UI_Px(zone_len_px, 1);
// UI_SetNext(Text, StringF(frame->arena, "ZONE %F", FmtUint(zone_idx)));
// // if (do_break && UI_IsMouseHovered(zone_box))
// if (do_break && zone_idx == 0)
// {
// UI_SetNext(DebugBreakFlags, UI_DebugBreakFlag_BuildFeedback | UI_DebugBreakFlag_CheckCursorHover);
// }
// UI_SetNext(Width, zone_width);
// UI_SetNext(Height, zone_height);
// UI_SetNext(BackgroundColor, zone_color);
// UI_SetNext(FloatingPos, zone_pos);
// UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_DontClampFloatingX | UI_BoxFlag_DontClampFloatingY | UI_BoxFlag_CaptureMouse);
// // UI_SetNext(Flags, UI_BoxFlag_Floating | UI_BoxFlag_DontClampFloatingX | UI_BoxFlag_DontClampFloatingY);
// UI_SetDF(Parent, UI_BuildBoxEx(zone_box))
// {
// }
// }
zone_track_idx += 1;
}
}
@ -5977,10 +6017,8 @@ void V_TickForever(WaveLaneCtx *lane)
{
// Vec2 timeline_cursor_pos = VEC2(old_cursor_offset_px, 0);
Vec2 timeline_cursor_pos = VEC2((profiler->cursor_ns - profiler->view_ns) / profiler->ns_per_px, 0);
Vec4 timeline_cursor_color = theme.col.window_bd;
timeline_cursor_color.a = UI_Hot(main_box) * 0.5;
UI_SetNext(Width, UI_Fnt(0.15, 1));
UI_SetNext(Width, timeline_cursor_width);
UI_SetNext(Height, UI_Grow(1, 0));
UI_SetNext(BackgroundColor, timeline_cursor_color);
UI_SetNext(FloatingPos, timeline_cursor_pos);
@ -5993,7 +6031,7 @@ void V_TickForever(WaveLaneCtx *lane)
UI_Key tooltip_box = UI_KeyF("tooltip");
Vec2 tooltip_pos = SubVec2(frame->screen_cursor, UI_Anchor(main_box));
tooltip_pos = AddVec2(tooltip_pos, theme.tooltip_offset_px);
f32 tooltip_opacity = 0.75;
f32 tooltip_opacity = 0.95;
// UI_Key tooltip_box = UI_KeyF("tooltip");
@ -6005,18 +6043,18 @@ void V_TickForever(WaveLaneCtx *lane)
UI_SetNext(Opacity, tooltip_opacity);
UI_SetNext(BackgroundColor, theme.col.window_bg);
UI_SetNext(BorderColor, theme.col.window_bd);
UI_SetNext(Rounding, UI_Rpx(theme.rounding * 5));
UI_SetNext(BorderSize, 1);
// UI_SetNext(Width, UI_Fnt(15, 0));
// UI_SetNext(Height, UI_Fnt(15, 0));
UI_SetNext(Width, UI_Shrink(0, 1));
UI_SetNext(Height, UI_Shrink(0, 1));
UI_SetNext(Anchor, UI_Region_TopLeft);
UI_SetNext(Opacity, tooltip_opacity);
UI_SetNext(FloatingPos, tooltip_pos);
UI_SetNext(Flags, UI_BoxFlag_Floating);
UI_SetDF(Width, UI_Shrink(0, 1))
UI_SetDF(Height, UI_Shrink(0, 1))
UI_SetDF(Parent, UI_BuildRowEx(tooltip_box))
{
UI_BuildSpacer(window_padding, Axis_X);
@ -6025,10 +6063,16 @@ void V_TickForever(WaveLaneCtx *lane)
UI_SetNext(Height, UI_Shrink(0, 1));
UI_SetDF(Parent, UI_BuildColumn())
{
UI_BuildSpacer(window_padding, Axis_Y);
if (is_measuring && ruler_len_ns != 0)
{
UI_SetNext(TextColor, theme.col.positive);
UI_BuildLabelF("%F", FmtTimeNs(ruler_len_ns, .p = 3));
}
if (hovered_zone)
{
UI_BuildSpacer(window_padding, Axis_Y);
V_ZoneDesc *zone = hovered_zone;
// UI_BuildLabelF("Hi!!");
i64 zone_elapsed_ns = zone->end_ns - zone->start_ns;
@ -6036,10 +6080,17 @@ void V_TickForever(WaveLaneCtx *lane)
// UI_BuildLabelF("%Fms", FmtFloat(MsFromNs(zone_elapsed_ns), .p = 3));
UI_BuildLabelF("%F", FmtTimeNs(zone_elapsed_ns, .p = 3));
UI_SetDF(Parent, UI_BuildRow())
{
UI_SetNext(TextColor, theme.col.hint);
UI_BuildLabelF("%F: ", FmtString(zone->name));
UI_BuildSpacer(window_padding, Axis_Y);
UI_BuildLabelF("%F", FmtTimeNs(zone_elapsed_ns, .p = 3));
}
}
UI_BuildSpacer(window_padding, Axis_Y);
}
UI_BuildSpacer(window_padding, Axis_X);
}

View File

@ -258,22 +258,43 @@ Struct(V_ZoneDesc)
i64 end_ns;
};
Struct(V_ZoneRow)
{
u64 count;
V_ZoneDesc *first_zone;
V_ZoneDesc *last_zone;
};
Struct(V_ZoneTrack)
{
V_ZoneTrack *next;
V_ZoneTrack *prev;
V_ZoneDesc *first_zone;
V_ZoneDesc *last_zone;
u64 zone_rows_count;
V_ZoneRow *zone_rows;
};
Struct(V_Profiler)
{
Vec2 graph_dims;
b32 is_showing;
// TODO: Per track data
f64 target_view_ns;
f64 view_ns;
f64 drag_view_ns;
f64 drag_cursor_px;
f32 target_ruler_opacity;
f64 ruler_start_ns;
f32 ruler_opacity;
f64 target_ns_per_px;
f64 target_view_ns;
f64 ns_per_px;
f64 cursor_ns;
f64 ns_per_px;
f64 view_ns;
f64 drag_cursor_px;
};
////////////////////////////////////////////////////////////

View File

@ -1822,6 +1822,9 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
Vec4 final_tint_lin = LinearFromSrgb(box->desc.tint);
final_tint_lin.a *= box->solved_opacity;
Vec4 final_border_color_lin = LinearFromSrgb(box->desc.border_color);
final_border_color_lin.a *= box->solved_opacity;
Vec4 final_text_color_lin = LinearFromSrgb(box->desc.text_color);
final_text_color_lin.a *= box->desc.opacity;
final_text_color_lin = MulVec4Vec4(final_text_color_lin, final_tint_lin);
@ -1829,6 +1832,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
f32 alpha_cull_threshold = 0.0025;
// TODO: Check that sprite image is not empty
// TODO: Handle border tint
b32 should_upload_box = 1;
b32 should_upload_text = 1;
should_upload_box = should_upload_box && (final_tint_lin.a >= alpha_cull_threshold);
@ -1859,7 +1863,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
rect->bounds = box->screen_rect;
rect->scissor = box->solved_scissor;
rect->background_lin = LinearFromSrgb(box->desc.background_color);
rect->border_lin = LinearFromSrgb(box->desc.border_color);
rect->border_lin = final_border_color_lin;
rect->debug_lin = debug_lin;
rect->tint_lin = final_tint_lin;
rect->border_size = box->desc.border_size;