mirror of
https://github.com/wolfpld/tracy
synced 2025-05-05 06:33:52 +00:00
Special mode for callstack grouping in find zone menu.
This commit is contained in:
parent
851ae9077b
commit
422ed1f452
@ -5655,11 +5655,11 @@ void View::DrawFindZone()
|
|||||||
|
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
|
|
||||||
|
auto& zoneData = m_worker.GetZonesForSourceLocation( m_findZone.match[m_findZone.selMatch] );
|
||||||
if( ImGui::TreeNodeEx( "Histogram", ImGuiTreeNodeFlags_DefaultOpen ) )
|
if( ImGui::TreeNodeEx( "Histogram", ImGuiTreeNodeFlags_DefaultOpen ) )
|
||||||
{
|
{
|
||||||
const auto ty = ImGui::GetFontSize();
|
const auto ty = ImGui::GetFontSize();
|
||||||
|
|
||||||
auto& zoneData = m_worker.GetZonesForSourceLocation( m_findZone.match[m_findZone.selMatch] );
|
|
||||||
auto& zones = zoneData.zones;
|
auto& zones = zoneData.zones;
|
||||||
const auto tmin = m_findZone.selfTime ? zoneData.selfMin : zoneData.min;
|
const auto tmin = m_findZone.selfTime ? zoneData.selfMin : zoneData.min;
|
||||||
const auto tmax = m_findZone.selfTime ? zoneData.selfMax : zoneData.max;
|
const auto tmax = m_findZone.selfTime ? zoneData.selfMax : zoneData.max;
|
||||||
@ -6406,137 +6406,139 @@ void View::DrawFindZone()
|
|||||||
|
|
||||||
ImGui::BeginChild( "##zonesScroll", ImVec2( ImGui::GetWindowContentRegionWidth(), std::max( 200.f, ImGui::GetContentRegionAvail().y ) ) );
|
ImGui::BeginChild( "##zonesScroll", ImVec2( ImGui::GetWindowContentRegionWidth(), std::max( 200.f, ImGui::GetContentRegionAvail().y ) ) );
|
||||||
idx = 0;
|
idx = 0;
|
||||||
for( auto& v : groups )
|
if( groupBy == FindZone::GroupBy::Callstack )
|
||||||
{
|
{
|
||||||
const char* hdrString;
|
const auto gsz = groups.size();
|
||||||
switch( groupBy )
|
if( gsz > 0 )
|
||||||
{
|
{
|
||||||
case FindZone::GroupBy::Thread:
|
if( m_findZone.selCs > gsz ) m_findZone.selCs = gsz;
|
||||||
hdrString = m_worker.GetThreadString( m_worker.DecompressThread( v->first ) );
|
const auto group = groups[m_findZone.selCs];
|
||||||
break;
|
|
||||||
case FindZone::GroupBy::UserText:
|
const bool selHilite = m_findZone.selGroup == group->first;
|
||||||
hdrString = v->first == std::numeric_limits<uint64_t>::max() ? "No user text" : m_worker.GetString( StringIdx( v->first ) );
|
if( selHilite ) SetButtonHighlightColor();
|
||||||
break;
|
#ifdef TRACY_EXTENDED_FONT
|
||||||
case FindZone::GroupBy::Callstack:
|
if( ImGui::SmallButton( " " ICON_FA_CHECK " " ) )
|
||||||
if( v->first == 0 )
|
#else
|
||||||
|
if( ImGui::SmallButton( "Select" ) )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
hdrString = "No callstack";
|
m_findZone.selGroup = group->first;
|
||||||
|
m_findZone.ResetSelection();
|
||||||
}
|
}
|
||||||
else
|
if( selHilite ) ImGui::PopStyleColor( 3 );
|
||||||
|
ImGui::SameLine();
|
||||||
|
#ifdef TRACY_EXTENDED_FONT
|
||||||
|
if( ImGui::SmallButton( " " ICON_FA_CARET_LEFT " " ) )
|
||||||
|
#else
|
||||||
|
if( ImGui::SmallButton( " < " ) )
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
auto& callstack = m_worker.GetCallstack( v->first );
|
m_findZone.selCs = std::max( m_findZone.selCs - 1, 0 );
|
||||||
auto& frameData = *m_worker.GetCallstackFrame( *callstack.begin() );
|
|
||||||
hdrString = m_worker.GetString( frameData.data[frameData.size-1].name );
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
default:
|
|
||||||
hdrString = nullptr;
|
|
||||||
assert( false );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ImGui::PushID( v->first );
|
|
||||||
const bool expand = ImGui::TreeNodeEx( hdrString, ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ( v->first == m_findZone.selGroup ? ImGuiTreeNodeFlags_Selected : 0 ) );
|
|
||||||
if( ImGui::IsItemClicked() )
|
|
||||||
{
|
|
||||||
m_findZone.selGroup = v->first;
|
|
||||||
m_findZone.ResetSelection();
|
|
||||||
}
|
|
||||||
ImGui::PopID();
|
|
||||||
ImGui::SameLine();
|
|
||||||
ImGui::TextColored( ImVec4( 0.5f, 0.5f, 0.5f, 1.0f ), "(%s) %s", RealToString( v->second.zones.size(), true ), TimeToString( v->second.time ) );
|
|
||||||
if( groupBy == FindZone::GroupBy::Callstack && v->first != 0 )
|
|
||||||
{
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
SmallCallstackButton( "callstack", v->first, idx );
|
ImGui::Text( "%s / %s", RealToString( m_findZone.selCs + 1, true ), RealToString( gsz, true ) );
|
||||||
}
|
|
||||||
|
|
||||||
if( expand )
|
|
||||||
{
|
|
||||||
ImGui::Columns( 3, hdrString );
|
|
||||||
ImGui::Separator();
|
|
||||||
if( ImGui::SmallButton( "Time from start" ) ) m_findZone.tableSortBy = FindZone::TableSortBy::Starttime;
|
|
||||||
ImGui::NextColumn();
|
|
||||||
if( ImGui::SmallButton( "Execution time" ) ) m_findZone.tableSortBy = FindZone::TableSortBy::Runtime;
|
|
||||||
ImGui::NextColumn();
|
|
||||||
if( ImGui::SmallButton( "Name" ) ) m_findZone.tableSortBy = FindZone::TableSortBy::Name;
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
DrawHelpMarker( "Only displayed if custom zone name is set." );
|
#ifdef TRACY_EXTENDED_FONT
|
||||||
ImGui::NextColumn();
|
if( ImGui::SmallButton( " " ICON_FA_CARET_RIGHT " " ) )
|
||||||
ImGui::Separator();
|
#else
|
||||||
|
if( ImGui::SmallButton( " > " ) )
|
||||||
Vector<ZoneEvent*>* zonesToIterate = &v->second.zones;
|
#endif
|
||||||
Vector<ZoneEvent*> sortedZones;
|
|
||||||
|
|
||||||
if( m_findZone.tableSortBy != FindZone::TableSortBy::Starttime )
|
|
||||||
{
|
{
|
||||||
zonesToIterate = &sortedZones;
|
m_findZone.selCs = std::min<int>( m_findZone.selCs + 1, gsz - 1 );
|
||||||
sortedZones.reserve_and_use( v->second.zones.size() );
|
}
|
||||||
memcpy( sortedZones.data(), v->second.zones.data(), v->second.zones.size() * sizeof( ZoneEvent* ) );
|
|
||||||
|
|
||||||
switch( m_findZone.tableSortBy )
|
ImGui::SameLine();
|
||||||
|
TextFocused( "Count:", RealToString( group->second.zones.size(), true ) );
|
||||||
|
ImGui::SameLine();
|
||||||
|
TextFocused( "Time:", TimeToString( group->second.time ) );
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextDisabled( "(%.2f%%)", group->second.time * 100.f / zoneData.total );
|
||||||
|
|
||||||
|
if( group->first != 0 )
|
||||||
|
{
|
||||||
|
ImGui::SameLine();
|
||||||
|
int fidx = 0;
|
||||||
|
#ifdef TRACY_EXTENDED_FONT
|
||||||
|
SmallCallstackButton( " " ICON_FA_ALIGN_JUSTIFY " ", group->first, fidx, false );
|
||||||
|
#else
|
||||||
|
SmallCallstackButton( "Call stack", group->first, fidx, false );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ImGui::Spacing();
|
||||||
|
ImGui::Indent();
|
||||||
|
auto& csdata = m_worker.GetCallstack( group->first );
|
||||||
|
for( auto& entry : csdata )
|
||||||
{
|
{
|
||||||
case FindZone::TableSortBy::Runtime:
|
ImGui::TextDisabled( "%i.", fidx++ );
|
||||||
if( m_findZone.selfTime )
|
ImGui::SameLine();
|
||||||
|
auto frame = m_worker.GetCallstackFrame( entry );
|
||||||
|
if( !frame )
|
||||||
{
|
{
|
||||||
pdqsort_branchless( sortedZones.begin(), sortedZones.end(), [this]( const auto& lhs, const auto& rhs ) {
|
ImGui::Text( "0x%" PRIX64, entry );
|
||||||
return m_worker.GetZoneEndDirect( *lhs ) - lhs->start - this->GetZoneChildTimeFast( *lhs ) >
|
|
||||||
m_worker.GetZoneEndDirect( *rhs ) - rhs->start - this->GetZoneChildTimeFast( *rhs );
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pdqsort_branchless( sortedZones.begin(), sortedZones.end(), [this]( const auto& lhs, const auto& rhs ) {
|
ImGui::TextUnformatted( m_worker.GetString( frame->data[frame->size-1].name ) );
|
||||||
return m_worker.GetZoneEndDirect( *lhs ) - lhs->start > m_worker.GetZoneEndDirect( *rhs ) - rhs->start;
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case FindZone::TableSortBy::Name:
|
|
||||||
pdqsort_branchless( sortedZones.begin(), sortedZones.end(), [this]( const auto& lhs, const auto& rhs ) {
|
|
||||||
if( lhs->name.active != rhs->name.active ) return lhs->name.active > rhs->name.active;
|
|
||||||
return strcmp( m_worker.GetString( lhs->name ), m_worker.GetString( rhs->name ) ) < 0;
|
|
||||||
} );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert( false );
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
ImGui::Unindent();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
for( auto& ev : *zonesToIterate )
|
|
||||||
{
|
{
|
||||||
const auto end = m_worker.GetZoneEndDirect( *ev );
|
ImGui::Text( "No call stack" );
|
||||||
auto timespan = end - ev->start;
|
}
|
||||||
if( m_findZone.selfTime ) timespan -= GetZoneChildTimeFast( *ev );
|
|
||||||
|
ImGui::Spacing();
|
||||||
ImGui::PushID( ev );
|
if( ImGui::TreeNodeEx( "Zone list" ) )
|
||||||
if( ImGui::Selectable( TimeToString( ev->start - m_worker.GetTimeBegin() ), m_zoneInfoWindow == ev, ImGuiSelectableFlags_SpanAllColumns ) )
|
{
|
||||||
{
|
DrawZoneList( group->second.zones );
|
||||||
ShowZoneInfo( *ev );
|
}
|
||||||
}
|
}
|
||||||
if( ImGui::IsItemHovered() )
|
}
|
||||||
{
|
else
|
||||||
m_zoneHighlight = ev;
|
{
|
||||||
if( ImGui::IsMouseClicked( 2 ) )
|
for( auto& v : groups )
|
||||||
{
|
{
|
||||||
ZoomToZone( *ev );
|
const char* hdrString;
|
||||||
}
|
switch( groupBy )
|
||||||
ZoneTooltip( *ev );
|
{
|
||||||
}
|
case FindZone::GroupBy::Thread:
|
||||||
|
hdrString = m_worker.GetThreadString( m_worker.DecompressThread( v->first ) );
|
||||||
ImGui::NextColumn();
|
break;
|
||||||
ImGui::TextUnformatted( TimeToString( timespan ) );
|
case FindZone::GroupBy::UserText:
|
||||||
ImGui::NextColumn();
|
hdrString = v->first == std::numeric_limits<uint64_t>::max() ? "No user text" : m_worker.GetString( StringIdx( v->first ) );
|
||||||
if( ev->name.active )
|
break;
|
||||||
{
|
case FindZone::GroupBy::Callstack:
|
||||||
ImGui::TextUnformatted( m_worker.GetString( ev->name ) );
|
if( v->first == 0 )
|
||||||
}
|
{
|
||||||
ImGui::NextColumn();
|
hdrString = "No callstack";
|
||||||
|
}
|
||||||
ImGui::PopID();
|
else
|
||||||
|
{
|
||||||
|
auto& callstack = m_worker.GetCallstack( v->first );
|
||||||
|
auto& frameData = *m_worker.GetCallstackFrame( *callstack.begin() );
|
||||||
|
hdrString = m_worker.GetString( frameData.data[frameData.size-1].name );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
hdrString = nullptr;
|
||||||
|
assert( false );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ImGui::PushID( v->first );
|
||||||
|
const bool expand = ImGui::TreeNodeEx( hdrString, ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ( v->first == m_findZone.selGroup ? ImGuiTreeNodeFlags_Selected : 0 ) );
|
||||||
|
if( ImGui::IsItemClicked() )
|
||||||
|
{
|
||||||
|
m_findZone.selGroup = v->first;
|
||||||
|
m_findZone.ResetSelection();
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::TextColored( ImVec4( 0.5f, 0.5f, 0.5f, 1.0f ), "(%s) %s", RealToString( v->second.zones.size(), true ), TimeToString( v->second.time ) );
|
||||||
|
if( expand )
|
||||||
|
{
|
||||||
|
DrawZoneList( v->second.zones );
|
||||||
}
|
}
|
||||||
ImGui::Columns( 1 );
|
|
||||||
ImGui::Separator();
|
|
||||||
ImGui::TreePop();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
@ -6551,6 +6553,95 @@ void View::DrawFindZone()
|
|||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void View::DrawZoneList( const Vector<ZoneEvent*>& zones )
|
||||||
|
{
|
||||||
|
ImGui::Columns( 3 );
|
||||||
|
ImGui::Separator();
|
||||||
|
if( ImGui::SmallButton( "Time from start" ) ) m_findZone.tableSortBy = FindZone::TableSortBy::Starttime;
|
||||||
|
ImGui::NextColumn();
|
||||||
|
if( ImGui::SmallButton( "Execution time" ) ) m_findZone.tableSortBy = FindZone::TableSortBy::Runtime;
|
||||||
|
ImGui::NextColumn();
|
||||||
|
if( ImGui::SmallButton( "Name" ) ) m_findZone.tableSortBy = FindZone::TableSortBy::Name;
|
||||||
|
ImGui::SameLine();
|
||||||
|
DrawHelpMarker( "Only displayed if custom zone name is set." );
|
||||||
|
ImGui::NextColumn();
|
||||||
|
ImGui::Separator();
|
||||||
|
|
||||||
|
const Vector<ZoneEvent*>* zonesToIterate = &zones;
|
||||||
|
Vector<ZoneEvent*> sortedZones;
|
||||||
|
|
||||||
|
if( m_findZone.tableSortBy != FindZone::TableSortBy::Starttime )
|
||||||
|
{
|
||||||
|
zonesToIterate = &sortedZones;
|
||||||
|
sortedZones.reserve_and_use( zones.size() );
|
||||||
|
memcpy( sortedZones.data(), zones.data(), zones.size() * sizeof( ZoneEvent* ) );
|
||||||
|
|
||||||
|
switch( m_findZone.tableSortBy )
|
||||||
|
{
|
||||||
|
case FindZone::TableSortBy::Runtime:
|
||||||
|
if( m_findZone.selfTime )
|
||||||
|
{
|
||||||
|
pdqsort_branchless( sortedZones.begin(), sortedZones.end(), [this]( const auto& lhs, const auto& rhs ) {
|
||||||
|
return m_worker.GetZoneEndDirect( *lhs ) - lhs->start - this->GetZoneChildTimeFast( *lhs ) >
|
||||||
|
m_worker.GetZoneEndDirect( *rhs ) - rhs->start - this->GetZoneChildTimeFast( *rhs );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pdqsort_branchless( sortedZones.begin(), sortedZones.end(), [this]( const auto& lhs, const auto& rhs ) {
|
||||||
|
return m_worker.GetZoneEndDirect( *lhs ) - lhs->start > m_worker.GetZoneEndDirect( *rhs ) - rhs->start;
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FindZone::TableSortBy::Name:
|
||||||
|
pdqsort_branchless( sortedZones.begin(), sortedZones.end(), [this]( const auto& lhs, const auto& rhs ) {
|
||||||
|
if( lhs->name.active != rhs->name.active ) return lhs->name.active > rhs->name.active;
|
||||||
|
return strcmp( m_worker.GetString( lhs->name ), m_worker.GetString( rhs->name ) ) < 0;
|
||||||
|
} );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert( false );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for( auto& ev : *zonesToIterate )
|
||||||
|
{
|
||||||
|
const auto end = m_worker.GetZoneEndDirect( *ev );
|
||||||
|
auto timespan = end - ev->start;
|
||||||
|
if( m_findZone.selfTime ) timespan -= GetZoneChildTimeFast( *ev );
|
||||||
|
|
||||||
|
ImGui::PushID( ev );
|
||||||
|
if( ImGui::Selectable( TimeToString( ev->start - m_worker.GetTimeBegin() ), m_zoneInfoWindow == ev, ImGuiSelectableFlags_SpanAllColumns ) )
|
||||||
|
{
|
||||||
|
ShowZoneInfo( *ev );
|
||||||
|
}
|
||||||
|
if( ImGui::IsItemHovered() )
|
||||||
|
{
|
||||||
|
m_zoneHighlight = ev;
|
||||||
|
if( ImGui::IsMouseClicked( 2 ) )
|
||||||
|
{
|
||||||
|
ZoomToZone( *ev );
|
||||||
|
}
|
||||||
|
ZoneTooltip( *ev );
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::NextColumn();
|
||||||
|
ImGui::TextUnformatted( TimeToString( timespan ) );
|
||||||
|
ImGui::NextColumn();
|
||||||
|
if( ev->name.active )
|
||||||
|
{
|
||||||
|
ImGui::TextUnformatted( m_worker.GetString( ev->name ) );
|
||||||
|
}
|
||||||
|
ImGui::NextColumn();
|
||||||
|
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
ImGui::Columns( 1 );
|
||||||
|
ImGui::Separator();
|
||||||
|
ImGui::TreePop();
|
||||||
|
}
|
||||||
|
|
||||||
void View::DrawCompare()
|
void View::DrawCompare()
|
||||||
{
|
{
|
||||||
ImGui::Begin( "Compare traces", &m_compare.show );
|
ImGui::Begin( "Compare traces", &m_compare.show );
|
||||||
|
@ -131,6 +131,7 @@ private:
|
|||||||
std::vector<CallstackFrameTree> GetCallstackFrameTreeBottomUp( const MemData& mem ) const;
|
std::vector<CallstackFrameTree> GetCallstackFrameTreeBottomUp( const MemData& mem ) const;
|
||||||
std::vector<CallstackFrameTree> GetCallstackFrameTreeTopDown( const MemData& mem ) const;
|
std::vector<CallstackFrameTree> GetCallstackFrameTreeTopDown( const MemData& mem ) const;
|
||||||
void DrawFrameTreeLevel( std::vector<CallstackFrameTree>& tree, int& idx );
|
void DrawFrameTreeLevel( std::vector<CallstackFrameTree>& tree, int& idx );
|
||||||
|
void DrawZoneList( const Vector<ZoneEvent*>& zones );
|
||||||
|
|
||||||
void DrawInfoWindow();
|
void DrawInfoWindow();
|
||||||
void DrawZoneInfoWindow();
|
void DrawZoneInfoWindow();
|
||||||
@ -333,6 +334,7 @@ private:
|
|||||||
bool drawAvgMed = true;
|
bool drawAvgMed = true;
|
||||||
bool drawSelAvgMed = true;
|
bool drawSelAvgMed = true;
|
||||||
bool scheduleResetMatch = false;
|
bool scheduleResetMatch = false;
|
||||||
|
int selCs = 0;
|
||||||
|
|
||||||
void Reset()
|
void Reset()
|
||||||
{
|
{
|
||||||
@ -358,6 +360,7 @@ private:
|
|||||||
ResetSelection();
|
ResetSelection();
|
||||||
groups.clear();
|
groups.clear();
|
||||||
processed = 0;
|
processed = 0;
|
||||||
|
selCs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResetSelection()
|
void ResetSelection()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user