60 const void* PixelData,
64 FReadSurfaceDataFlags Flags,
65 TArrayView<FColor> Out)
67 SourcePitch *= GPixelFormats[Format].BlockBytes;
68 auto OutPixelCount = Extent.X * Extent.Y;
75 ConvertRawR16DataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData());
78 ConvertRawR8G8B8A8DataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData());
81 ConvertRawB8G8R8A8DataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData());
84 ConvertRawR10G10B10A2DataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData());
87 case PF_R16G16B16A16_UNORM:
88 case PF_R16G16B16A16_SNORM:
89 ConvertRawR16G16B16A16FDataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData(), Flags.GetLinearToGamma());
91 case PF_FloatR11G11B10:
92 ConvertRawR11G11B10DataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData(), Flags.GetLinearToGamma());
94 case PF_A32B32G32R32F:
95 ConvertRawR32G32B32A32DataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData(), Flags.GetLinearToGamma());
98 ConvertRawR16G16B16A16DataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData());
101 ConvertRawR16G16DataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData());
103 case PF_DepthStencil:
104 ConvertRawD32S8DataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData(), Flags);
107 ConvertRawR24G8DataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData(), Flags);
110 for (uint32 Y = 0; Y < (uint32)Extent.Y; Y++)
112 auto SrcPtr = (
float*)((uint8*)PixelData + Y * SourcePitch);
113 auto DestPtr = Out.GetData() + Y * Extent.X;
114 for (uint32 X = 0; X < (uint32)Extent.X; X++)
116 *DestPtr = FLinearColor(SrcPtr[0], 0.f, 0.f, 1.f).QuantizeRound();
122 case PF_R16G16B16A16_UINT:
123 case PF_R16G16B16A16_SINT:
124 ConvertRawR16G16B16A16DataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData());
127 ConvertRawR8DataToFColor(Extent.X, Extent.Y, (uint8*)PixelData, SourcePitch, Out.GetData());
130 UE_LOG(LogCarla, Warning, TEXT(
"Unsupported format %llu"), (
unsigned long long)Format);
195 TUniquePtr<TImagePixelData<FColor>> Data,
196 const FStringView& Path)
198 auto& HighResScreenshotConfig = GetHighResScreenshotConfig();
199 auto ImageTask = MakeUnique<FImageWriteTask>();
200 ImageTask->PixelData = MoveTemp(Data);
201 ImageTask->Filename = Path;
202 ImageTask->Format = EImageFormat::PNG;
203 ImageTask->CompressionQuality = (int32)EImageCompressionQuality::Default;
204 ImageTask->bOverwriteFile =
true;
205 ImageTask->PixelPreProcessors.Add(TAsyncAlphaWrite<FColor>(255));
206 return HighResScreenshotConfig.ImageWriteQueue->Enqueue(MoveTemp(ImageTask));
306 ENamedThreads::AnyBackgroundThreadNormalTask, [
307 Self = std::move(Self)]()
mutable
314 while (!Self.Readback->IsReady())
316 std::this_thread::sleep_for(std::chrono::microseconds(200));
317 if (++Spins > 25000u)
319 if (Self.Pool && Self.SlotIndex != INDEX_NONE)
321 Self.Pool->Release(Self.SlotIndex);
322 Self.SlotIndex = INDEX_NONE;
333 ENQUEUE_RENDER_COMMAND(RtlReadbackDeliver)(
334 [Self = MoveTemp(Self)](FRHICommandListImmediate&)
mutable
353 ENQUEUE_RENDER_COMMAND(FlushBatchedReadbacksCmd)(
354 [](FRHICommandListImmediate& CmdList)
367 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"FlushBatchedReadbacks Sync");
368 static thread_local auto RenderQueryPool =
369 RHICreateRenderQueryPool(RQT_AbsoluteTime);
370 auto Query = RenderQueryPool->AllocateQuery();
371 CmdList.EndRenderQuery(Query.GetQuery());
372 CmdList.ImmediateFlush(EImmediateFlushType::FlushRHIThread);
374 RHIGetRenderQueryResult(Query.GetQuery(), DeltaTime,
true);
375 Query.ReleaseQuery();
381 struct FMappedReadback
383 void* Data =
nullptr;
385 int32 BufferHeight = 0;
387 TArray<FMappedReadback> Mapped;
388 Mapped.SetNum(Batch.Num());
389 for (int32 Index = 0; Index < Batch.Num(); ++Index)
391 Mapped[Index].Data = Batch[Index].Readback->Lock(
392 Mapped[Index].RowPitch, &Mapped[Index].BufferHeight);
395 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"FlushBatchedReadbacks Deliver");
396 ParallelFor(Batch.Num(), [&](int32 Index)
398 if (Mapped[Index].Data != nullptr)
400 Batch[Index].Callback(
402 Mapped[Index].RowPitch,
403 Mapped[Index].BufferHeight,
409 for (int32 Index = 0; Index < Batch.Num(); ++Index)
411 if (Mapped[Index].Data !=
nullptr)
412 Batch[Index].Readback->Unlock();
413 if (Batch[Index].Pool && Batch[Index].SlotIndex != INDEX_NONE)
414 Batch[Index].Pool->Release(Batch[Index].SlotIndex);