diff --git a/profiler/src/profiler/TracyView_FlameGraph.cpp b/profiler/src/profiler/TracyView_FlameGraph.cpp index 17212da4..d61cf8e6 100644 --- a/profiler/src/profiler/TracyView_FlameGraph.cpp +++ b/profiler/src/profiler/TracyView_FlameGraph.cpp @@ -1,8 +1,92 @@ +#include "TracyEvent.hpp" +#include "TracyVector.hpp" #include "TracyView.hpp" +#include "tracy_robin_hood.h" namespace tracy { +struct FlameGraphItem +{ + int16_t srcloc; + int64_t time; + Vector children; +}; + +static void BuildFlameGraph( const Worker& worker, Vector& data, const Vector>& zones ) +{ + unordered_flat_map map; + for( size_t i=0; i*)&zones; + for( auto& v : vec ) + { + if( !v.IsEndValid() ) break; + const auto srcloc = v.SrcLoc(); + const auto duration = v.End() - v.Start(); + auto it = map.find( srcloc ); + if( it == map.end() ) + { + map.emplace( srcloc, data.size() ); + data.push_back( FlameGraphItem { srcloc, duration } ); + if( v.HasChildren() ) + { + auto& children = worker.GetZoneChildren( v.Child() ); + BuildFlameGraph( worker, data.back().children, children ); + } + } + else + { + auto& item = data[it->second]; + item.time += duration; + if( v.HasChildren() ) + { + auto& children = worker.GetZoneChildren( v.Child() ); + BuildFlameGraph( worker, item.children, children ); + } + } + } + } + else + { + for( auto& v : zones ) + { + if( !v->IsEndValid() ) break; + const auto srcloc = v->SrcLoc(); + const auto duration = v->End() - v->Start(); + auto it = map.find( srcloc ); + if( it == map.end() ) + { + map.emplace( srcloc, data.size() ); + data.push_back( FlameGraphItem { srcloc, duration } ); + if( v->HasChildren() ) + { + auto& children = worker.GetZoneChildren( v->Child() ); + BuildFlameGraph( worker, data.back().children, children ); + } + } + else + { + auto& item = data[it->second]; + item.time += duration; + if( v->HasChildren() ) + { + auto& children = worker.GetZoneChildren( v->Child() ); + BuildFlameGraph( worker, item.children, children ); + } + } + } + } +} + +static void SortFlameGraph( Vector& data ) +{ + std::sort( data.begin(), data.end(), []( const FlameGraphItem& lhs, const FlameGraphItem& rhs ) { return lhs.time > rhs.time; } ); + for( auto& v : data ) SortFlameGraph( v.children ); +} + void View::DrawFlameGraph() { const auto scale = GetScale();