diff --git a/profiler/src/profiler/TracyView.cpp b/profiler/src/profiler/TracyView.cpp index f6f437be..6f507b21 100644 --- a/profiler/src/profiler/TracyView.cpp +++ b/profiler/src/profiler/TracyView.cpp @@ -249,6 +249,26 @@ void View::ViewSymbol( const char* fileName, int line, uint64_t baseAddr, uint64 m_sourceView->OpenSymbol( fileName, line, baseAddr, symAddr, m_worker, *this ); } +void View::UpdateThreadOrder() +{ + const auto& threadData = m_worker.GetThreadData(); + if( threadData.size() == m_threadOrder.size() ) return; + + m_threadOrder.reserve( threadData.size() ); + // Only new threads are in the end of the worker's ThreadData vector. + // Threads which get reordered by received thread hints are not new, yet removed from m_threadOrder. + // Therefore, those are kept in m_threadReinsert and are gathered before the remaining new threads. + const size_t numReinsert = m_threadReinsert.size(); + const size_t numNew = threadData.size() - m_threadOrder.size() - numReinsert; + for( size_t i = 0; i < numReinsert + numNew; i++ ) + { + const ThreadData* td = i < numReinsert ? m_threadReinsert[i] : threadData[m_threadOrder.size()]; + auto it = std::find_if( m_threadOrder.begin(), m_threadOrder.end(), [td]( const auto t ) { return td->groupHint < t->groupHint; } ); + m_threadOrder.insert( it, td ); + } + m_threadReinsert.clear(); +} + bool View::ViewDispatch( const char* fileName, int line, uint64_t symAddr ) { if( line == 0 ) diff --git a/profiler/src/profiler/TracyView.hpp b/profiler/src/profiler/TracyView.hpp index 66fcf46f..4aff05f5 100644 --- a/profiler/src/profiler/TracyView.hpp +++ b/profiler/src/profiler/TracyView.hpp @@ -437,6 +437,7 @@ private: void UpdateTitle(); void ValidateSourceRegex(); + void UpdateThreadOrder(); unordered_flat_map m_threadDepthLimit; unordered_flat_map m_visibleMsgThread; diff --git a/profiler/src/profiler/TracyView_FlameGraph.cpp b/profiler/src/profiler/TracyView_FlameGraph.cpp index 387646aa..093af75b 100644 --- a/profiler/src/profiler/TracyView_FlameGraph.cpp +++ b/profiler/src/profiler/TracyView_FlameGraph.cpp @@ -1026,7 +1026,8 @@ void View::DrawFlameGraph() m_flameGraphPan = 0; } - auto& td = m_worker.GetThreadData(); + UpdateThreadOrder(); + const auto& td = m_threadOrder; auto expand = ImGui::TreeNode( ICON_FA_SHUFFLE " Visible threads:" ); ImGui::SameLine(); size_t visibleThreads = 0; diff --git a/profiler/src/profiler/TracyView_Timeline.cpp b/profiler/src/profiler/TracyView_Timeline.cpp index 773d1c16..83b31bcc 100644 --- a/profiler/src/profiler/TracyView_Timeline.cpp +++ b/profiler/src/profiler/TracyView_Timeline.cpp @@ -393,24 +393,7 @@ void View::DrawTimeline() } if( m_vd.drawZones ) { - const auto& threadData = m_worker.GetThreadData(); - if( threadData.size() != m_threadOrder.size() ) - { - m_threadOrder.reserve( threadData.size() ); - // Only new threads are in the end of the worker's ThreadData vector. - // Threads which get reordered by received thread hints are not new, yet removed from m_threadOrder. - // Therefore, those are kept in the m_threadReinsert vector. As such, we will gather first threads from the - // reinsert vector, and afterwards the remaining ones must be new (and thus found at the end of threadData). - size_t numReinsert = m_threadReinsert.size(); - size_t numNew = threadData.size() - m_threadOrder.size() - numReinsert; - for( size_t i = 0; i < numReinsert + numNew; i++ ) - { - const ThreadData *td = i < numReinsert ? m_threadReinsert[i] : threadData[m_threadOrder.size()]; - auto it = std::find_if( m_threadOrder.begin(), m_threadOrder.end(), [td]( const auto t ) { return td->groupHint < t->groupHint; } ); - m_threadOrder.insert( it, td ); - } - m_threadReinsert.clear(); - } + UpdateThreadOrder(); for( const auto& v : m_threadOrder ) { m_tc.AddItem( v );