1
0
mirror of https://github.com/wolfpld/tracy.git synced 2025-03-20 07:40:02 +08:00

Add staging area for frame images.

Compressing frame images on a separate thread may cause frame image
arrival before frames are sent. Fix this issue by creating a staging
area in which frame images will wait for frames to arrive.

This probably breaks playback functionality, as non-existent frames may
be queried, but this problem seems to be very hard to find, so let's
ignore it for now.
This commit is contained in:
Bartosz Taudul 2019-06-27 13:04:27 +02:00
parent bb35f9a897
commit 7dc7ece2bd
2 changed files with 28 additions and 9 deletions

View File

@ -2951,10 +2951,18 @@ void Worker::ProcessFrameMark( const QueueFrameMark& ev )
Query( ServerQueryFrameName, name );
} );
int32_t frameImage = -1;
auto fis = m_frameImageStaging.find( fd->frames.size() );
if( fis != m_frameImageStaging.end() )
{
frameImage = fis->second;
m_frameImageStaging.erase( fis );
}
assert( fd->continuous == 1 );
const auto time = TscTime( ev.time );
assert( fd->frames.empty() || fd->frames.back().start <= time );
fd->frames.push_back( FrameEvent{ time, -1, -1 } );
fd->frames.push_back( FrameEvent{ time, -1, frameImage } );
m_data.lastTime = std::max( m_data.lastTime, time );
}
@ -3006,7 +3014,6 @@ void Worker::ProcessFrameImage( const QueueFrameImage& ev )
auto& frames = m_data.framesBase->frames;
const auto fidx = ev.frame - m_data.frameOffset + 1;
assert( fidx < frames.size() );
if( m_onDemand && fidx <= 1 )
{
m_pendingFrameImageData.erase( it );
@ -3017,11 +3024,6 @@ void Worker::ProcessFrameImage( const QueueFrameImage& ev )
FrameImageIndexFailure();
return;
}
if( frames[fidx].frameImage >= 0 )
{
FrameImageTwiceFailure();
return;
}
auto fi = m_slab.Alloc<FrameImage>();
fi->ptr = PackFrameImage( (const char*)it->second, ev.w, ev.h, fi->csz );
@ -3032,9 +3034,25 @@ void Worker::ProcessFrameImage( const QueueFrameImage& ev )
const auto idx = m_data.frameImage.size();
m_data.frameImage.push_back( fi );
frames[fidx].frameImage = idx;
m_pendingFrameImageData.erase( it );
if( fidx >= frames.size() )
{
if( m_frameImageStaging.find( fidx ) != m_frameImageStaging.end() )
{
FrameImageTwiceFailure();
return;
}
m_frameImageStaging.emplace( fidx, idx );
}
else if( frames[fidx].frameImage >= 0 )
{
FrameImageTwiceFailure();
}
else
{
frames[fidx].frameImage = idx;
}
}
void Worker::ProcessZoneText( const QueueZoneText& ev )

View File

@ -543,6 +543,7 @@ private:
Vector<ServerQueryPacket> m_serverQueryQueue;
size_t m_serverQuerySpaceLeft;
flat_hash_map<uint64_t, int32_t> m_frameImageStaging;
char* m_frameImageBuffer = nullptr;
size_t m_frameImageBufferSize = 0;
};