Skip to content

Commit 9e500bc

Browse files
committed
Handle merging inlined ghost zones.
1 parent 994b88f commit 9e500bc

File tree

3 files changed

+162
-153
lines changed

3 files changed

+162
-153
lines changed

‎server/TracyView.cpp‎

Lines changed: 63 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -3568,18 +3568,16 @@ int View::DrawGhostLevel( const Vector<GhostZone>& vec, bool hover, double pxns,
35683568
}
35693569
else
35703570
{
3571-
const auto& ghostFrame = m_worker.GetGhostFrame( ev.frame );
3572-
const auto frame = m_worker.GetCallstackFrame( ghostFrame );
3571+
const auto& ghostKey = m_worker.GetGhostFrame( ev.frame );
3572+
const auto frame = m_worker.GetCallstackFrame( ghostKey.frame );
35733573
const auto pr0 = ( ev.start.Val() - m_vd.zvStart ) * pxns;
35743574
const auto pr1 = ( ev.end.Val() - m_vd.zvStart ) * pxns;
35753575
const auto px0 = std::max( pr0, -10.0 );
35763576
const auto px1 = std::max( { std::min( pr1, double( w + 10 ) ), px0 + pxns * 0.5, px0 + MinVisSize } );
3577-
int fsz;
35783577
if( !frame )
35793578
{
3580-
fsz = 1;
35813579
char symName[64];
3582-
sprintf( symName, "0x%" PRIx64, m_worker.GetCanonicalPointer( ghostFrame ) );
3580+
sprintf( symName, "0x%" PRIx64, m_worker.GetCanonicalPointer( ghostKey.frame ) );
35833581
const auto tsz = ImGui::CalcTextSize( symName );
35843582

35853583
const auto txtColor = 0xFF888888;
@@ -3631,99 +3629,82 @@ int View::DrawGhostLevel( const Vector<GhostZone>& vec, bool hover, double pxns,
36313629
}
36323630
else
36333631
{
3634-
fsz = int( frame->size );
3635-
auto foff = offset;
3636-
for( int i=fsz-1; i>=0; i-- )
3637-
{
3638-
const auto isInline = i != fsz-1;
3639-
const auto col = isInline ? DarkenColor( color ) : color;
3640-
const auto sym = m_worker.GetSymbolData( frame->data[i].symAddr );
3641-
const auto symName = m_worker.GetString( frame->data[i].name );
3642-
uint32_t txtColor = symName[0] == '[' ? 0xFF999999 : 0xFFFFFFFF;
3643-
const auto tsz = ImGui::CalcTextSize( symName );
3632+
const auto& sym = frame->data[ghostKey.inlineFrame];
3633+
const auto isInline = ghostKey.inlineFrame != frame->size-1;
3634+
const auto col = isInline ? DarkenColor( color ) : color;
3635+
const auto symName = m_worker.GetString( sym.name );
3636+
uint32_t txtColor = symName[0] == '[' ? 0xFF999999 : 0xFFFFFFFF;
3637+
const auto tsz = ImGui::CalcTextSize( symName );
36443638

3645-
draw->AddRectFilled( wpos + ImVec2( px0, foff ), wpos + ImVec2( px1, foff + tsz.y ), col );
3646-
draw->AddRect( wpos + ImVec2( px0, foff ), wpos + ImVec2( px1, foff + tsz.y ), outline, 0.f, -1 );
3639+
draw->AddRectFilled( wpos + ImVec2( px0, offset ), wpos + ImVec2( px1, offset + tsz.y ), col );
3640+
draw->AddRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( px1, offset + tsz.y ), outline, 0.f, -1 );
36473641

3648-
if( tsz.x < zsz )
3642+
if( tsz.x < zsz )
3643+
{
3644+
const auto x = ( ev.start.Val() - m_vd.zvStart ) * pxns + ( ( end - ev.start.Val() ) * pxns - tsz.x ) / 2;
3645+
if( x < 0 || x > w - tsz.x )
36493646
{
3650-
const auto x = ( ev.start.Val() - m_vd.zvStart ) * pxns + ( ( end - ev.start.Val() ) * pxns - tsz.x ) / 2;
3651-
if( x < 0 || x > w - tsz.x )
3652-
{
3653-
ImGui::PushClipRect( wpos + ImVec2( px0, foff ), wpos + ImVec2( px1, foff + tsz.y * 2 ), true );
3654-
DrawTextContrast( draw, wpos + ImVec2( std::max( std::max( 0., px0 ), std::min( double( w - tsz.x ), x ) ), foff ), txtColor, symName );
3655-
ImGui::PopClipRect();
3656-
}
3657-
else if( ev.start.Val() == ev.end.Val() )
3658-
{
3659-
DrawTextContrast( draw, wpos + ImVec2( px0 + ( px1 - px0 - tsz.x ) * 0.5, foff ), txtColor, symName );
3660-
}
3661-
else
3662-
{
3663-
DrawTextContrast( draw, wpos + ImVec2( x, foff ), txtColor, symName );
3664-
}
3647+
ImGui::PushClipRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( px1, offset + tsz.y * 2 ), true );
3648+
DrawTextContrast( draw, wpos + ImVec2( std::max( std::max( 0., px0 ), std::min( double( w - tsz.x ), x ) ), offset ), txtColor, symName );
3649+
ImGui::PopClipRect();
3650+
}
3651+
else if( ev.start.Val() == ev.end.Val() )
3652+
{
3653+
DrawTextContrast( draw, wpos + ImVec2( px0 + ( px1 - px0 - tsz.x ) * 0.5, offset ), txtColor, symName );
36653654
}
36663655
else
36673656
{
3668-
ImGui::PushClipRect( wpos + ImVec2( px0, foff ), wpos + ImVec2( px1, foff + tsz.y * 2 ), true );
3669-
DrawTextContrast( draw, wpos + ImVec2( ( ev.start.Val() - m_vd.zvStart ) * pxns, foff ), txtColor, symName );
3670-
ImGui::PopClipRect();
3657+
DrawTextContrast( draw, wpos + ImVec2( x, offset ), txtColor, symName );
36713658
}
3659+
}
3660+
else
3661+
{
3662+
ImGui::PushClipRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( px1, offset + tsz.y * 2 ), true );
3663+
DrawTextContrast( draw, wpos + ImVec2( ( ev.start.Val() - m_vd.zvStart ) * pxns, offset ), txtColor, symName );
3664+
ImGui::PopClipRect();
3665+
}
36723666

3673-
if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px0, foff ), wpos + ImVec2( px1, foff + tsz.y ) ) )
3667+
if( hover && ImGui::IsMouseHoveringRect( wpos + ImVec2( px0, offset ), wpos + ImVec2( px1, offset + tsz.y ) ) )
3668+
{
3669+
ImGui::BeginTooltip();
3670+
TextDisabledUnformatted( ICON_FA_GHOST " Ghost zone" );
3671+
ImGui::Separator();
3672+
ImGui::TextUnformatted( symName );
3673+
if( isInline )
36743674
{
3675-
ImGui::BeginTooltip();
3676-
TextDisabledUnformatted( ICON_FA_GHOST " Ghost zone" );
3677-
ImGui::Separator();
3678-
ImGui::TextUnformatted( symName );
3679-
if( isInline )
3680-
{
3681-
ImGui::SameLine();
3682-
TextDisabledUnformatted( "[inline]" );
3683-
}
3684-
if( sym ) TextFocused( "Image:", m_worker.GetString( sym->imageName ) );
3685-
TextDisabledUnformatted( "Location:" );
3686-
ImGui::SameLine();
3687-
const char* file;
3688-
uint32_t line;
3689-
if( sym && !isInline )
3690-
{
3691-
file = m_worker.GetString( sym->file );
3692-
line = sym->line;
3693-
}
3694-
else
3695-
{
3696-
file = m_worker.GetString( frame->data[i].file );
3697-
line = frame->data[i].line;
3698-
}
3699-
ImGui::Text( "%s:%i", file, line );
37003675
ImGui::SameLine();
3701-
ImGui::TextDisabled( "(0x%" PRIx64 ")", m_worker.GetCanonicalPointer( ghostFrame ) );
3702-
TextFocused( "Thread:", m_worker.GetThreadName( tid ) );
3703-
ImGui::SameLine();
3704-
ImGui::TextDisabled( "(%s)", RealToString( tid ) );
3705-
ImGui::Separator();
3706-
TextFocused( "Execution time:", TimeToString( ev.end.Val() - ev.start.Val() ) );
3707-
ImGui::EndTooltip();
3708-
3709-
if( ImGui::IsMouseClicked( 0 ) )
3710-
{
3711-
ViewDispatch( file, line, frame->data[i].symAddr );
3712-
}
3713-
else if( !m_zoomAnim.active && ImGui::IsMouseClicked( 2 ) )
3714-
{
3715-
ZoomToRange( ev.start.Val(), ev.end.Val() );
3716-
}
3676+
TextDisabledUnformatted( "[inline]" );
37173677
}
3678+
const auto symbol = m_worker.GetSymbolData( sym.symAddr );
3679+
if( symbol ) TextFocused( "Image:", m_worker.GetString( symbol->imageName ) );
3680+
TextDisabledUnformatted( "Location:" );
3681+
ImGui::SameLine();
3682+
const char* file = m_worker.GetString( sym.file );
3683+
uint32_t line = sym.line;
3684+
ImGui::Text( "%s:%i", file, line );
3685+
ImGui::SameLine();
3686+
ImGui::TextDisabled( "(0x%" PRIx64 ")", sym.symAddr );
3687+
TextFocused( "Thread:", m_worker.GetThreadName( tid ) );
3688+
ImGui::SameLine();
3689+
ImGui::TextDisabled( "(%s)", RealToString( tid ) );
3690+
ImGui::Separator();
3691+
TextFocused( "Execution time:", TimeToString( ev.end.Val() - ev.start.Val() ) );
3692+
ImGui::EndTooltip();
37183693

3719-
foff += ostep;
3694+
if( ImGui::IsMouseClicked( 0 ) )
3695+
{
3696+
ViewDispatch( file, line, sym.symAddr );
3697+
}
3698+
else if( !m_zoomAnim.active && ImGui::IsMouseClicked( 2 ) )
3699+
{
3700+
ZoomToRange( ev.start.Val(), ev.end.Val() );
3701+
}
37203702
}
37213703
}
37223704

