virtual void WaitAsynchronousCompletion(uint32 Handle) override { STAT(double ThisTime = 0); { SCOPE_SECONDS_COUNTER(ThisTime); FAsyncTask<FBuildAsyncWorker>* AsyncTask = NULL; { FScopeLock ScopeLock(&SynchronizationObject); AsyncTask = PendingTasks.FindRef(Handle); } check(AsyncTask); AsyncTask->EnsureCompletion(); } INC_FLOAT_STAT_BY(STAT_DDC_ASyncWaitTime,(float)ThisTime); }
void Serialize(int64 DesiredPosition, void* V, int64 Length) { const int32 CompressionBlockSize = PakEntry.CompressionBlockSize; uint32 CompressionBlockIndex = DesiredPosition / CompressionBlockSize; uint8* WorkingBuffers[2]; int64 DirectCopyStart = DesiredPosition % PakEntry.CompressionBlockSize; FAsyncTask<FPakUncompressTask> UncompressTask; FCompressionScratchBuffers& ScratchSpace = FCompressionScratchBuffers::Get(); bool bStartedUncompress = false; int64 WorkingBufferRequiredSize = FCompression::CompressMemoryBound((ECompressionFlags)PakEntry.CompressionMethod,CompressionBlockSize); WorkingBufferRequiredSize = EncryptionPolicy::AlignReadRequest(WorkingBufferRequiredSize); ScratchSpace.EnsureBufferSpace(CompressionBlockSize, WorkingBufferRequiredSize*2); WorkingBuffers[0] = ScratchSpace.ScratchBuffer; WorkingBuffers[1] = ScratchSpace.ScratchBuffer + WorkingBufferRequiredSize; while (Length > 0) { const FPakCompressedBlock& Block = PakEntry.CompressionBlocks[CompressionBlockIndex]; int64 Pos = CompressionBlockIndex * CompressionBlockSize; int64 CompressedBlockSize = Block.CompressedEnd-Block.CompressedStart; int64 UncompressedBlockSize = FMath::Min<int64>(PakEntry.UncompressedSize-Pos, PakEntry.CompressionBlockSize); int64 ReadSize = EncryptionPolicy::AlignReadRequest(CompressedBlockSize); int64 WriteSize = FMath::Min<int64>(UncompressedBlockSize - DirectCopyStart, Length); PakReader->Seek(Block.CompressedStart); PakReader->Serialize(WorkingBuffers[CompressionBlockIndex & 1],ReadSize); if (bStartedUncompress) { UncompressTask.EnsureCompletion(); bStartedUncompress = false; } FPakUncompressTask& TaskDetails = UncompressTask.GetTask(); if (DirectCopyStart == 0 && Length >= CompressionBlockSize) { // Block can be decompressed directly into output buffer TaskDetails.Flags = (ECompressionFlags)PakEntry.CompressionMethod; TaskDetails.UncompressedBuffer = (uint8*)V; TaskDetails.UncompressedSize = UncompressedBlockSize; TaskDetails.CompressedBuffer = WorkingBuffers[CompressionBlockIndex & 1]; TaskDetails.CompressedSize = CompressedBlockSize; TaskDetails.CopyOut = nullptr; } else { // Block needs to be copied from a working buffer TaskDetails.Flags = (ECompressionFlags)PakEntry.CompressionMethod; TaskDetails.UncompressedBuffer = (uint8*)ScratchSpace.TempBuffer; TaskDetails.UncompressedSize = UncompressedBlockSize; TaskDetails.CompressedBuffer = WorkingBuffers[CompressionBlockIndex & 1]; TaskDetails.CompressedSize = CompressedBlockSize; TaskDetails.CopyOut = V; TaskDetails.CopyOffset = DirectCopyStart; TaskDetails.CopyLength = WriteSize; } if (Length == WriteSize) { UncompressTask.StartSynchronousTask(); } else { UncompressTask.StartBackgroundTask(); } bStartedUncompress = true; V = (void*)((uint8*)V + WriteSize); Length -= WriteSize; DirectCopyStart = 0; ++CompressionBlockIndex; } if(bStartedUncompress) { UncompressTask.EnsureCompletion(); } }