From d627409f30912d11d07dadf28eb02a162e80855b Mon Sep 17 00:00:00 2001 From: jacob Date: Tue, 31 Mar 2026 18:36:58 -0500 Subject: [PATCH] profiler ruler --- src/pp/pp_vis/pp_vis_core.c | 633 +++++++++++++++++++----------------- src/pp/pp_vis/pp_vis_core.h | 33 +- src/ui/ui_core.c | 6 +- 3 files changed, 374 insertions(+), 298 deletions(-) diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 5d6ade6f..48354678 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -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); } diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index 56d69ffe..7c8743b7 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -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; }; //////////////////////////////////////////////////////////// diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index abe345b9..71cd1908 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -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;