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 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; }() };

View File

@ -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;

View File

@ -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 );

View File

@ -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;

View File

@ -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" );

View File

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

View File

@ -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,44 +1872,55 @@ 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 );
uint16_t sz; if( ev.hdr.type == QueueType::FrameImageData )
memcpy( &sz, ptr, sizeof( sz ) );
ptr += sizeof( sz );
switch( ev.hdr.type )
{ {
case QueueType::CustomStringData: uint32_t sz;
AddCustomString( ev.stringTransfer.ptr, ptr, sz ); memcpy( &sz, ptr, sizeof( sz ) );
break; ptr += sizeof( sz );
case QueueType::StringData: AddFrameImageData( ev.stringTransfer.ptr, ptr, sz );
AddString( ev.stringTransfer.ptr, ptr, sz ); ptr += sz;
m_serverQuerySpaceLeft++; }
break; else
case QueueType::ThreadName: {
AddThreadString( ev.stringTransfer.ptr, ptr, sz ); uint16_t sz;
m_serverQuerySpaceLeft++; memcpy( &sz, ptr, sizeof( sz ) );
break; ptr += sizeof( sz );
case QueueType::PlotName: switch( ev.hdr.type )
HandlePlotName( ev.stringTransfer.ptr, ptr, sz ); {
m_serverQuerySpaceLeft++; case QueueType::CustomStringData:
break; AddCustomString( ev.stringTransfer.ptr, ptr, sz );
case QueueType::SourceLocationPayload: break;
AddSourceLocationPayload( ev.stringTransfer.ptr, ptr, sz ); case QueueType::StringData:
break; AddString( ev.stringTransfer.ptr, ptr, sz );
case QueueType::CallstackPayload: m_serverQuerySpaceLeft++;
AddCallstackPayload( ev.stringTransfer.ptr, ptr, sz ); break;
break; case QueueType::ThreadName:
case QueueType::FrameName: AddThreadString( ev.stringTransfer.ptr, ptr, sz );
HandleFrameName( ev.stringTransfer.ptr, ptr, sz ); m_serverQuerySpaceLeft++;
m_serverQuerySpaceLeft++; break;
break; case QueueType::PlotName:
case QueueType::CallstackAllocPayload: HandlePlotName( ev.stringTransfer.ptr, ptr, sz );
AddCallstackAllocPayload( ev.stringTransfer.ptr, ptr, sz ); m_serverQuerySpaceLeft++;
break; break;
default: case QueueType::SourceLocationPayload:
assert( false ); AddSourceLocationPayload( ev.stringTransfer.ptr, ptr, sz );
break; 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; 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 );

View File

@ -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;