mirror of
https://github.com/wolfpld/tracy.git
synced 2024-12-02 01:44:34 +00:00
Frame image transfer prototype.
This commit is contained in:
parent
a37348c5c7
commit
e5bb6011c5
@ -24,6 +24,8 @@
|
|||||||
#define FrameMarkStart(x)
|
#define FrameMarkStart(x)
|
||||||
#define FrameMarkEnd(x)
|
#define FrameMarkEnd(x)
|
||||||
|
|
||||||
|
#define FrameImage(x,y,z)
|
||||||
|
|
||||||
#define TracyLockable( type, varname ) type varname;
|
#define TracyLockable( type, varname ) type varname;
|
||||||
#define TracyLockableN( type, varname, desc ) type varname;
|
#define TracyLockableN( type, varname, desc ) type varname;
|
||||||
#define TracySharedLockable( type, varname ) type varname;
|
#define TracySharedLockable( type, varname ) type varname;
|
||||||
@ -86,6 +88,8 @@
|
|||||||
#define FrameMarkStart( name ) tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgStart );
|
#define FrameMarkStart( name ) tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgStart );
|
||||||
#define FrameMarkEnd( name ) tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgEnd );
|
#define FrameMarkEnd( name ) tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgEnd );
|
||||||
|
|
||||||
|
#define FrameImage( image, width, height ) tracy::Profiler::SendFrameImage( image, width, height );
|
||||||
|
|
||||||
#define TracyLockable( type, varname ) tracy::Lockable<type> varname { [] () -> const tracy::SourceLocationData* { static const tracy::SourceLocationData srcloc { nullptr, #type " " #varname, __FILE__, __LINE__, 0 }; return &srcloc; }() };
|
#define TracyLockable( type, varname ) tracy::Lockable<type> varname { [] () -> const tracy::SourceLocationData* { static const tracy::SourceLocationData srcloc { nullptr, #type " " #varname, __FILE__, __LINE__, 0 }; return &srcloc; }() };
|
||||||
#define TracyLockableN( type, varname, desc ) tracy::Lockable<type> varname { [] () -> const tracy::SourceLocationData* { static const tracy::SourceLocationData srcloc { nullptr, desc, __FILE__, __LINE__, 0 }; return &srcloc; }() };
|
#define TracyLockableN( type, varname, desc ) tracy::Lockable<type> varname { [] () -> const tracy::SourceLocationData* { static const tracy::SourceLocationData srcloc { nullptr, desc, __FILE__, __LINE__, 0 }; return &srcloc; }() };
|
||||||
#define TracySharedLockable( type, varname ) tracy::SharedLockable<type> varname { [] () -> const tracy::SourceLocationData* { static const tracy::SourceLocationData srcloc { nullptr, #type " " #varname, __FILE__, __LINE__, 0 }; return &srcloc; }() };
|
#define TracySharedLockable( type, varname ) tracy::SharedLockable<type> varname { [] () -> const tracy::SourceLocationData* { static const tracy::SourceLocationData srcloc { nullptr, #type " " #varname, __FILE__, __LINE__, 0 }; return &srcloc; }() };
|
||||||
|
@ -1362,6 +1362,10 @@ static void FreeAssociatedMemory( const QueueItem& item )
|
|||||||
ptr = MemRead<uint64_t>( &item.callstackAlloc.ptr );
|
ptr = MemRead<uint64_t>( &item.callstackAlloc.ptr );
|
||||||
tracy_free( (void*)ptr );
|
tracy_free( (void*)ptr );
|
||||||
break;
|
break;
|
||||||
|
case QueueType::FrameImage:
|
||||||
|
ptr = MemRead<uint64_t>( &item.frameImage.image );
|
||||||
|
tracy_free( (void*)ptr );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert( false );
|
assert( false );
|
||||||
break;
|
break;
|
||||||
@ -1446,6 +1450,11 @@ Profiler::DequeueStatus Profiler::Dequeue( moodycamel::ConsumerToken& token )
|
|||||||
SendCallstackAlloc( ptr );
|
SendCallstackAlloc( ptr );
|
||||||
tracy_free( (void*)ptr );
|
tracy_free( (void*)ptr );
|
||||||
break;
|
break;
|
||||||
|
case QueueType::FrameImage:
|
||||||
|
ptr = MemRead<uint64_t>( &item->frameImage.image );
|
||||||
|
SendLongString( ptr, (const char*)ptr, QueueType::FrameImageData );
|
||||||
|
tracy_free( (void*)ptr );
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
assert( false );
|
assert( false );
|
||||||
break;
|
break;
|
||||||
@ -1567,6 +1576,26 @@ void Profiler::SendString( uint64_t str, const char* ptr, QueueType type )
|
|||||||
AppendDataUnsafe( ptr, l16 );
|
AppendDataUnsafe( ptr, l16 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Profiler::SendLongString( uint64_t str, const char* ptr, QueueType type )
|
||||||
|
{
|
||||||
|
assert( type == QueueType::FrameImageData );
|
||||||
|
|
||||||
|
QueueItem item;
|
||||||
|
MemWrite( &item.hdr.type, type );
|
||||||
|
MemWrite( &item.stringTransfer.ptr, str );
|
||||||
|
|
||||||
|
auto len = strlen( ptr );
|
||||||
|
assert( len <= std::numeric_limits<uint32_t>::max() );
|
||||||
|
assert( QueueDataSize[(int)type] + sizeof( uint32_t ) + len <= TargetFrameSize );
|
||||||
|
auto l32 = uint32_t( len );
|
||||||
|
|
||||||
|
NeedDataSize( QueueDataSize[(int)type] + sizeof( l32 ) + l32 );
|
||||||
|
|
||||||
|
AppendDataUnsafe( &item, QueueDataSize[(int)type] );
|
||||||
|
AppendDataUnsafe( &l32, sizeof( l32 ) );
|
||||||
|
AppendDataUnsafe( ptr, l32 );
|
||||||
|
}
|
||||||
|
|
||||||
void Profiler::SendSourceLocation( uint64_t ptr )
|
void Profiler::SendSourceLocation( uint64_t ptr )
|
||||||
{
|
{
|
||||||
auto srcloc = (const SourceLocationData*)ptr;
|
auto srcloc = (const SourceLocationData*)ptr;
|
||||||
|
@ -170,6 +170,25 @@ public:
|
|||||||
GetProfiler().m_serialLock.unlock();
|
GetProfiler().m_serialLock.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static tracy_force_inline void SendFrameImage( void* image, uint16_t w, uint16_t h )
|
||||||
|
{
|
||||||
|
#ifdef TRACY_ON_DEMAND
|
||||||
|
if( !GetProfiler().IsConnected() ) return;
|
||||||
|
#endif
|
||||||
|
const auto sz = size_t( w ) * size_t( h ) * 4;
|
||||||
|
Magic magic;
|
||||||
|
auto token = GetToken();
|
||||||
|
auto ptr = (char*)tracy_malloc( sz );
|
||||||
|
memcpy( ptr, image, sz );
|
||||||
|
auto& tail = token->get_tail_index();
|
||||||
|
auto item = token->enqueue_begin<tracy::moodycamel::CanAlloc>( magic );
|
||||||
|
MemWrite( &item->hdr.type, QueueType::FrameImage );
|
||||||
|
MemWrite( &item->frameImage.image, (uint64_t)ptr );
|
||||||
|
MemWrite( &item->frameImage.w, w );
|
||||||
|
MemWrite( &item->frameImage.h, h );
|
||||||
|
tail.store( magic + 1, std::memory_order_release );
|
||||||
|
}
|
||||||
|
|
||||||
static tracy_force_inline void PlotData( const char* name, int64_t val )
|
static tracy_force_inline void PlotData( const char* name, int64_t val )
|
||||||
{
|
{
|
||||||
#ifdef TRACY_ON_DEMAND
|
#ifdef TRACY_ON_DEMAND
|
||||||
@ -422,6 +441,7 @@ private:
|
|||||||
|
|
||||||
bool SendData( const char* data, size_t len );
|
bool SendData( const char* data, size_t len );
|
||||||
void SendString( uint64_t ptr, const char* str, QueueType type );
|
void SendString( uint64_t ptr, const char* str, QueueType type );
|
||||||
|
void SendLongString( uint64_t ptr, const char* str, QueueType type );
|
||||||
void SendSourceLocation( uint64_t ptr );
|
void SendSourceLocation( uint64_t ptr );
|
||||||
void SendSourceLocationPayload( uint64_t ptr );
|
void SendSourceLocationPayload( uint64_t ptr );
|
||||||
void SendCallstackPayload( uint64_t ptr );
|
void SendCallstackPayload( uint64_t ptr );
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
namespace tracy
|
namespace tracy
|
||||||
{
|
{
|
||||||
|
|
||||||
enum : uint32_t { ProtocolVersion = 6 };
|
enum : uint32_t { ProtocolVersion = 7 };
|
||||||
|
|
||||||
using lz4sz_t = uint32_t;
|
using lz4sz_t = uint32_t;
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ enum class QueueType : uint8_t
|
|||||||
CallstackMemory,
|
CallstackMemory,
|
||||||
Callstack,
|
Callstack,
|
||||||
CallstackAlloc,
|
CallstackAlloc,
|
||||||
|
FrameImage,
|
||||||
Terminate,
|
Terminate,
|
||||||
KeepAlive,
|
KeepAlive,
|
||||||
Crash,
|
Crash,
|
||||||
@ -61,6 +62,7 @@ enum class QueueType : uint8_t
|
|||||||
CallstackPayload,
|
CallstackPayload,
|
||||||
CallstackAllocPayload,
|
CallstackAllocPayload,
|
||||||
FrameName,
|
FrameName,
|
||||||
|
FrameImageData,
|
||||||
NUM_TYPES
|
NUM_TYPES
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -98,6 +100,13 @@ struct QueueFrameMark
|
|||||||
uint64_t name; // ptr
|
uint64_t name; // ptr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct QueueFrameImage
|
||||||
|
{
|
||||||
|
uint64_t image; // ptr
|
||||||
|
uint16_t w;
|
||||||
|
uint16_t h;
|
||||||
|
};
|
||||||
|
|
||||||
struct QueueSourceLocation
|
struct QueueSourceLocation
|
||||||
{
|
{
|
||||||
uint64_t name;
|
uint64_t name;
|
||||||
@ -310,6 +319,7 @@ struct QueueItem
|
|||||||
QueueZoneValidation zoneValidation;
|
QueueZoneValidation zoneValidation;
|
||||||
QueueStringTransfer stringTransfer;
|
QueueStringTransfer stringTransfer;
|
||||||
QueueFrameMark frameMark;
|
QueueFrameMark frameMark;
|
||||||
|
QueueFrameImage frameImage;
|
||||||
QueueSourceLocation srcloc;
|
QueueSourceLocation srcloc;
|
||||||
QueueZoneText zoneText;
|
QueueZoneText zoneText;
|
||||||
QueueLockAnnounce lockAnnounce;
|
QueueLockAnnounce lockAnnounce;
|
||||||
@ -351,6 +361,7 @@ static const size_t QueueDataSize[] = {
|
|||||||
sizeof( QueueHeader ) + sizeof( QueueCallstackMemory ),
|
sizeof( QueueHeader ) + sizeof( QueueCallstackMemory ),
|
||||||
sizeof( QueueHeader ) + sizeof( QueueCallstack ),
|
sizeof( QueueHeader ) + sizeof( QueueCallstack ),
|
||||||
sizeof( QueueHeader ) + sizeof( QueueCallstackAlloc ),
|
sizeof( QueueHeader ) + sizeof( QueueCallstackAlloc ),
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueFrameImage ),
|
||||||
// above items must be first
|
// above items must be first
|
||||||
sizeof( QueueHeader ), // terminate
|
sizeof( QueueHeader ), // terminate
|
||||||
sizeof( QueueHeader ), // keep alive
|
sizeof( QueueHeader ), // keep alive
|
||||||
@ -397,6 +408,7 @@ static const size_t QueueDataSize[] = {
|
|||||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // callstack payload
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // callstack payload
|
||||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // callstack alloc payload
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // callstack alloc payload
|
||||||
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame name
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame name
|
||||||
|
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame image data
|
||||||
};
|
};
|
||||||
|
|
||||||
static_assert( QueueItemSize == 32, "Queue item size not 32 bytes" );
|
static_assert( QueueItemSize == 32, "Queue item size not 32 bytes" );
|
||||||
|
@ -356,6 +356,12 @@ struct SourceLocationComparator
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct FrameImage
|
||||||
|
{
|
||||||
|
const char* ptr;
|
||||||
|
uint16_t w, h;
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1825,7 +1825,8 @@ void Worker::Exec()
|
|||||||
if( m_terminate )
|
if( m_terminate )
|
||||||
{
|
{
|
||||||
if( m_pendingStrings != 0 || m_pendingThreads != 0 || m_pendingSourceLocation != 0 || m_pendingCallstackFrames != 0 ||
|
if( m_pendingStrings != 0 || m_pendingThreads != 0 || m_pendingSourceLocation != 0 || m_pendingCallstackFrames != 0 ||
|
||||||
!m_pendingCustomStrings.empty() || m_data.plots.IsPending() || m_pendingCallstackPtr != 0 || m_pendingCallstackSubframes != 0 )
|
!m_pendingCustomStrings.empty() || m_data.plots.IsPending() || m_pendingCallstackPtr != 0 ||
|
||||||
|
m_pendingCallstackSubframes != 0 || !m_pendingFrameImageData.empty() )
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1871,6 +1872,16 @@ bool Worker::DispatchProcess( const QueueItem& ev, char*& ptr )
|
|||||||
if( ev.hdr.idx >= (int)QueueType::StringData )
|
if( ev.hdr.idx >= (int)QueueType::StringData )
|
||||||
{
|
{
|
||||||
ptr += sizeof( QueueHeader ) + sizeof( QueueStringTransfer );
|
ptr += sizeof( QueueHeader ) + sizeof( QueueStringTransfer );
|
||||||
|
if( ev.hdr.type == QueueType::FrameImageData )
|
||||||
|
{
|
||||||
|
uint32_t sz;
|
||||||
|
memcpy( &sz, ptr, sizeof( sz ) );
|
||||||
|
ptr += sizeof( sz );
|
||||||
|
AddFrameImageData( ev.stringTransfer.ptr, ptr, sz );
|
||||||
|
ptr += sz;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
uint16_t sz;
|
uint16_t sz;
|
||||||
memcpy( &sz, ptr, sizeof( sz ) );
|
memcpy( &sz, ptr, sizeof( sz ) );
|
||||||
ptr += sizeof( sz );
|
ptr += sizeof( sz );
|
||||||
@ -1909,6 +1920,7 @@ bool Worker::DispatchProcess( const QueueItem& ev, char*& ptr )
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ptr += sz;
|
ptr += sz;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -2223,6 +2235,14 @@ void Worker::AddCustomString( uint64_t ptr, char* str, size_t sz )
|
|||||||
m_pendingCustomStrings.emplace( ptr, StoreString( str, sz ) );
|
m_pendingCustomStrings.emplace( ptr, StoreString( str, sz ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Worker::AddFrameImageData( uint64_t ptr, char* data, size_t sz )
|
||||||
|
{
|
||||||
|
assert( m_pendingFrameImageData.find( ptr ) == m_pendingFrameImageData.end() );
|
||||||
|
auto image = m_slab.AllocBig( sz );
|
||||||
|
memcpy( image, data, sz );
|
||||||
|
m_pendingFrameImageData.emplace( ptr, image );
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t Worker::GetCanonicalPointer( const CallstackFrameId& id ) const
|
uint64_t Worker::GetCanonicalPointer( const CallstackFrameId& id ) const
|
||||||
{
|
{
|
||||||
assert( id.sel == 0 );
|
assert( id.sel == 0 );
|
||||||
@ -2486,6 +2506,9 @@ bool Worker::Process( const QueueItem& ev )
|
|||||||
case QueueType::FrameMarkMsgEnd:
|
case QueueType::FrameMarkMsgEnd:
|
||||||
ProcessFrameMarkEnd( ev.frameMark );
|
ProcessFrameMarkEnd( ev.frameMark );
|
||||||
break;
|
break;
|
||||||
|
case QueueType::FrameImage:
|
||||||
|
ProcessFrameImage( ev.frameImage );
|
||||||
|
break;
|
||||||
case QueueType::SourceLocation:
|
case QueueType::SourceLocation:
|
||||||
AddSourceLocation( ev.srcloc );
|
AddSourceLocation( ev.srcloc );
|
||||||
m_serverQuerySpaceLeft++;
|
m_serverQuerySpaceLeft++;
|
||||||
@ -2848,6 +2871,22 @@ void Worker::ProcessFrameMarkEnd( const QueueFrameMark& ev )
|
|||||||
m_data.lastTime = std::max( m_data.lastTime, time );
|
m_data.lastTime = std::max( m_data.lastTime, time );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Worker::ProcessFrameImage( const QueueFrameImage& ev )
|
||||||
|
{
|
||||||
|
auto it = m_pendingFrameImageData.find( ev.image );
|
||||||
|
assert( it != m_pendingFrameImageData.end() );
|
||||||
|
|
||||||
|
auto fi = m_slab.Alloc<FrameImage>();
|
||||||
|
fi->ptr = (const char*)it->second;
|
||||||
|
fi->w = ev.w;
|
||||||
|
fi->h = ev.h;
|
||||||
|
|
||||||
|
const auto idx = m_data.frameImage.size();
|
||||||
|
m_data.frameImage.push_back( fi );
|
||||||
|
|
||||||
|
m_pendingFrameImageData.erase( it );
|
||||||
|
}
|
||||||
|
|
||||||
void Worker::ProcessZoneText( const QueueZoneText& ev )
|
void Worker::ProcessZoneText( const QueueZoneText& ev )
|
||||||
{
|
{
|
||||||
auto tit = m_threadMap.find( ev.thread );
|
auto tit = m_threadMap.find( ev.thread );
|
||||||
|
@ -181,6 +181,8 @@ private:
|
|||||||
|
|
||||||
Vector<Vector<ZoneEvent*>> zoneVectorCache;
|
Vector<Vector<ZoneEvent*>> zoneVectorCache;
|
||||||
|
|
||||||
|
Vector<FrameImage*> frameImage;
|
||||||
|
|
||||||
CrashEvent crashEvent;
|
CrashEvent crashEvent;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -354,6 +356,7 @@ private:
|
|||||||
tracy_force_inline void ProcessFrameMark( const QueueFrameMark& ev );
|
tracy_force_inline void ProcessFrameMark( const QueueFrameMark& ev );
|
||||||
tracy_force_inline void ProcessFrameMarkStart( const QueueFrameMark& ev );
|
tracy_force_inline void ProcessFrameMarkStart( const QueueFrameMark& ev );
|
||||||
tracy_force_inline void ProcessFrameMarkEnd( const QueueFrameMark& ev );
|
tracy_force_inline void ProcessFrameMarkEnd( const QueueFrameMark& ev );
|
||||||
|
tracy_force_inline void ProcessFrameImage( const QueueFrameImage& ev );
|
||||||
tracy_force_inline void ProcessZoneText( const QueueZoneText& ev );
|
tracy_force_inline void ProcessZoneText( const QueueZoneText& ev );
|
||||||
tracy_force_inline void ProcessZoneName( const QueueZoneText& ev );
|
tracy_force_inline void ProcessZoneName( const QueueZoneText& ev );
|
||||||
tracy_force_inline void ProcessLockAnnounce( const QueueLockAnnounce& ev );
|
tracy_force_inline void ProcessLockAnnounce( const QueueLockAnnounce& ev );
|
||||||
@ -425,6 +428,7 @@ private:
|
|||||||
void AddString( uint64_t ptr, char* str, size_t sz );
|
void AddString( uint64_t ptr, char* str, size_t sz );
|
||||||
void AddThreadString( uint64_t id, char* str, size_t sz );
|
void AddThreadString( uint64_t id, char* str, size_t sz );
|
||||||
void AddCustomString( uint64_t ptr, char* str, size_t sz );
|
void AddCustomString( uint64_t ptr, char* str, size_t sz );
|
||||||
|
void AddFrameImageData( uint64_t ptr, char* data, size_t sz );
|
||||||
|
|
||||||
tracy_force_inline void AddCallstackPayload( uint64_t ptr, char* data, size_t sz );
|
tracy_force_inline void AddCallstackPayload( uint64_t ptr, char* data, size_t sz );
|
||||||
tracy_force_inline void AddCallstackAllocPayload( uint64_t ptr, char* data, size_t sz );
|
tracy_force_inline void AddCallstackAllocPayload( uint64_t ptr, char* data, size_t sz );
|
||||||
@ -491,6 +495,7 @@ private:
|
|||||||
flat_hash_map<uint64_t, uint32_t, nohash<uint64_t>> m_sourceLocationShrink;
|
flat_hash_map<uint64_t, uint32_t, nohash<uint64_t>> m_sourceLocationShrink;
|
||||||
flat_hash_map<uint64_t, ThreadData*, nohash<uint64_t>> m_threadMap;
|
flat_hash_map<uint64_t, ThreadData*, nohash<uint64_t>> m_threadMap;
|
||||||
flat_hash_map<uint64_t, NextCallstack, nohash<uint64_t>> m_nextCallstack;
|
flat_hash_map<uint64_t, NextCallstack, nohash<uint64_t>> m_nextCallstack;
|
||||||
|
flat_hash_map<uint64_t, void*, nohash<uint64_t>> m_pendingFrameImageData;
|
||||||
|
|
||||||
uint32_t m_pendingStrings;
|
uint32_t m_pendingStrings;
|
||||||
uint32_t m_pendingThreads;
|
uint32_t m_pendingThreads;
|
||||||
|
Loading…
Reference in New Issue
Block a user