Frame image transfer prototype.

This commit is contained in:
Bartosz Taudul 2019-06-06 21:39:54 +02:00
parent a37348c5c7
commit e5bb6011c5
8 changed files with 153 additions and 38 deletions

View File

@ -24,6 +24,8 @@
#define FrameMarkStart(x)
#define FrameMarkEnd(x)
#define FrameImage(x,y,z)
#define TracyLockable( type, varname ) type varname;
#define TracyLockableN( type, varname, desc ) type varname;
#define TracySharedLockable( type, varname ) type varname;
@ -86,6 +88,8 @@
#define FrameMarkStart( name ) tracy::Profiler::SendFrameMark( name, tracy::QueueType::FrameMarkMsgStart );
#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 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; }() };

View File

@ -1362,6 +1362,10 @@ static void FreeAssociatedMemory( const QueueItem& item )
ptr = MemRead<uint64_t>( &item.callstackAlloc.ptr );
tracy_free( (void*)ptr );
break;
case QueueType::FrameImage:
ptr = MemRead<uint64_t>( &item.frameImage.image );
tracy_free( (void*)ptr );
break;
default:
assert( false );
break;
@ -1446,6 +1450,11 @@ Profiler::DequeueStatus Profiler::Dequeue( moodycamel::ConsumerToken& token )
SendCallstackAlloc( ptr );
tracy_free( (void*)ptr );
break;
case QueueType::FrameImage:
ptr = MemRead<uint64_t>( &item->frameImage.image );
SendLongString( ptr, (const char*)ptr, QueueType::FrameImageData );
tracy_free( (void*)ptr );
break;
default:
assert( false );
break;
@ -1567,6 +1576,26 @@ void Profiler::SendString( uint64_t str, const char* ptr, QueueType type )
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 )
{
auto srcloc = (const SourceLocationData*)ptr;

View File

@ -170,6 +170,25 @@ public:
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 )
{
#ifdef TRACY_ON_DEMAND
@ -422,6 +441,7 @@ private:
bool SendData( const char* data, size_t len );
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 SendSourceLocationPayload( uint64_t ptr );
void SendCallstackPayload( uint64_t ptr );

View File

@ -9,7 +9,7 @@
namespace tracy
{
enum : uint32_t { ProtocolVersion = 6 };
enum : uint32_t { ProtocolVersion = 7 };
using lz4sz_t = uint32_t;

View File

@ -17,6 +17,7 @@ enum class QueueType : uint8_t
CallstackMemory,
Callstack,
CallstackAlloc,
FrameImage,
Terminate,
KeepAlive,
Crash,
@ -61,6 +62,7 @@ enum class QueueType : uint8_t
CallstackPayload,
CallstackAllocPayload,
FrameName,
FrameImageData,
NUM_TYPES
};
@ -98,6 +100,13 @@ struct QueueFrameMark
uint64_t name; // ptr
};
struct QueueFrameImage
{
uint64_t image; // ptr
uint16_t w;
uint16_t h;
};
struct QueueSourceLocation
{
uint64_t name;
@ -310,6 +319,7 @@ struct QueueItem
QueueZoneValidation zoneValidation;
QueueStringTransfer stringTransfer;
QueueFrameMark frameMark;
QueueFrameImage frameImage;
QueueSourceLocation srcloc;
QueueZoneText zoneText;
QueueLockAnnounce lockAnnounce;
@ -351,6 +361,7 @@ static const size_t QueueDataSize[] = {
sizeof( QueueHeader ) + sizeof( QueueCallstackMemory ),
sizeof( QueueHeader ) + sizeof( QueueCallstack ),
sizeof( QueueHeader ) + sizeof( QueueCallstackAlloc ),
sizeof( QueueHeader ) + sizeof( QueueFrameImage ),
// above items must be first
sizeof( QueueHeader ), // terminate
sizeof( QueueHeader ), // keep alive
@ -397,6 +408,7 @@ static const size_t QueueDataSize[] = {
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // callstack payload
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // callstack alloc payload
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame name
sizeof( QueueHeader ) + sizeof( QueueStringTransfer ), // frame image data
};
static_assert( QueueItemSize == 32, "Queue item size not 32 bytes" );

View File

@ -356,6 +356,12 @@ struct SourceLocationComparator
}
};
struct FrameImage
{
const char* ptr;
uint16_t w, h;
};
}
#endif

View File

