diff --git a/server/TracyEvent.hpp b/server/TracyEvent.hpp index af340c07..140acbd2 100644 --- a/server/TracyEvent.hpp +++ b/server/TracyEvent.hpp @@ -164,22 +164,30 @@ struct ZoneEvent tracy_force_inline bool IsEndValid() const { return ( _end_child1 >> 63 ) == 0; } tracy_force_inline int16_t SrcLoc() const { return int16_t( _start_srcloc & 0xFFFF ); } tracy_force_inline void SetSrcLoc( int16_t srcloc ) { memcpy( &_start_srcloc, &srcloc, 2 ); } - tracy_force_inline int32_t Child() const { return int32_t( uint32_t( _end_child1 & 0xFFFF ) | ( uint32_t( _child2 ) << 16 ) ); } - tracy_force_inline void SetChild( int32_t child ) { memcpy( &_end_child1, &child, 2 ); _child2 = uint32_t( child ) >> 16; } - tracy_force_inline bool HasChildren() const { return ( _child2 >> 15 ) == 0; } + tracy_force_inline int32_t Child() const { int32_t child; memcpy( &child, &_child2, 4 ); return child; } + tracy_force_inline void SetChild( int32_t child ) { memcpy( &_child2, &child, 4 ); } + tracy_force_inline bool HasChildren() const { uint8_t tmp; memcpy( &tmp, ((char*)&_end_child1)+1, 1 ); return ( tmp >> 7 ) == 0; } uint64_t _start_srcloc; - uint64_t _end_child1; - StringIdx text; - Int24 callstack; - StringIdx name; uint16_t _child2; + uint64_t _end_child1; + uint32_t extra; }; enum { ZoneEventSize = sizeof( ZoneEvent ) }; static_assert( std::is_standard_layout::value, "ZoneEvent is not standard layout" ); +struct ZoneExtra +{ + Int24 callstack; + StringIdx text; + StringIdx name; +}; + +enum { ZoneExtraSize = sizeof( ZoneExtra ) }; + + struct LockEvent { enum class Type : uint8_t diff --git a/server/TracyVersion.hpp b/server/TracyVersion.hpp index 6b081aa5..bb0d918b 100644 --- a/server/TracyVersion.hpp +++ b/server/TracyVersion.hpp @@ -7,7 +7,7 @@ namespace Version { enum { Major = 0 }; enum { Minor = 6 }; -enum { Patch = 2 }; +enum { Patch = 3 }; } } diff --git a/server/TracyView.cpp b/server/TracyView.cpp index 3e498e1f..3b77de16 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -5429,6 +5429,21 @@ void View::DrawInfoWindow() } } +template +static inline uint32_t GetZoneCallstack( const T& ev, const Worker& worker ); + +template<> +static inline uint32_t GetZoneCallstack( const ZoneEvent& ev, const Worker& worker ) +{ + return worker.GetZoneExtra( ev ).callstack.Val(); +} + +template<> +static inline uint32_t GetZoneCallstack( const GpuEvent& ev, const Worker& worker ) +{ + return ev.callstack.Val(); +} + template void DrawZoneTrace( T zone, const std::vector& trace, const Worker& worker, BuzzAnim& anim, View& view, bool& showUnknownFrames, std::function showZone ) { @@ -5452,7 +5467,9 @@ void DrawZoneTrace( T zone, const std::vector& trace, const Worker& worker, B for( size_t i=0; icallstack.Val() == 0 || curr->callstack.Val() == 0 ) + const auto pcv = GetZoneCallstack( *prev, worker ); + const auto ccv = GetZoneCallstack( *curr, worker ); + if( pcv == 0 || ccv == 0 ) { if( showUnknownFrames ) { @@ -5461,10 +5478,10 @@ void DrawZoneTrace( T zone, const std::vector& trace, const Worker& worker, B TextDisabledUnformatted( "[unknown frames]" ); } } - else if( prev->callstack.Val() != curr->callstack.Val() ) + else if( pcv != ccv ) { - auto& prevCs = worker.GetCallstack( prev->callstack.Val() ); - auto& currCs = worker.GetCallstack( curr->callstack.Val() ); + auto& prevCs = worker.GetCallstack( pcv ); + auto& currCs = worker.GetCallstack( ccv ); const auto psz = int8_t( prevCs.size() ); int8_t idx; @@ -5531,7 +5548,8 @@ void DrawZoneTrace( T zone, const std::vector& trace, const Worker& worker, B } auto last = trace.empty() ? zone : trace.back(); - if( last->callstack.Val() == 0 ) + const auto lcv = GetZoneCallstack( *last, worker ); + if( lcv == 0 ) { if( showUnknownFrames ) { @@ -5542,7 +5560,7 @@ void DrawZoneTrace( T zone, const std::vector& trace, const Worker& worker, B } else { - auto& cs = worker.GetCallstack( last->callstack.Val() ); + auto& cs = worker.GetCallstack( lcv ); const auto csz = cs.size(); for( uint8_t i=1; iid; - if( ev.name.Active() ) + if( m_worker.HasZoneExtra( ev ) && m_worker.GetZoneExtra( ev ).name.Active() ) { if( m_bigFont ) ImGui::PushFont( m_bigFont ); - TextFocused( "Zone name:", m_worker.GetString( ev.name ) ); + TextFocused( "Zone name:", m_worker.GetString( m_worker.GetZoneExtra( ev ).name ) ); if( m_bigFont ) ImGui::PopFont(); if( srcloc.name.active ) { @@ -5829,9 +5848,9 @@ void View::DrawZoneInfoWindow() TextFocused( "Thread:", m_worker.GetThreadName( tid ) ); ImGui::SameLine(); ImGui::TextDisabled( "(%s)", RealToString( tid, true ) ); - if( ev.text.Active() ) + if( m_worker.HasZoneExtra( ev ) && m_worker.GetZoneExtra( ev ).text.Active() ) { - TextFocused( "User text:", m_worker.GetString( ev.text ) ); + TextFocused( "User text:", m_worker.GetString( m_worker.GetZoneExtra( ev ).text ) ); } ImGui::Separator(); @@ -7977,9 +7996,14 @@ uint64_t View::GetSelectionTarget( const Worker::ZoneThreadData& ev, FindZone::G case FindZone::GroupBy::Thread: return ev.Thread(); case FindZone::GroupBy::UserText: - return ev.Zone()->text.Active() ? ev.Zone()->text.Idx() : std::numeric_limits::max(); + { + const auto& zone = *ev.Zone(); + if( !m_worker.HasZoneExtra( zone ) ) return std::numeric_limits::max(); + const auto& extra = m_worker.GetZoneExtra( zone ); + return extra.text.Active() ? extra.text.Idx() : std::numeric_limits::max(); + } case FindZone::GroupBy::Callstack: - return ev.Zone()->callstack.Val(); + return m_worker.GetZoneExtra( *ev.Zone() ).callstack.Val(); case FindZone::GroupBy::Parent: { const auto parent = GetZoneParent( *ev.Zone(), m_worker.DecompressThread( ev.Thread() ) ); @@ -9185,10 +9209,21 @@ void View::DrawFindZone() gid = ev.Thread(); break; case FindZone::GroupBy::UserText: - gid = ev.Zone()->text.Active() ? ev.Zone()->text.Idx() : std::numeric_limits::max(); + { + const auto& zone = *ev.Zone(); + if( !m_worker.HasZoneExtra( zone ) ) + { + gid = std::numeric_limits::max(); + } + else + { + const auto& extra = m_worker.GetZoneExtra( zone ); + gid = extra.text.Active() ? extra.text.Idx() : std::numeric_limits::max(); + } break; + } case FindZone::GroupBy::Callstack: - gid = ev.Zone()->callstack.Val(); + gid = m_worker.GetZoneExtra( *ev.Zone() ).callstack.Val(); break; case FindZone::GroupBy::Parent: { @@ -9503,8 +9538,10 @@ void View::DrawZoneList( const Vector>& zones ) 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; + const auto hle = m_worker.HasZoneExtra( *lhs ); + const auto hre = m_worker.HasZoneExtra( *rhs ); + if( !( hle & hre ) ) return hle > hre; + return strcmp( m_worker.GetString( m_worker.GetZoneExtra( *lhs ).name ), m_worker.GetString( m_worker.GetZoneExtra( *rhs ).name ) ) < 0; } ); break; default: @@ -9549,9 +9586,13 @@ void View::DrawZoneList( const Vector>& zones ) ImGui::NextColumn(); ImGui::TextUnformatted( TimeToString( timespan ) ); ImGui::NextColumn(); - if( ev->name.Active() ) + if( m_worker.HasZoneExtra( *ev ) ) { - ImGui::TextUnformatted( m_worker.GetString( ev->name ) ); + const auto& extra = m_worker.GetZoneExtra( *ev ); + if( extra.name.Active() ) + { + ImGui::TextUnformatted( m_worker.GetString( extra.name ) ); + } } ImGui::NextColumn(); if( m_zoneHover == ev ) ImGui::PopStyleColor(); @@ -13852,9 +13893,9 @@ void View::ZoneTooltip( const ZoneEvent& ev ) const auto selftime = GetZoneSelfTime( ev ); ImGui::BeginTooltip(); - if( ev.name.Active() ) + if( m_worker.HasZoneExtra( ev ) && m_worker.GetZoneExtra( ev ).name.Active() ) { - ImGui::TextUnformatted( m_worker.GetString( ev.name ) ); + ImGui::TextUnformatted( m_worker.GetString( m_worker.GetZoneExtra( ev ).name ) ); } if( srcloc.name.active ) { @@ -13902,10 +13943,10 @@ void View::ZoneTooltip( const ZoneEvent& ev ) TextFocused( "Running state regions:", RealToString( cnt, true ) ); } } - if( ev.text.Active() ) + if( m_worker.HasZoneExtra( ev ) && m_worker.GetZoneExtra( ev ).text.Active() ) { ImGui::NewLine(); - TextColoredUnformatted( ImVec4( 0xCC / 255.f, 0xCC / 255.f, 0x22 / 255.f, 1.f ), m_worker.GetString( ev.text ) ); + TextColoredUnformatted( ImVec4( 0xCC / 255.f, 0xCC / 255.f, 0x22 / 255.f, 1.f ), m_worker.GetString( m_worker.GetZoneExtra( ev ).text ) ); } ImGui::EndTooltip(); } diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index 376cd0f0..b1286d9c 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -236,6 +236,7 @@ Worker::Worker( const char* addr, int port ) m_data.sourceLocationExpand.push_back( 0 ); m_data.localThreadCompress.InitZero(); m_data.callstackPayload.push_back( nullptr ); + m_data.zoneExtra.push_back( ZoneExtra {} ); memset( m_gpuCtxMap, 0, sizeof( m_gpuCtxMap ) ); @@ -262,6 +263,7 @@ Worker::Worker( const std::string& program, const std::vector= FileVersion( 0, 6, 3 ) ) + { + f.Read( sz ); + assert( sz != 0 ); + m_data.zoneExtra.reserve_exact( sz, m_slab ); + f.Read( m_data.zoneExtra.data(), sz * sizeof( ZoneExtra ) ); + } + else + { + m_data.zoneExtra.push_back( ZoneExtra {} ); + } + s_loadProgress.progress.store( LoadProgress::Zones, std::memory_order_relaxed ); f.Read( sz ); s_loadProgress.subTotal.store( sz, std::memory_order_relaxed ); @@ -931,10 +945,10 @@ Worker::Worker( FileRead& f, EventType::Type eventMask, bool bgTasks ) td->id = tid; if( tsz != 0 ) { - if( fileVer <= FileVersion( 0, 5, 9 ) ) + if( fileVer < FileVersion( 0, 6, 3 ) ) { int64_t refTime = 0; - ReadTimelinePre0510( f, td->timeline, tsz, refTime, fileVer ); + ReadTimelinePre063( f, td->timeline, tsz, refTime, childIdx, fileVer ); } else { @@ -2067,9 +2081,9 @@ const char* Worker::GetZoneName( const ZoneEvent& ev ) const const char* Worker::GetZoneName( const ZoneEvent& ev, const SourceLocation& srcloc ) const { - if( ev.name.Active() ) + if( HasZoneExtra( ev ) && GetZoneExtra( ev ).name.Active() ) { - return GetString( ev.name ); + return GetString( GetZoneExtra( ev ).name ); } else if( srcloc.name.active ) { @@ -3420,7 +3434,7 @@ ZoneEvent* Worker::AllocZoneEvent() ret = m_zoneEventPool.back_and_pop(); } #endif - memset( &ret->text, 0, sizeof( ZoneEvent::text ) + sizeof( ZoneEvent::callstack ) + sizeof( ZoneEvent::name ) ); + ret->extra = 0; return ret; } @@ -3767,13 +3781,15 @@ void Worker::ProcessZoneText( const QueueZoneText& ev ) auto zone = stack.back(); auto it = m_pendingCustomStrings.find( ev.text ); assert( it != m_pendingCustomStrings.end() ); - if( !zone->text.Active() ) + if( !HasZoneExtra( *zone ) ) AllocZoneExtra( *zone ); + auto& extra = GetZoneExtraMutable( *zone ); + if( !extra.text.Active() ) { - zone->text = StringIdx( it->second.idx ); + extra.text = StringIdx( it->second.idx ); } else { - const auto str0 = GetString( zone->text ); + const auto str0 = GetString( extra.text ); const auto str1 = it->second.ptr; const auto len0 = strlen( str0 ); const auto len1 = strlen( str1 ); @@ -3781,7 +3797,7 @@ void Worker::ProcessZoneText( const QueueZoneText& ev ) memcpy( buf, str0, len0 ); buf[len0] = '\n'; memcpy( buf+len0+1, str1, len1 ); - zone->text = StringIdx( StoreString( buf, len0+len1+1 ).idx ); + extra.text = StringIdx( StoreString( buf, len0+len1+1 ).idx ); } m_pendingCustomStrings.erase( it ); } @@ -3800,7 +3816,9 @@ void Worker::ProcessZoneName( const QueueZoneText& ev ) auto zone = stack.back(); auto it = m_pendingCustomStrings.find( ev.text ); assert( it != m_pendingCustomStrings.end() ); - zone->name = StringIdx( it->second.idx ); + if( !HasZoneExtra( *zone ) ) AllocZoneExtra( *zone ); + auto& extra = GetZoneExtraMutable( *zone ); + extra.name = StringIdx( it->second.idx ); m_pendingCustomStrings.erase( it ); } @@ -4456,8 +4474,12 @@ void Worker::ProcessCallstack( const QueueCallstack& ev ) switch( next.type ) { case NextCallstackType::Zone: - next.zone->callstack.SetVal( m_pendingCallstackId ); + { + if( !HasZoneExtra( *next.zone ) ) AllocZoneExtra( *next.zone ); + auto& extra = GetZoneExtraMutable( *next.zone ); + extra.callstack.SetVal( m_pendingCallstackId ); break; + } case NextCallstackType::Gpu: next.gpu->callstack.SetVal( m_pendingCallstackId ); break; @@ -4490,8 +4512,12 @@ void Worker::ProcessCallstackAlloc( const QueueCallstackAlloc& ev ) switch( next.type ) { case NextCallstackType::Zone: - next.zone->callstack.SetVal( m_pendingCallstackId ); + { + if( !HasZoneExtra( *next.zone ) ) AllocZoneExtra( *next.zone ); + auto& extra = GetZoneExtraMutable( *next.zone ); + extra.callstack.SetVal( m_pendingCallstackId ); break; + } case NextCallstackType::Gpu: next.gpu->callstack.SetVal( m_pendingCallstackId ); break; @@ -4992,7 +5018,7 @@ void Worker::ReadTimeline( FileRead& f, ZoneEvent* zone, int64_t& refTime, int32 } } -void Worker::ReadTimelinePre0510( FileRead& f, ZoneEvent* zone, int64_t& refTime, int fileVer ) +void Worker::ReadTimelinePre063( FileRead& f, ZoneEvent* zone, int64_t& refTime, int32_t& childIdx, int fileVer ) { uint64_t sz; f.Read( sz ); @@ -5002,12 +5028,22 @@ void Worker::ReadTimelinePre0510( FileRead& f, ZoneEvent* zone, int64_t& refTime } else { - const auto child = m_data.zoneChildren.size(); - zone->SetChild( child ); - m_data.zoneChildren.push_back( Vector>() ); - Vector> tmp; - ReadTimelinePre0510( f, tmp, sz, refTime, fileVer ); - m_data.zoneChildren[child] = std::move( tmp ); + if( fileVer >= FileVersion( 0, 5, 10 ) ) + { + const auto idx = childIdx; + childIdx++; + zone->SetChild( idx ); + ReadTimelinePre063( f, m_data.zoneChildren[idx], sz, refTime, childIdx, fileVer ); + } + else + { + const auto child = m_data.zoneChildren.size(); + zone->SetChild( child ); + m_data.zoneChildren.push_back( Vector>() ); + Vector> tmp; + ReadTimelinePre063( f, tmp, sz, refTime, childIdx, fileVer ); + m_data.zoneChildren[child] = std::move( tmp ); + } } } @@ -5104,7 +5140,7 @@ void Worker::ReadTimeline( FileRead& f, Vector>& _vec, uint f.Read( srcloc ); zone->SetSrcLoc( srcloc ); // Use zone->_end_child1 as scratch buffer for zone start time offset. - f.Read( &zone->_end_child1, sizeof( zone->_end_child1 ) + sizeof( zone->text ) + sizeof( zone->callstack ) + sizeof( zone->name ) ); + f.Read( &zone->_end_child1, sizeof( zone->_end_child1 ) + sizeof( zone->extra ) ); refTime += int64_t( zone->_end_child1 ); zone->SetStart( refTime ); ReadTimeline( f, zone, refTime, childIdx ); @@ -5116,9 +5152,9 @@ void Worker::ReadTimeline( FileRead& f, Vector>& _vec, uint while( ++zone != end ); } -void Worker::ReadTimelinePre0510( FileRead& f, Vector>& _vec, uint64_t size, int64_t& refTime, int fileVer ) +void Worker::ReadTimelinePre063( FileRead& f, Vector>& _vec, uint64_t size, int64_t& refTime, int32_t& childIdx, int fileVer ) { - assert( fileVer <= FileVersion( 0, 5, 9 ) ); + assert( fileVer < FileVersion( 0, 6, 3 ) ); assert( size != 0 ); auto& vec = *(Vector*)( &_vec ); vec.set_magic(); @@ -5151,43 +5187,50 @@ void Worker::ReadTimelinePre0510( FileRead& f, Vector>& _ve f.Skip( 2 ); } } + ZoneExtra extra; if( fileVer <= FileVersion( 0, 5, 7 ) ) { __StringIdxOld str; f.Read( str ); if( str.active ) { - zone->text.SetIdx( str.idx ); + extra.text.SetIdx( str.idx ); } else { - new ( &zone->text ) StringIdx(); + new ( &extra.text ) StringIdx(); } - f.Read( zone->callstack ); + f.Read( extra.callstack ); f.Skip( 1 ); f.Read( str ); if( str.active ) { - zone->name.SetIdx( str.idx ); + extra.name.SetIdx( str.idx ); } else { - new ( &zone->name ) StringIdx(); + new ( &extra.name ) StringIdx(); } } else { - f.Read( &zone->text, sizeof( zone->text ) ); - f.Read( &zone->callstack, sizeof( zone->callstack ) ); + f.Read( &extra.text, sizeof( extra.text ) ); + f.Read( &extra.callstack, sizeof( extra.callstack ) ); if( fileVer <= FileVersion( 0, 5, 8 ) ) { f.Skip( 1 ); } - f.Read( &zone->name, sizeof( zone->name ) ); + f.Read( &extra.name, sizeof( extra.name ) ); + } + zone->extra = 0; + if( extra.callstack.Val() != 0 || extra.name.Active() || extra.text.Active() ) + { + AllocZoneExtra( *zone ); + memcpy( &GetZoneExtraMutable( *zone ), &extra, sizeof( ZoneExtra ) ); } refTime += zone->_end_child1; zone->SetStart( refTime - m_data.baseTime ); - ReadTimelinePre0510( f, zone, refTime, fileVer ); + ReadTimelinePre063( f, zone, refTime, childIdx, fileVer ); int64_t end = ReadTimeOffset( f, refTime ); if( end >= 0 ) end -= m_data.baseTime; zone->SetEnd( end ); @@ -5510,6 +5553,10 @@ void Worker::Write( FileWrite& f ) } } + sz = m_data.zoneExtra.size(); + f.Write( &sz, sizeof( sz ) ); + f.Write( m_data.zoneExtra.data(), sz * sizeof( ZoneExtra ) ); + sz = 0; for( auto& v : m_data.threads ) sz += v->count; f.Write( &sz, sizeof( sz ) ); @@ -5735,10 +5782,7 @@ void Worker::WriteTimelineImpl( FileWrite& f, const V& vec, int64_t& refTime ) f.Write( &srcloc, sizeof( srcloc ) ); int64_t start = v.Start(); WriteTimeOffset( f, refTime, start ); - f.Write( &v.text, sizeof( v.text ) ); - f.Write( &v.callstack, sizeof( v.callstack ) ); - f.Write( &v.name, sizeof( v.name ) ); - + f.Write( &v.extra, sizeof( v.extra ) ); if( v.Child() < 0 ) { const uint64_t sz = 0; @@ -5748,7 +5792,6 @@ void Worker::WriteTimelineImpl( FileWrite& f, const V& vec, int64_t& refTime ) { WriteTimeline( f, GetZoneChildren( v.Child() ), refTime ); } - WriteTimeOffset( f, refTime, v.End() ); } } @@ -5873,4 +5916,12 @@ const Worker::CpuThreadTopology* Worker::GetThreadTopology( uint32_t cpuThread ) return &it->second; } +void Worker::AllocZoneExtra( ZoneEvent& ev ) +{ + assert( ev.extra == 0 ); + ev.extra = uint32_t( m_data.zoneExtra.size() ); + auto& extra = m_data.zoneExtra.push_next(); + memset( &extra, 0, sizeof( extra ) ); +} + } diff --git a/server/TracyWorker.hpp b/server/TracyWorker.hpp index f552b56f..c24a853c 100644 --- a/server/TracyWorker.hpp +++ b/server/TracyWorker.hpp @@ -184,6 +184,7 @@ private: Vector> messages; StringDiscovery plots; Vector threads; + Vector zoneExtra; MemData memory; uint64_t zonesCnt = 0; uint64_t gpuCnt = 0; @@ -402,6 +403,9 @@ public: tracy_force_inline const Vector>& GetZoneChildren( int32_t idx ) const { return m_data.zoneChildren[idx]; } tracy_force_inline const Vector>& GetGpuChildren( int32_t idx ) const { return m_data.gpuChildren[idx]; } + tracy_force_inline const bool HasZoneExtra( const ZoneEvent& ev ) const { return ev.extra != 0; } + tracy_force_inline const ZoneExtra& GetZoneExtra( const ZoneEvent& ev ) const { return m_data.zoneExtra[ev.extra]; } + std::vector GetMatchingSourceLocation( const char* query, bool ignoreCase ) const; #ifndef TRACY_NO_STATISTICS @@ -609,7 +613,7 @@ private: #endif tracy_force_inline void ReadTimeline( FileRead& f, ZoneEvent* zone, int64_t& refTime, int32_t& childIdx ); - tracy_force_inline void ReadTimelinePre0510( FileRead& f, ZoneEvent* zone, int64_t& refTime, int fileVer ); + tracy_force_inline void ReadTimelinePre063( FileRead& f, ZoneEvent* zone, int64_t& refTime, int32_t& childIdx, int fileVer ); tracy_force_inline void ReadTimeline( FileRead& f, GpuEvent* zone, int64_t& refTime, int64_t& refGpuTime, int32_t& childIdx ); tracy_force_inline void ReadTimelinePre0510( FileRead& f, GpuEvent* zone, int64_t& refTime, int64_t& refGpuTime, int fileVer ); @@ -619,8 +623,11 @@ private: tracy_force_inline void CountZoneStatistics( ZoneEvent* zone ); #endif + tracy_force_inline ZoneExtra& GetZoneExtraMutable( const ZoneEvent& ev ) { return m_data.zoneExtra[ev.extra]; } + tracy_force_inline void AllocZoneExtra( ZoneEvent& ev ); + void ReadTimeline( FileRead& f, Vector>& vec, uint64_t size, int64_t& refTime, int32_t& childIdx ); - void ReadTimelinePre0510( FileRead& f, Vector>& vec, uint64_t size, int64_t& refTime, int fileVer ); + void ReadTimelinePre063( FileRead& f, Vector>& vec, uint64_t size, int64_t& refTime, int32_t& childIdx, int fileVer ); void ReadTimeline( FileRead& f, Vector>& vec, uint64_t size, int64_t& refTime, int64_t& refGpuTime, int32_t& childIdx ); void ReadTimelinePre0510( FileRead& f, Vector>& vec, uint64_t size, int64_t& refTime, int64_t& refGpuTime, int fileVer );