From d18f08fb9e7650117361e523b4ecd71f08fe74c9 Mon Sep 17 00:00:00 2001 From: Antoine Mura Date: Mon, 7 Jul 2025 16:51:25 +0200 Subject: [PATCH] Add Thread Timeline Cropping --- profiler/src/profiler/TracyView.hpp | 4 +- .../src/profiler/TracyView_ZoneTimeline.cpp | 128 ++++++++++++++---- 2 files changed, 104 insertions(+), 28 deletions(-) diff --git a/profiler/src/profiler/TracyView.hpp b/profiler/src/profiler/TracyView.hpp index e402a91e..d537ecb4 100644 --- a/profiler/src/profiler/TracyView.hpp +++ b/profiler/src/profiler/TracyView.hpp @@ -244,7 +244,8 @@ private: void DrawTimelineFrames( const FrameData& frames ); void DrawTimeline(); void DrawSampleList( const TimelineContext& ctx, const std::vector& drawList, const Vector& vec, int offset ); - void DrawZoneList( const TimelineContext& ctx, const std::vector& drawList, int offset, uint64_t tid ); + void DrawZoneList( const TimelineContext& ctx, const std::vector& drawList, int offset, uint64_t tid, const int maxDepth, const double margin ); + int DrawThreadCropper( const int depth, const uint64_t tid, const float yPos, const float ostep, const float radius, const float margin, const bool hasCtxSwitches ); void DrawContextSwitchList( const TimelineContext& ctx, const std::vector& drawList, const Vector& ctxSwitch, int offset, int endOffset, bool isFiber ); int DispatchGpuZoneLevel( const Vector>& vec, bool hover, double pxns, int64_t nspx, const ImVec2& wpos, int offset, int depth, uint64_t thread, float yMin, float yMax, int64_t begin, int drift ); template @@ -392,6 +393,7 @@ private: void Attention( bool& alreadyDone ); void UpdateTitle(); + unordered_flat_map m_threadMaxDisplayDepth; unordered_flat_map m_visibleMsgThread; unordered_flat_map m_waitStackThread; unordered_flat_map m_flameGraphThread; diff --git a/profiler/src/profiler/TracyView_ZoneTimeline.cpp b/profiler/src/profiler/TracyView_ZoneTimeline.cpp index 3d66a28a..fc614518 100644 --- a/profiler/src/profiler/TracyView_ZoneTimeline.cpp +++ b/profiler/src/profiler/TracyView_ZoneTimeline.cpp @@ -13,8 +13,6 @@ namespace tracy extern double s_time; -constexpr float MinVisSize = 3; - static tracy_force_inline uint32_t MixGhostColor( uint32_t c0, uint32_t c1 ) { return 0xFF000000 | @@ -56,9 +54,19 @@ void View::DrawThread( const TimelineContext& ctx, const ThreadData& thread, con } const auto yPos = wpos.y + offset; + const float marginLeft = 5.5f; + const float radius = 4.5f * GetScale(); + const float margin = 2 * radius + marginLeft + 3.0f * GetScale(); + + if( depth > 0 ) + { + depth = DrawThreadCropper( depth, thread.id, yPos, ostep, radius, marginLeft, hasCtxSwitch ); + } + const auto* drawList = ImGui::GetWindowDrawList(); + ImGui::PushClipRect( drawList->GetClipRectMin() + ImVec2( margin, 0 ), drawList->GetClipRectMax(), true ); if( !draw.empty() && yPos <= yMax && yPos + ostep * depth >= yMin ) { - DrawZoneList( ctx, draw, offset, thread.id ); + DrawZoneList( ctx, draw, offset, thread.id, depth, margin ); } offset += ostep * depth; @@ -78,6 +86,7 @@ void View::DrawThread( const TimelineContext& ctx, const ThreadData& thread, con const auto lockDepth = DrawLocks( ctx, lockDraw, thread.id, offset, m_nextLockHighlight ); offset += sstep * lockDepth; } + ImGui::PopClipRect(); } void View::DrawThreadMessagesList( const TimelineContext& ctx, const std::vector& drawList, int offset, uint64_t tid ) @@ -203,7 +212,7 @@ void View::DrawThreadOverlays( const ThreadData& thread, const ImVec2& ul, const } } -void View::DrawZoneList( const TimelineContext& ctx, const std::vector& drawList, int _offset, uint64_t tid ) +void View::DrawZoneList( const TimelineContext& ctx, const std::vector& drawList, int _offset, uint64_t tid, const int maxDepth, const double margin ) { auto draw = ImGui::GetWindowDrawList(); const auto w = ctx.w; @@ -219,6 +228,7 @@ void View::DrawZoneList( const TimelineContext& ctx, const std::vector= maxDepth ) continue; const auto offset = _offset + ostep * v.depth; const auto yPos = wpos.y + offset; if( yPos > yMax || yPos + ostep < yMin ) continue; @@ -230,11 +240,12 @@ void View::DrawZoneList( const TimelineContext& ctx, const std::vectorAddRectFilled( wpos + ImVec2( std::max( px0, -10.0 ), offset ), wpos + ImVec2( std::min( std::max( px1, px0+MinVisSize ), double( w + 10 ) ), offset + ty ), color ); - DrawZigZag( draw, wpos + ImVec2( 0, offset + ty/2 ), std::max( px0, -10.0 ), std::min( std::max( px1, px0+MinVisSize ), double( w + 10 ) ), ty/4, DarkenColor( color ) ); - if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( std::max( px0, -10.0 ), offset ), wpos + ImVec2( std::min( std::max( px1, px0+MinVisSize ), double( w + 10 ) ), offset + ty + 1 ) ) ) + const auto px0 = std::max( ( ev.Start() - vStart ) * pxns, margin); + const auto px1 = std::max( ( rend - vStart ) * pxns, margin ); + if( px1 == px0 ) break; + draw->AddRectFilled( wpos + ImVec2( px0, offset ), wpos + ImVec2( std::min( px1, double( w + 10 ) ), offset + ty ), color ); + DrawZigZag( draw, wpos + ImVec2( 0, offset + ty/2 ), px0, std::min( px1, double( w + 10 ) ), ty/4, DarkenColor( color ) ); + if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( std::min( px1, double( w + 10 ) ), offset + ty + 1 ) ) ) { if( IsMouseClickReleased( 1 ) ) m_setRangePopup = RangeSlim { ev.Start(), rend, true }; if( v.num > 1 ) @@ -300,8 +311,9 @@ void View::DrawZoneList( const TimelineContext& ctx, const std::vectorAddRectFilled( wpos + ImVec2( px0, offset ), wpos + ImVec2( px1, offset + tsz.y ), zoneColor.color ); if( zoneColor.highlight ) { @@ -322,7 +334,7 @@ void View::DrawZoneList( const TimelineContext& ctx, const std::vector w - tsz.x ) { ImGui::PushClipRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( px1, offset + tsz.y * 2 ), true ); @@ -335,13 +347,13 @@ void View::DrawZoneList( const TimelineContext& ctx, const std::vectorAddRectFilled( wpos + ImVec2( std::max( px0, -10.0 ), offset ), wpos + ImVec2( std::min( std::max( px1, px0+MinVisSize ), double( w + 10 ) ), offset + ty ), color ); - DrawZigZag( draw, wpos + ImVec2( 0, offset + ty/2 ), std::max( px0, -10.0 ), std::min( std::max( px1, px0+MinVisSize ), double( w + 10 ) ), ty/4, DarkenColor( color ) ); - if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( std::max( px0, -10.0 ), offset ), wpos + ImVec2( std::min( std::max( px1, px0+MinVisSize ), double( w + 10 ) ), offset + ty + 1 ) ) ) + const auto px0 = std::max( ( ev.start.Val() - m_vd.zvStart ) * pxns, margin ); + const auto px1 = std::max( ( rend - m_vd.zvStart ) * pxns, margin ); + if( px0 == px1 ) break; + draw->AddRectFilled( wpos + ImVec2( px0, offset ), wpos + ImVec2( std::min( px0, double( w + 10 ) ), offset + ty ), color ); + DrawZigZag( draw, wpos + ImVec2( 0, offset + ty/2 ), px0, std::min( px0, double( w + 10 ) ), ty/4, DarkenColor( color ) ); + if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( std::min( px0, double( w + 10 ) ), offset + ty + 1 ) ) ) { if( IsMouseClickReleased( 1 ) ) m_setRangePopup = RangeSlim { ev.start.Val(), rend , true }; ImGui::BeginTooltip(); @@ -427,8 +440,9 @@ void View::DrawZoneList( const TimelineContext& ctx, const std::vector w - tsz.x ) { ImGui::PushClipRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( px1, offset + tsz.y * 2 ), true ); @@ -457,13 +471,13 @@ void View::DrawZoneList( const TimelineContext& ctx, const std::vector w - tsz.x ) { ImGui::PushClipRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( px1, offset + tsz.y * 2 ), true ); @@ -539,13 +553,13 @@ void View::DrawZoneList( const TimelineContext& ctx, const std::vectorAddCircle( center, hradius, 0xFFFFFFFF, 0, GetScale() ); + foreground->AddLine( ImVec2( 0, yPos + ( lineId + 1 ) * ostep ), ImVec2( window.x, yPos + ( lineId + 1 ) * ostep ), 0x880000FF, 2.0f * GetScale() ); + if( clicked ) + { + if( isCropped ) + { + if( m_threadMaxDisplayDepth[tid] >= 0 ) + { + if( m_threadMaxDisplayDepth[tid] == lineId + 1 ) + { + isCropped = false; + m_threadMaxDisplayDepth.erase( tid ); + } + else + { + m_threadMaxDisplayDepth[tid] = lineId + 1; + } + } + } + else + { + isCropped = true; + m_threadMaxDisplayDepth[tid] = lineId + 1; + } + } + } + ImU32 color = 0xFF666666; + if( isCropped && lineId + 1 == m_threadMaxDisplayDepth[tid] ) + { + color = 0xFFFFFFFF; + } + if( !isCropped || lineId < m_threadMaxDisplayDepth[tid] ) + { + draw->AddCircleFilled( center, radius, color ); + } + } + draw->AddLine( ImVec2( margin + radius, yPos + ostep * ( hasCtxSwitches ? -0.5 : 0.5 ) - radius ), ImVec2( margin + radius, yPos + ostep * ( ( lineId - 1 ) + 0.5 ) - radius ), 0xFF666666, 2.0f * GetScale() ); + return isCropped ? m_threadMaxDisplayDepth[tid] : depth; +} + }