diff --git a/profiler/src/profiler/TracyView.hpp b/profiler/src/profiler/TracyView.hpp index f39f9cfa..5884ffb5 100644 --- a/profiler/src/profiler/TracyView.hpp +++ b/profiler/src/profiler/TracyView.hpp @@ -51,6 +51,8 @@ struct CpuUsageDraw; struct CpuCtxDraw; struct LockDraw; struct PlotDraw; +struct FlameGraphItem; +struct FlameGraphContext; class View @@ -272,6 +274,7 @@ private: void DrawSourceTooltip( const char* filename, uint32_t line, int before = 3, int after = 3, bool separateTooltip = true ); void DrawWaitStacks(); void DrawFlameGraph(); + void DrawFlameGraphItem( const FlameGraphItem& item, FlameGraphContext& ctx, uint64_t ts, int depth ); void ListMemData( std::vector& vec, const std::function& DrawAddress, int64_t startTime = -1, uint64_t pool = 0 ); diff --git a/profiler/src/profiler/TracyView_FlameGraph.cpp b/profiler/src/profiler/TracyView_FlameGraph.cpp index 4ba7929b..44cb636d 100644 --- a/profiler/src/profiler/TracyView_FlameGraph.cpp +++ b/profiler/src/profiler/TracyView_FlameGraph.cpp @@ -1,4 +1,6 @@ +#include "TracyColor.hpp" #include "TracyEvent.hpp" +#include "TracyImGui.hpp" #include "TracyVector.hpp" #include "TracyView.hpp" #include "tracy_robin_hood.h" @@ -87,6 +89,62 @@ static void SortFlameGraph( Vector& data ) for( auto& v : data ) SortFlameGraph( v.children ); } +struct FlameGraphContext +{ + ImDrawList* draw; + ImVec2 wpos; + ImVec2 dpos; + float ty; + float ostep; + double pxns; + double nxps; +}; + +void View::DrawFlameGraphItem( const FlameGraphItem& item, FlameGraphContext& ctx, uint64_t ts, int depth ) +{ + const auto x0 = ctx.dpos.x + ts * ctx.pxns; + const auto x1 = x0 + item.time * ctx.pxns; + const auto y0 = ctx.dpos.y + depth * ctx.ostep; + const auto y1 = y0 + ctx.ty; + + const auto& srcloc = m_worker.GetSourceLocation( item.srcloc ); + const auto color = GetSrcLocColor( srcloc, depth ); + const auto hiColor = HighlightColor( color ); + const auto darkColor = DarkenColor( color ); + + const auto zsz = x1 - x0; + const char* name = m_worker.GetString( srcloc.name.active ? srcloc.name : srcloc.function ); + + auto tsz = ImGui::CalcTextSize( name ); + if( m_vd.shortenName == ShortenName::Always || ( ( m_vd.shortenName == ShortenName::NoSpace || m_vd.shortenName == ShortenName::NoSpaceAndNormalize ) && tsz.x > zsz ) ) + { + name = ShortenZoneName( m_vd.shortenName, name, tsz, zsz ); + } + + ctx.draw->AddRectFilled( ImVec2( x0, y0 ), ImVec2( x1, y1 ), color ); + DrawLine( ctx.draw, ImVec2( x0, y1 ), ImVec2( x0, y0 ), ImVec2( x1-1, y0 ), hiColor ); + DrawLine( ctx.draw, ImVec2( x0, y1 ), ImVec2( x1-1, y1), ImVec2( x1-1, y0 ), darkColor ); + + if( tsz.x < zsz ) + { + const auto x = ( x1 + x0 - tsz.x ) * 0.5; + DrawTextContrast( ctx.draw, ImVec2( x, y0 ), 0xFFFFFFFF, name ); + } + else + { + ImGui::PushClipRect( ImVec2( x0, y0 ), ImVec2( x1, y1 ), true ); + DrawTextContrast( ctx.draw, ImVec2( x0, y0 ), 0xFFFFFFFF, name ); + ImGui::PopClipRect(); + } + + uint64_t cts = ts; + for( auto& v : item.children ) + { + DrawFlameGraphItem( v, ctx, cts, depth+1 ); + cts += v.time; + } +} + void View::DrawFlameGraph() { const auto scale = GetScale(); @@ -115,6 +173,25 @@ void View::DrawFlameGraph() for( auto& v : data ) zsz += v.time; ImGui::BeginChild( "##flameGraph" ); + + const auto region = ImGui::GetContentRegionAvail(); + FlameGraphContext ctx; + ctx.draw = ImGui::GetWindowDrawList(); + ctx.wpos = ImGui::GetCursorScreenPos(); + ctx.dpos = ctx.wpos + ImVec2( 0.5f, 0.5f ); + ctx.ty = ImGui::GetTextLineHeight(); + ctx.ostep = ctx.ty + 1; + ctx.pxns = region.x / zsz; + ctx.nxps = 1.0 / ctx.pxns; + + ImGui::ItemSize( region ); + uint64_t ts = 0; + for( auto& v : data ) + { + DrawFlameGraphItem( v, ctx, ts, 0 ); + ts += v.time; + } + ImGui::EndChild(); ImGui::End();