10 #include "Engine/TextureRenderTarget2D.h" 11 #include "Async/Async.h" 12 #include "HighResScreenshot.h" 13 #include "Runtime/ImageWriteQueue/Public/ImageWriteQueue.h" 20 const UTextureRenderTarget2D &RenderTarget,
22 FRHICommandListImmediate &RHICmdList,
25 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"WritePixelsToBuffer");
26 check(IsInRenderingThread());
29 static_cast<const FTextureRenderTarget2DResource *
>(RenderTarget.Resource);
30 FTexture2DRHIRef Texture = RenderResource->GetRenderTargetTexture();
36 auto BackBufferReadback = std::make_unique<FRHIGPUTextureReadback>(TEXT(
"CameraBufferReadback"));
37 FIntPoint BackBufferSize = Texture->GetSizeXY();
38 EPixelFormat BackBufferPixelFormat = Texture->GetFormat();
40 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"EnqueueCopy");
41 BackBufferReadback->EnqueueCopy(RHICmdList,
43 FResolveRect(0, 0, BackBufferSize.X, BackBufferSize.Y));
48 FRenderQueryRHIRef Query = RHICreateRenderQuery(RQT_AbsoluteTime);
49 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"create query");
50 RHICmdList.EndRenderQuery(Query);
51 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"Flush");
52 RHICmdList.ImmediateFlush(EImmediateFlushType::FlushRHIThread);
53 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"query result");
54 uint64 OldAbsTime = 0;
55 RHICmdList.GetRenderQueryResult(Query, OldAbsTime,
true);
58 AsyncTask(ENamedThreads::HighTaskPriority, [=, Readback=std::move(BackBufferReadback)]()
mutable {
60 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"Wait GPU transfer");
61 while (!Readback->IsReady())
63 std::this_thread::yield();
68 TRACE_CPUPROFILER_EVENT_SCOPE_STR(
"Readback data");
69 FPixelFormatInfo PixelFormat = GPixelFormats[BackBufferPixelFormat];
70 uint32 ExpectedRowBytes = BackBufferSize.X * PixelFormat.BlockBytes;
71 int32 Size = (BackBufferSize.Y * (PixelFormat.BlockBytes * BackBufferSize.X));
72 void* LockedData = Readback->Lock(Size);
75 FuncForSending(LockedData, Size, Offset, ExpectedRowBytes);
84 UTextureRenderTarget2D &RenderTarget,
85 TArray<FColor> &BitMap)
87 check(IsInGameThread());
88 FTextureRenderTargetResource *RTResource =
89 RenderTarget.GameThread_GetRenderTargetResource();
90 if (RTResource ==
nullptr)
92 UE_LOG(LogCarla, Error, TEXT(
"FPixelReader: UTextureRenderTarget2D missing render target"));
95 FReadSurfaceDataFlags ReadPixelFlags(RCM_UNorm);
96 ReadPixelFlags.SetLinearToGamma(
true);
97 return RTResource->ReadPixels(BitMap, ReadPixelFlags);
101 UTextureRenderTarget2D &RenderTarget)
103 const FIntPoint DestSize(RenderTarget.GetSurfaceWidth(), RenderTarget.GetSurfaceHeight());
104 TUniquePtr<TImagePixelData<FColor>> PixelData = MakeUnique<TImagePixelData<FColor>>(DestSize);
105 TArray<FColor> Pixels(PixelData->Pixels.GetData(), PixelData->Pixels.Num());
110 PixelData->Pixels = Pixels;
115 UTextureRenderTarget2D &RenderTarget,
116 const FString &FilePath)
122 TUniquePtr<TImagePixelData<FColor>> PixelData,
123 const FString &FilePath)
125 TUniquePtr<FImageWriteTask> ImageTask = MakeUnique<FImageWriteTask>();
126 ImageTask->PixelData = MoveTemp(PixelData);
127 ImageTask->Filename = FilePath;
128 ImageTask->Format = EImageFormat::PNG;
129 ImageTask->CompressionQuality = (int32) EImageCompressionQuality::Default;
130 ImageTask->bOverwriteFile =
true;
131 ImageTask->PixelPreProcessors.Add(TAsyncAlphaWrite<FColor>(255));
133 FHighResScreenshotConfig &HighResScreenshotConfig = GetHighResScreenshotConfig();
134 return HighResScreenshotConfig.ImageWriteQueue->Enqueue(MoveTemp(ImageTask));
static TUniquePtr< TImagePixelData< FColor > > DumpPixels(UTextureRenderTarget2D &RenderTarget)
Dump the pixels in RenderTarget.
static bool WritePixelsToArray(UTextureRenderTarget2D &RenderTarget, TArray< FColor > &BitMap)
Copy the pixels in RenderTarget into BitMap.
static void WritePixelsToBuffer(const UTextureRenderTarget2D &RenderTarget, uint32 Offset, FRHICommandListImmediate &InRHICmdList, FPixelReader::Payload FuncForSending)
Copy the pixels in RenderTarget into Buffer.
std::function< void(void *, uint32, uint32, uint32)> Payload
static TFuture< bool > SavePixelsToDisk(UTextureRenderTarget2D &RenderTarget, const FString &FilePath)
Asynchronously save the pixels in RenderTarget to disk.