diff --git a/server/TracyWorker.cpp b/server/TracyWorker.cpp index cc89cd1f..2ddc1609 100644 --- a/server/TracyWorker.cpp +++ b/server/TracyWorker.cpp @@ -36,6 +36,7 @@ #include "../common/TracySystem.hpp" #include "TracyFileRead.hpp" #include "TracyFileWrite.hpp" +#include "TracyTaskDispatch.hpp" #include "TracyVersion.hpp" #include "TracyWorker.hpp" @@ -1347,38 +1348,98 @@ Worker::Worker( FileRead& f, EventType::Type eventMask ) if( eventMask & EventType::FrameImages ) { - size_t tmpbufsz = 0; - char* tmpbuf = nullptr; f.Read( sz ); m_data.frameImage.reserve_exact( sz, m_slab ); s_loadProgress.subTotal.store( sz, std::memory_order_relaxed ); - for( uint64_t i=0; i(); - f.Read2( fi->w, fi->h ); - f.Read( fi->flip ); - const auto sz = size_t( fi->w * fi->h / 2 ); - if( tmpbufsz < sz ) + struct JobData { - tmpbufsz = sz; - delete[] tmpbuf; - tmpbuf = new char[sz]; - } - f.Read( tmpbuf, sz ); - fi->ptr = PackFrameImage( tmpbuf, fi->w, fi->h, fi->csz ); - m_data.frameImage[i] = fi; - } - delete[] tmpbuf; + enum State : int { InProgress, Available, DataReady }; + FrameImage* fi; + char* buf = nullptr; + size_t bufsz = 0; + char* outbuf = nullptr; + size_t outsz = 0; + std::atomic state = Available; + }; - const auto& frames = GetFramesBase()->frames; - const auto fsz = uint32_t( frames.size() ); - for( uint32_t i=0; i( std::thread::hardware_concurrency() - 2, 2 ); + auto td = std::make_unique( jobs ); + auto data = std::make_unique( jobs ); + + for( uint64_t i=0; iframeRef = i; + s_loadProgress.subProgress.store( i, std::memory_order_relaxed ); + auto fi = m_slab.Alloc(); + f.Read2( fi->w, fi->h ); + f.Read( fi->flip ); + const auto sz = size_t( fi->w * fi->h / 2 ); + + int idx = -1; + for(;;) + { + for( int j=0; jcsz ); + memcpy( tmp, data[j].outbuf, data[j].fi->csz ); + data[j].fi->ptr = tmp; + } + idx = j; + break; + } + } + if( idx >= 0 ) break; + std::this_thread::yield(); + } + + if( data[idx].bufsz < sz ) + { + data[idx].bufsz = sz; + delete[] data[idx].buf; + data[idx].buf = new char[sz]; + } + f.Read( data[idx].buf, sz ); + data[idx].fi = fi; + + data[idx].state.store( JobData::InProgress, std::memory_order_release ); + td->Queue( [this, &data, idx, fi] { + PackFrameImage( data[idx].outbuf, data[idx].outsz, data[idx].buf, fi->w, fi->h, fi->csz ); + data[idx].state.store( JobData::DataReady, std::memory_order_release ); + } ); + + m_data.frameImage[i] = fi; + } + td->Sync(); + td.reset(); + for( size_t i=0; icsz ); + memcpy( tmp, data[i].outbuf, data[i].fi->csz ); + data[i].fi->ptr = tmp; + } + delete[] data[i].buf; + delete[] data[i].outbuf; + } + + const auto& frames = GetFramesBase()->frames; + const auto fsz = uint32_t( frames.size() ); + for( uint32_t i=0; iframeRef = i; + } } } }