diff --git a/profiler/build/win32/Tracy.vcxproj b/profiler/build/win32/Tracy.vcxproj index d598a5ac..321c9623 100644 --- a/profiler/build/win32/Tracy.vcxproj +++ b/profiler/build/win32/Tracy.vcxproj @@ -139,6 +139,7 @@ + diff --git a/profiler/build/win32/Tracy.vcxproj.filters b/profiler/build/win32/Tracy.vcxproj.filters index 25b97ceb..a0eeed43 100644 --- a/profiler/build/win32/Tracy.vcxproj.filters +++ b/profiler/build/win32/Tracy.vcxproj.filters @@ -276,6 +276,9 @@ server + + server + diff --git a/server/TracyView.cpp b/server/TracyView.cpp index 0860b75c..08807a28 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -7951,305 +7951,6 @@ void View::DrawLockInfoWindow() if( !visible ) m_lockInfoWindow = InvalidId; } -void View::DrawCpuDataWindow() -{ - const auto scale = GetScale(); - ImGui::SetNextWindowSize( ImVec2( 700 * scale, 800 * scale ), ImGuiCond_FirstUseEver ); - ImGui::Begin( "CPU data", &m_showCpuDataWindow ); - if( ImGui::GetCurrentWindowRead()->SkipItems ) { ImGui::End(); return; } - - struct PidData - { - std::vector tids; - CpuThreadData data; - }; - - const auto& ctd = m_worker.GetCpuThreadData(); - unordered_flat_map pids; - for( auto& v : ctd ) - { - uint64_t pid = m_worker.GetPidFromTid( v.first ); - auto it = pids.find( pid ); - if( it == pids.end() ) - { - it = pids.emplace( pid, PidData {} ).first; - } - it->second.tids.emplace_back( v.first ); - it->second.data.runningTime += v.second.runningTime; - it->second.data.runningRegions += v.second.runningRegions; - it->second.data.migrations += v.second.migrations; - } - - TextFocused( "Tracked threads:", RealToString( ctd.size() ) ); - ImGui::SameLine(); - TextFocused( "Tracked processes:", RealToString( pids.size() ) ); - ImGui::Separator(); - ImGui::BeginChild( "##cpudata" ); - if( ImGui::BeginTable( "##cpudata", 5, ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable | ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_ScrollY ) ) - { - ImGui::TableSetupScrollFreeze( 0, 1 ); - ImGui::TableSetupColumn( "PID/TID", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize ); - ImGui::TableSetupColumn( "Name" ); - ImGui::TableSetupColumn( "Running time", ImGuiTableColumnFlags_PreferSortDescending ); - ImGui::TableSetupColumn( "Running regions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize ); - ImGui::TableSetupColumn( "CPU migrations", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize ); - ImGui::TableHeadersRow(); - - std::vector::iterator> psort; - psort.reserve( pids.size() ); - for( auto it = pids.begin(); it != pids.end(); ++it ) psort.emplace_back( it ); - const auto& sortspec = *ImGui::TableGetSortSpecs()->Specs; - switch( sortspec.ColumnIndex ) - { - case 0: - if( sortspec.SortDirection == ImGuiSortDirection_Descending ) - { - pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->first > r->first; } ); - } - else - { - pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->first < r->first; } ); - } - break; - case 1: - if( sortspec.SortDirection == ImGuiSortDirection_Descending ) - { - pdqsort_branchless( psort.begin(), psort.end(), [this] ( const auto& l, const auto& r ) { return strcmp( m_worker.GetExternalName( l->second.tids[0] ).first, m_worker.GetExternalName( r->second.tids[0] ).first ) > 0; } ); - } - else - { - pdqsort_branchless( psort.begin(), psort.end(), [this] ( const auto& l, const auto& r ) { return strcmp( m_worker.GetExternalName( l->second.tids[0] ).first, m_worker.GetExternalName( r->second.tids[0] ).first ) < 0; } ); - } - break; - case 2: - if( sortspec.SortDirection == ImGuiSortDirection_Descending ) - { - pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->second.data.runningTime > r->second.data.runningTime; } ); - } - else - { - pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->second.data.runningTime < r->second.data.runningTime; } ); - } - break; - case 3: - if( sortspec.SortDirection == ImGuiSortDirection_Descending ) - { - pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->second.data.runningRegions > r->second.data.runningRegions; } ); - } - else - { - pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->second.data.runningRegions < r->second.data.runningRegions; } ); - } - break; - case 4: - if( sortspec.SortDirection == ImGuiSortDirection_Descending ) - { - pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->second.data.migrations > r->second.data.migrations; } ); - } - else - { - pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->second.data.migrations < r->second.data.migrations; } ); - } - break; - default: - assert( false ); - break; - } - - const auto thisPid = m_worker.GetPid(); - const auto rtimespan = 1.0 / m_worker.GetLastTime(); - const auto ty = ImGui::GetTextLineHeight(); - - auto& style = ImGui::GetStyle(); - const auto framePaddingY = style.FramePadding.y; - for( auto& pidit : psort ) - { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - - char buf[128]; - auto& pid = *pidit; - const auto pidMatch = thisPid != 0 && thisPid == pid.first; - auto name = m_worker.GetExternalName( pid.second.tids[0] ).first; - if( pidMatch ) - { - name = m_worker.GetCaptureProgram().c_str(); - ImGui::PushStyleColor( ImGuiCol_Text, ImVec4( 0.2f, 1.0f, 0.2f, 1.0f ) ); - } - const auto pidtxt = pid.first == 0 ? "Unknown" : RealToString( pid.first ); - const auto expand = ImGui::TreeNode( pidtxt ); - if( ImGui::IsItemHovered() ) - { - if( pidMatch ) - { - m_drawThreadMigrations = pid.first; - m_cpuDataThread = pid.first; - } - m_drawThreadHighlight = pid.first; - } - const auto tsz = pid.second.tids.size(); - if( tsz > 1 ) - { - ImGui::SameLine(); - ImGui::TextDisabled( "(%s)", RealToString( tsz ) ); - } - ImGui::TableNextColumn(); - ImGui::TextUnformatted( pid.first == 0 ? "???" : name ); - if( ImGui::IsItemHovered() ) - { - if( pidMatch ) - { - m_drawThreadMigrations = pid.first; - m_cpuDataThread = pid.first; - } - m_drawThreadHighlight = pid.first; - } - ImGui::TableNextColumn(); - PrintStringPercent( buf, TimeToString( pid.second.data.runningTime ), double( pid.second.data.runningTime ) * rtimespan * 100 ); - style.FramePadding.y = 0; - ImGui::ProgressBar( double( pid.second.data.runningTime ) * rtimespan, ImVec2( -1, ty ), buf ); - style.FramePadding.y = framePaddingY; - ImGui::TableNextColumn(); - ImGui::TextUnformatted( RealToString( pid.second.data.runningRegions ) ); - ImGui::TableNextColumn(); - ImGui::TextUnformatted( RealToString( pid.second.data.migrations ) ); - ImGui::SameLine(); - PrintStringPercent( buf, double( pid.second.data.migrations ) / pid.second.data.runningRegions * 100 ); - TextDisabledUnformatted( buf ); - if( expand ) - { - ImGui::Separator(); - switch( sortspec.ColumnIndex ) - { - case 0: - if( sortspec.SortDirection == ImGuiSortDirection_Descending ) - { - pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), []( const auto& l, const auto& r ) { return l > r; } ); - } - else - { - pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end() ); - } - break; - case 1: - if( sortspec.SortDirection == ImGuiSortDirection_Descending ) - { - pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [this] ( const auto& l, const auto& r ) { return strcmp( m_worker.GetExternalName( l ).second, m_worker.GetExternalName( r ).second ) > 0; } ); - } - else - { - pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [this] ( const auto& l, const auto& r ) { return strcmp( m_worker.GetExternalName( l ).second, m_worker.GetExternalName( r ).second ) < 0; } ); - } - break; - case 2: - if( sortspec.SortDirection == ImGuiSortDirection_Descending ) - { - pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [&ctd] ( const auto& l, const auto& r ) { return ctd.find( l )->second.runningTime > ctd.find( r )->second.runningTime; } ); - } - else - { - pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [&ctd] ( const auto& l, const auto& r ) { return ctd.find( l )->second.runningTime < ctd.find( r )->second.runningTime; } ); - } - break; - case 3: - if( sortspec.SortDirection == ImGuiSortDirection_Descending ) - { - pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [&ctd] ( const auto& l, const auto& r ) { return ctd.find( l )->second.runningRegions > ctd.find( r )->second.runningRegions; } ); - } - else - { - pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [&ctd] ( const auto& l, const auto& r ) { return ctd.find( l )->second.runningRegions < ctd.find( r )->second.runningRegions; } ); - } - break; - case 4: - if( sortspec.SortDirection == ImGuiSortDirection_Descending ) - { - pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [&ctd] ( const auto& l, const auto& r ) { return ctd.find( l )->second.migrations > ctd.find( r )->second.migrations; } ); - } - else - { - pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [&ctd] ( const auto& l, const auto& r ) { return ctd.find( l )->second.migrations < ctd.find( r )->second.migrations; } ); - } - break; - default: - assert( false ); - break; - } - for( auto& tid : pid.second.tids ) - { - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - - const auto tidMatch = pidMatch && m_worker.IsThreadLocal( tid ); - const char* tname; - if( tidMatch ) - { - tname = m_worker.GetThreadName( tid ); - ImGui::PushStyleColor( ImGuiCol_Text, ImVec4( 1.0f, 1.0f, 0.2f, 1.0f ) ); - } - else - { - tname = m_worker.GetExternalName( tid ).second; - } - const auto& tit = ctd.find( tid ); - assert( tit != ctd.end() ); - ImGui::TextUnformatted( RealToString( tid ) ); - if( ImGui::IsItemHovered() ) - { - if( tidMatch ) - { - m_drawThreadMigrations = tid; - m_cpuDataThread = tid; - } - m_drawThreadHighlight = tid; - } - ImGui::TableNextColumn(); - if( tidMatch ) - { - SmallColorBox( GetThreadColor( tid, 0 ) ); - ImGui::SameLine(); - } - ImGui::TextUnformatted( tname ); - if( ImGui::IsItemHovered() ) - { - if( tidMatch ) - { - m_drawThreadMigrations = tid; - m_cpuDataThread = tid; - } - m_drawThreadHighlight = tid; - } - ImGui::TableNextColumn(); - PrintStringPercent( buf, TimeToString( tit->second.runningTime ), double( tit->second.runningTime ) * rtimespan * 100 ); - style.FramePadding.y = 0; - ImGui::ProgressBar( double( tit->second.runningTime ) * rtimespan, ImVec2( -1, ty ), buf ); - style.FramePadding.y = framePaddingY; - ImGui::TableNextColumn(); - ImGui::TextUnformatted( RealToString( tit->second.runningRegions ) ); - ImGui::TableNextColumn(); - ImGui::TextUnformatted( RealToString( tit->second.migrations ) ); - ImGui::SameLine(); - PrintStringPercent( buf, double( tit->second.migrations ) / tit->second.runningRegions * 100 ); - TextDisabledUnformatted( buf ); - if( tidMatch ) - { - ImGui::PopStyleColor(); - } - } - ImGui::TreePop(); - ImGui::Separator(); - } - if( pidMatch ) - { - ImGui::PopStyleColor(); - } - } - ImGui::EndTable(); - } - ImGui::EndChild(); - ImGui::End(); -} - void View::DrawSelectedAnnotation() { assert( m_selectedAnnotation ); diff --git a/server/TracyView_CpuData.cpp b/server/TracyView_CpuData.cpp new file mode 100644 index 00000000..c1929be3 --- /dev/null +++ b/server/TracyView_CpuData.cpp @@ -0,0 +1,307 @@ +#include "TracyPrint.hpp" +#include "TracyView.hpp" + +namespace tracy +{ + +void View::DrawCpuDataWindow() +{ + const auto scale = GetScale(); + ImGui::SetNextWindowSize( ImVec2( 700 * scale, 800 * scale ), ImGuiCond_FirstUseEver ); + ImGui::Begin( "CPU data", &m_showCpuDataWindow ); + if( ImGui::GetCurrentWindowRead()->SkipItems ) { ImGui::End(); return; } + + struct PidData + { + std::vector tids; + CpuThreadData data; + }; + + const auto& ctd = m_worker.GetCpuThreadData(); + unordered_flat_map pids; + for( auto& v : ctd ) + { + uint64_t pid = m_worker.GetPidFromTid( v.first ); + auto it = pids.find( pid ); + if( it == pids.end() ) + { + it = pids.emplace( pid, PidData {} ).first; + } + it->second.tids.emplace_back( v.first ); + it->second.data.runningTime += v.second.runningTime; + it->second.data.runningRegions += v.second.runningRegions; + it->second.data.migrations += v.second.migrations; + } + + TextFocused( "Tracked threads:", RealToString( ctd.size() ) ); + ImGui::SameLine(); + TextFocused( "Tracked processes:", RealToString( pids.size() ) ); + ImGui::Separator(); + ImGui::BeginChild( "##cpudata" ); + if( ImGui::BeginTable( "##cpudata", 5, ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable | ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_ScrollY ) ) + { + ImGui::TableSetupScrollFreeze( 0, 1 ); + ImGui::TableSetupColumn( "PID/TID", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize ); + ImGui::TableSetupColumn( "Name" ); + ImGui::TableSetupColumn( "Running time", ImGuiTableColumnFlags_PreferSortDescending ); + ImGui::TableSetupColumn( "Running regions", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize ); + ImGui::TableSetupColumn( "CPU migrations", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoResize ); + ImGui::TableHeadersRow(); + + std::vector::iterator> psort; + psort.reserve( pids.size() ); + for( auto it = pids.begin(); it != pids.end(); ++it ) psort.emplace_back( it ); + const auto& sortspec = *ImGui::TableGetSortSpecs()->Specs; + switch( sortspec.ColumnIndex ) + { + case 0: + if( sortspec.SortDirection == ImGuiSortDirection_Descending ) + { + pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->first > r->first; } ); + } + else + { + pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->first < r->first; } ); + } + break; + case 1: + if( sortspec.SortDirection == ImGuiSortDirection_Descending ) + { + pdqsort_branchless( psort.begin(), psort.end(), [this] ( const auto& l, const auto& r ) { return strcmp( m_worker.GetExternalName( l->second.tids[0] ).first, m_worker.GetExternalName( r->second.tids[0] ).first ) > 0; } ); + } + else + { + pdqsort_branchless( psort.begin(), psort.end(), [this] ( const auto& l, const auto& r ) { return strcmp( m_worker.GetExternalName( l->second.tids[0] ).first, m_worker.GetExternalName( r->second.tids[0] ).first ) < 0; } ); + } + break; + case 2: + if( sortspec.SortDirection == ImGuiSortDirection_Descending ) + { + pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->second.data.runningTime > r->second.data.runningTime; } ); + } + else + { + pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->second.data.runningTime < r->second.data.runningTime; } ); + } + break; + case 3: + if( sortspec.SortDirection == ImGuiSortDirection_Descending ) + { + pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->second.data.runningRegions > r->second.data.runningRegions; } ); + } + else + { + pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->second.data.runningRegions < r->second.data.runningRegions; } ); + } + break; + case 4: + if( sortspec.SortDirection == ImGuiSortDirection_Descending ) + { + pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->second.data.migrations > r->second.data.migrations; } ); + } + else + { + pdqsort_branchless( psort.begin(), psort.end(), [] ( const auto& l, const auto& r ) { return l->second.data.migrations < r->second.data.migrations; } ); + } + break; + default: + assert( false ); + break; + } + + const auto thisPid = m_worker.GetPid(); + const auto rtimespan = 1.0 / m_worker.GetLastTime(); + const auto ty = ImGui::GetTextLineHeight(); + + auto& style = ImGui::GetStyle(); + const auto framePaddingY = style.FramePadding.y; + for( auto& pidit : psort ) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + + char buf[128]; + auto& pid = *pidit; + const auto pidMatch = thisPid != 0 && thisPid == pid.first; + auto name = m_worker.GetExternalName( pid.second.tids[0] ).first; + if( pidMatch ) + { + name = m_worker.GetCaptureProgram().c_str(); + ImGui::PushStyleColor( ImGuiCol_Text, ImVec4( 0.2f, 1.0f, 0.2f, 1.0f ) ); + } + const auto pidtxt = pid.first == 0 ? "Unknown" : RealToString( pid.first ); + const auto expand = ImGui::TreeNode( pidtxt ); + if( ImGui::IsItemHovered() ) + { + if( pidMatch ) + { + m_drawThreadMigrations = pid.first; + m_cpuDataThread = pid.first; + } + m_drawThreadHighlight = pid.first; + } + const auto tsz = pid.second.tids.size(); + if( tsz > 1 ) + { + ImGui::SameLine(); + ImGui::TextDisabled( "(%s)", RealToString( tsz ) ); + } + ImGui::TableNextColumn(); + ImGui::TextUnformatted( pid.first == 0 ? "???" : name ); + if( ImGui::IsItemHovered() ) + { + if( pidMatch ) + { + m_drawThreadMigrations = pid.first; + m_cpuDataThread = pid.first; + } + m_drawThreadHighlight = pid.first; + } + ImGui::TableNextColumn(); + PrintStringPercent( buf, TimeToString( pid.second.data.runningTime ), double( pid.second.data.runningTime ) * rtimespan * 100 ); + style.FramePadding.y = 0; + ImGui::ProgressBar( double( pid.second.data.runningTime ) * rtimespan, ImVec2( -1, ty ), buf ); + style.FramePadding.y = framePaddingY; + ImGui::TableNextColumn(); + ImGui::TextUnformatted( RealToString( pid.second.data.runningRegions ) ); + ImGui::TableNextColumn(); + ImGui::TextUnformatted( RealToString( pid.second.data.migrations ) ); + ImGui::SameLine(); + PrintStringPercent( buf, double( pid.second.data.migrations ) / pid.second.data.runningRegions * 100 ); + TextDisabledUnformatted( buf ); + if( expand ) + { + ImGui::Separator(); + switch( sortspec.ColumnIndex ) + { + case 0: + if( sortspec.SortDirection == ImGuiSortDirection_Descending ) + { + pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), []( const auto& l, const auto& r ) { return l > r; } ); + } + else + { + pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end() ); + } + break; + case 1: + if( sortspec.SortDirection == ImGuiSortDirection_Descending ) + { + pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [this] ( const auto& l, const auto& r ) { return strcmp( m_worker.GetExternalName( l ).second, m_worker.GetExternalName( r ).second ) > 0; } ); + } + else + { + pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [this] ( const auto& l, const auto& r ) { return strcmp( m_worker.GetExternalName( l ).second, m_worker.GetExternalName( r ).second ) < 0; } ); + } + break; + case 2: + if( sortspec.SortDirection == ImGuiSortDirection_Descending ) + { + pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [&ctd] ( const auto& l, const auto& r ) { return ctd.find( l )->second.runningTime > ctd.find( r )->second.runningTime; } ); + } + else + { + pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [&ctd] ( const auto& l, const auto& r ) { return ctd.find( l )->second.runningTime < ctd.find( r )->second.runningTime; } ); + } + break; + case 3: + if( sortspec.SortDirection == ImGuiSortDirection_Descending ) + { + pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [&ctd] ( const auto& l, const auto& r ) { return ctd.find( l )->second.runningRegions > ctd.find( r )->second.runningRegions; } ); + } + else + { + pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [&ctd] ( const auto& l, const auto& r ) { return ctd.find( l )->second.runningRegions < ctd.find( r )->second.runningRegions; } ); + } + break; + case 4: + if( sortspec.SortDirection == ImGuiSortDirection_Descending ) + { + pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [&ctd] ( const auto& l, const auto& r ) { return ctd.find( l )->second.migrations > ctd.find( r )->second.migrations; } ); + } + else + { + pdqsort_branchless( pid.second.tids.begin(), pid.second.tids.end(), [&ctd] ( const auto& l, const auto& r ) { return ctd.find( l )->second.migrations < ctd.find( r )->second.migrations; } ); + } + break; + default: + assert( false ); + break; + } + for( auto& tid : pid.second.tids ) + { + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + + const auto tidMatch = pidMatch && m_worker.IsThreadLocal( tid ); + const char* tname; + if( tidMatch ) + { + tname = m_worker.GetThreadName( tid ); + ImGui::PushStyleColor( ImGuiCol_Text, ImVec4( 1.0f, 1.0f, 0.2f, 1.0f ) ); + } + else + { + tname = m_worker.GetExternalName( tid ).second; + } + const auto& tit = ctd.find( tid ); + assert( tit != ctd.end() ); + ImGui::TextUnformatted( RealToString( tid ) ); + if( ImGui::IsItemHovered() ) + { + if( tidMatch ) + { + m_drawThreadMigrations = tid; + m_cpuDataThread = tid; + } + m_drawThreadHighlight = tid; + } + ImGui::TableNextColumn(); + if( tidMatch ) + { + SmallColorBox( GetThreadColor( tid, 0 ) ); + ImGui::SameLine(); + } + ImGui::TextUnformatted( tname ); + if( ImGui::IsItemHovered() ) + { + if( tidMatch ) + { + m_drawThreadMigrations = tid; + m_cpuDataThread = tid; + } + m_drawThreadHighlight = tid; + } + ImGui::TableNextColumn(); + PrintStringPercent( buf, TimeToString( tit->second.runningTime ), double( tit->second.runningTime ) * rtimespan * 100 ); + style.FramePadding.y = 0; + ImGui::ProgressBar( double( tit->second.runningTime ) * rtimespan, ImVec2( -1, ty ), buf ); + style.FramePadding.y = framePaddingY; + ImGui::TableNextColumn(); + ImGui::TextUnformatted( RealToString( tit->second.runningRegions ) ); + ImGui::TableNextColumn(); + ImGui::TextUnformatted( RealToString( tit->second.migrations ) ); + ImGui::SameLine(); + PrintStringPercent( buf, double( tit->second.migrations ) / tit->second.runningRegions * 100 ); + TextDisabledUnformatted( buf ); + if( tidMatch ) + { + ImGui::PopStyleColor(); + } + } + ImGui::TreePop(); + ImGui::Separator(); + } + if( pidMatch ) + { + ImGui::PopStyleColor(); + } + } + ImGui::EndTable(); + } + ImGui::EndChild(); + ImGui::End(); +} + + +}