3723-
maxdepth = std::max( maxdepth, depth + fsz - 1 );
37243705
if( ev.child >= 0 )
37253706
{
3726-
const auto d = DispatchGhostLevel( m_worker.GetGhostChildren( ev.child ), hover, pxns, nspx, wpos, _offset, depth + fsz - 1, yMin, yMax, tid );
3707+
const auto d = DispatchGhostLevel( m_worker.GetGhostChildren( ev.child ), hover, pxns, nspx, wpos, _offset, depth, yMin, yMax, tid );
37273708
if( d > maxdepth ) maxdepth = d;
37283709
}
37293710
++it;
@@ -3770,13 +3751,9 @@ int View::SkipGhostLevel( const Vector<GhostZone>& vec, bool hover, double pxns,
37703751
}
37713752
else
37723753
{
3773-
const auto& ghostFrame = m_worker.GetGhostFrame( ev.frame );
3774-
const auto frame = m_worker.GetCallstackFrame( ghostFrame );
3775-
const auto fsz = frame ? int( frame->size ) : 1;
3776-
maxdepth = std::max( maxdepth, depth + fsz - 1 );
37773754
if( ev.child >= 0 )
37783755
{
3779-
const auto d = DispatchGhostLevel( m_worker.GetGhostChildren( ev.child ), hover, pxns, nspx, wpos, _offset, depth + fsz - 1, yMin, yMax, tid );
3756+
const auto d = DispatchGhostLevel( m_worker.GetGhostChildren( ev.child ), hover, pxns, nspx, wpos, _offset, depth, yMin, yMax, tid );
37803757
if( d > maxdepth ) maxdepth = d;
37813758
}
37823759
++it;

‎server/TracyWorker.cpp‎

Lines changed: 64 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -4016,91 +4016,91 @@ void Worker::HandlePostponedSamples()
40164016
while( it != m_data.postponedSamples.end() );
40174017
}
40184018