@ -1825,7 +1825,8 @@ void Worker::Exec()
if( m_terminate )
{
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;
}
@ -1871,44 +1872,55 @@ bool Worker::DispatchProcess( const QueueItem& ev, char*& ptr )
if( ev.hdr.idx >= (int)QueueType::StringData )
{
ptr += sizeof( QueueHeader ) + sizeof( QueueStringTransfer );
uint16_t sz;
memcpy( &sz, ptr, sizeof( sz ) );
ptr += sizeof( sz );
switch( ev.hdr.type )
if( ev.hdr.type == QueueType::FrameImageData )
{
case QueueType::CustomStringData:
AddCustomString( ev.stringTransfer.ptr, ptr, sz );
break;
case QueueType::StringData:
AddString( ev.stringTransfer.ptr, ptr, sz );
m_serverQuerySpaceLeft++;
break;
case QueueType::ThreadName:
AddThreadString( ev.stringTransfer.ptr, ptr, sz );
m_serverQuerySpaceLeft++;
break;
case QueueType::PlotName:
HandlePlotName( ev.stringTransfer.ptr, ptr, sz );
m_serverQuerySpaceLeft++;
break;
case QueueType::SourceLocationPayload:
AddSourceLocationPayload( ev.stringTransfer.ptr, ptr, sz );
break;
case QueueType::CallstackPayload:
AddCallstackPayload( ev.stringTransfer.ptr, ptr, sz );
break;
case QueueType::FrameName:
HandleFrameName( ev.stringTransfer.ptr, ptr, sz );
m_serverQuerySpaceLeft++;
break;
case QueueType::CallstackAllocPayload:
AddCallstackAllocPayload( ev.stringTransfer.ptr, ptr, sz );
break;
default:
assert( false );
break;
uint32_t sz;
memcpy( &sz, ptr, sizeof( sz ) );
ptr += sizeof( sz );
AddFrameImageData( ev.stringTransfer.ptr, ptr, sz );
ptr += sz;
}
else
{
uint16_t sz;
memcpy( &sz, ptr, sizeof( sz ) );
ptr += sizeof( sz );
switch( ev.hdr.type )
{
case QueueType::CustomStringData:
AddCustomString( ev.stringTransfer.ptr, ptr, sz );
break;
case QueueType::StringData:
AddString( ev.stringTransfer.ptr, ptr, sz );
m_serverQuerySpaceLeft++;
break;
case QueueType::ThreadName:
AddThreadString( ev.stringTransfer.ptr, ptr, sz );
m_serverQuerySpaceLeft++;
break;
case QueueType::PlotName:
HandlePlotName( ev.stringTransfer.ptr, ptr, sz );
m_serverQuerySpaceLeft++;
break;
case QueueType::SourceLocationPayload:
AddSourceLocationPayload( ev.stringTransfer.ptr, ptr, sz );
break;
case QueueType::CallstackPayload:
AddCallstackPayload( ev.stringTransfer.ptr, ptr, sz );
break;
case QueueType::FrameName:
HandleFrameName( ev.stringTransfer.ptr, ptr, sz );
m_serverQuerySpaceLeft++;
break;
case QueueType::CallstackAllocPayload:
AddCallstackAllocPayload( ev.stringTransfer.ptr, ptr, sz );
break;
default:
assert( false );
break;
}
ptr += sz;
}
ptr += sz;
return true;
}
else
@ -2223,6 +2235,14 @@ void Worker::AddCustomString( uint64_t ptr, char* str, size_t 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
{
assert( id.sel == 0 );
@ -2486,6 +2506,9 @@ bool Worker::Process( const QueueItem& ev )
case QueueType::FrameMarkMsgEnd:
ProcessFrameMarkEnd( ev.frameMark );
break;
case QueueType::FrameImage:
ProcessFrameImage( ev.frameImage );
break;
case QueueType::SourceLocation:
AddSourceLocation( ev.srcloc );
m_serverQuerySpaceLeft++;
@ -2848,6 +2871,22 @@ void Worker::ProcessFrameMarkEnd( const QueueFrameMark& ev )
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 )
{
auto tit = m_threadMap.find( ev.thread );

View File

@ -181,6 +181,8 @@ private:
Vector<Vector<ZoneEvent*>> zoneVectorCache;
Vector<FrameImage*> frameImage;
CrashEvent crashEvent;
};
@ -354,6 +356,7 @@ private:
tracy_force_inline void ProcessFrameMark( const QueueFrameMark& ev );
tracy_force_inline void ProcessFrameMarkStart( 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 ProcessZoneName( const QueueZoneText& 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 AddThreadString( uint64_t id, 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 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, ThreadData*, nohash<uint64_t>> m_threadMap;
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_pendingThreads;