4019-
int Worker::AddGhostZone( const VarArray<CallstackFrameId>& cs, Vector<GhostZone>* vec, uint64_t t )
4019+
void Worker::GetStackWithInlines( Vector<InlineStackData>& ret, const VarArray<CallstackFrameId>& cs )
40204020
{
4021-
int gcnt = 0;
4021+
ret.clear();
40224022
int idx = cs.size() - 1;
40234023
do
40244024
{
40254025
auto& entry = cs[idx];
4026+
const auto frame = GetCallstackFrame( entry );
4027+
if( frame )
4028+
{
4029+
uint8_t i = frame->size;
4030+
do
4031+
{
4032+
i--;
4033+
ret.push_back( InlineStackData { frame->data[i].symAddr, entry, i } );
4034+
}
4035+
while( i != 0 );
4036+
}
4037+
else
4038+
{
4039+
ret.push_back( InlineStackData{ GetCanonicalPointer( entry ), entry, 0 } );
4040+
}
4041+
}
4042+
while( idx-- > 0 );
4043+
}
4044+
4045+
int Worker::AddGhostZone( const VarArray<CallstackFrameId>& cs, Vector<GhostZone>* vec, uint64_t t )
4046+
{
4047+
static Vector<InlineStackData> stack;
4048+
GetStackWithInlines( stack, cs );
4049+
4050+
const uint64_t refBackTime = vec->empty() ? 0 : vec->back().end.Val();
4051+
int gcnt = 0;
4052+
int idx = 0;
4053+
while( !vec->empty() && idx < stack.size() )
4054+
{
4055+
auto& back = vec->back();
4056+
const auto& backKey = m_data.ghostFrames[back.frame.Val()];
4057+
const auto backFrame = GetCallstackFrame( backKey.frame );
4058+
if( !backFrame ) break;
4059+
const auto& inlineFrame = backFrame->data[backKey.inlineFrame];
4060+
if( inlineFrame.symAddr != stack[idx].symAddr ) break;
4061+
if( back.end.Val() != refBackTime ) break;
4062+
back.end.SetVal( t + m_samplingPeriod );
4063+
idx++;
4064+
if( back.child < 0 )
4065+
{
4066+
back.child = m_data.ghostChildren.size();
4067+
vec = &m_data.ghostChildren.push_next();
4068+
}
4069+
else
4070+
{
4071+
vec = &m_data.ghostChildren[back.child];
4072+
}
4073+
}
4074+
while( idx < stack.size() )
4075+
{
4076+
gcnt++;
40264077
uint32_t fid;
4027-
auto it = m_data.ghostFramesMap.find( entry.data );
4078+
GhostKey key { stack[idx].frame, stack[idx].inlineFrame };
4079+
auto it = m_data.ghostFramesMap.find( key );
40284080
if( it == m_data.ghostFramesMap.end() )
40294081
{
40304082
fid = uint32_t( m_data.ghostFrames.size() );
4031-
m_data.ghostFrames.push_back( entry );
4032-
m_data.ghostFramesMap.emplace( entry.data, fid );
4083+
m_data.ghostFrames.push_back( key );
4084+
m_data.ghostFramesMap.emplace( key, fid );
40334085
}
40344086
else
40354087
{
40364088
fid = it->second;
40374089
}
4038-
if( vec->empty() )
4090+
auto& zone = vec->push_next();
4091+
zone.start.SetVal( t );
4092+
zone.end.SetVal( t + m_samplingPeriod );
4093+
zone.frame.SetVal( fid );
4094+
if( ++idx == stack.size() )
40394095
{
4040-
gcnt++;
4041-
auto& zone = vec->push_next();
4042-
zone.start.SetVal( t );
4043-
zone.end.SetVal( t + m_samplingPeriod );
4044-
zone.frame.SetVal( fid );
40454096
zone.child = -1;
40464097
}
40474098
else
40484099
{
4049-
auto& back = vec->back();
4050-
const auto backFrame = GetCallstackFrame( m_data.ghostFrames[back.frame.Val()] );
4051-
const auto thisFrame = GetCallstackFrame( entry );
4052-
bool match = false;
4053-
if( backFrame && thisFrame )
4054-
{
4055-
match = backFrame->size == thisFrame->size;
4056-
if( match )
4057-
{
4058-
for( uint8_t i=0; i<thisFrame->size; i++ )
4059-
{
4060-
if( backFrame->data[i].symAddr != thisFrame->data[i].symAddr )
4061-
{
4062-
match = false;
4063-
break;
4064-
}
4065-
}
4066-
}
4067-
}
4068-
if( match )
4069-
{
4070-
back.end.SetVal( t + m_samplingPeriod );
4071-
}
4072-
else
4073-
{
4074-
gcnt++;
4075-
auto ptr = &back;
4076-
for(;;)
4077-
{
4078-
ptr->end.SetVal( t );
4079-
if( ptr->child < 0 ) break;
4080-
ptr = &GetGhostChildrenMutable( ptr->child ).back();
4081-
}
4082-
auto& zone = vec->push_next_non_empty();
4083-
zone.start.SetVal( t );
4084-
zone.end.SetVal( t + m_samplingPeriod );
4085-
zone.frame.SetVal( fid );
4086-
zone.child = -1;
4087-
}
4088-
}
4089-
if( idx > 0 )
4090-
{
4091-
auto& zone = vec->back();
4092-
if( zone.child < 0 )
4093-
{
4094-
zone.child = m_data.ghostChildren.size();
4095-
vec = &m_data.ghostChildren.push_next();
4096-
}
4097-
else
4098-
{
4099-
vec = &m_data.ghostChildren[zone.child];
4100-
}
4100+
zone.child = m_data.ghostChildren.size();
4101+
vec = &m_data.ghostChildren.push_next();
41014102
}
41024103
}
4103-
while( idx-- > 0 );
41044104
return gcnt;
41054105
}
41064106

0 commit comments

Comments
 (0)