// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include #include "FxMat/RenderMaterial.h" #include "Device/Device.h" #include "JobCommon.h" class MixUpdateCycle; class Job; typedef std::unique_ptr JobUPtr; typedef std::shared_ptr JobPtr; typedef std::weak_ptr JobPtrW; typedef cti::continuable AsyncBool; typedef std::shared_ptr JobBatchPtr; typedef TUniqueFunction OnAllJobsDoneCallback; typedef std::vector OnAllJobsDoneCallbackVec; typedef GenericTaskPriorityQueue, DeviceNativeTask_CompareStrong> JobPriorityQueue; struct FInvalidationDetails; DECLARE_LOG_CATEGORY_EXTERN(LogBatch, Log, All); ////////////////////////////////////////////////////////////////////////// /// JobBatch: A series of jobs put together that need to execute at the /// same time ////////////////////////////////////////////////////////////////////////// class TEXTUREGRAPHENGINE_API JobBatch { public: static uint64 GBatchId; /// For easier debugging protected: mutable FCriticalSection Mutex; /// Mutex for the JobObj queue std::atomic bIsLocked = false; /// Whether the queue is now locked from any further changes std::vector AllJobs; /// All the jobs within the system JobPriorityQueue Queue; /// The JobObj queue JobPtr CurrJob; /// The current JobObj ... we keep it to prevent it from going out of scope JobPtr PrevJob; /// The previous JobObj that we ran. Mostly for debugging purposes double StartTime = 0; /// Time when the batch was started double EndTime = 0; /// Time when the batch has ended uint64 FrameId = 0; /// What is the frame id for this size_t BatchId = 0; /// What is the index of this batch std::shared_ptr Cycle; /// Scene update cycle information int32 ReplayCount = 0; /// Counting the number of debug replay of this batch bool bCaptureRenderDoc = false; /// flag to record a RenderDoc capture for debugging the batch bool bNoCache = false; /// Whether we should ignore the cache bool bIsIdle = false; /// Is the batch generated by an idle service or not bool bIsFinished = false; /// Whether the batch has been finished or not bool bIsAsync = true; /// Whether the job batch is asynchronous or not AsyncJobResultPtr BeginQueue_Native(JobPriorityQueue& InQueue); void EndBatch(); friend class Job; void OnJobDone(Job* JobObj, int64 JobId); /// Once a JobObj is TRULY done then it reports to the batch, void AddNativeJob_Now(JobPtr JobObj, bool AddToAllJobs); std::atomic NumJobsRunning = 0; /// A count down of the jobs still running, decremented by OnJobDone OnAllJobsDoneCallbackVec OnAllJobsDoneCallbacks; /// If the call back has been assigned, that 's what will get called when all the jobs are done. std::vector JobsFinished; /// Jobs that have been finished void PrintJobTimings() const; public: explicit JobBatch(const FInvalidationDetails& Details); virtual ~JobBatch(); virtual AsyncJobResultPtr Exec(OnAllJobsDoneCallback Callback = nullptr); virtual JobPtrW AddJob(JobUPtr JobObj); virtual void RemoveJob(JobPtrW JobObj); bool IsLocked() const; void ResetForReplay(int32 JobId = -1); /// For debug purpose we can reset the state of a batch for a replay /// A JobObj index can be specified to only reset that JobObj during replay void SetCaptureRenderDoc(bool CaptureRenderDoc = true); void DebugDumpUnfinishedJobs(); void Terminate(); void OnDone(OnAllJobsDoneCallback Callback); ////////////////////////////////////////////////////////////////////////// /// Inline functions ////////////////////////////////////////////////////////////////////////// FORCEINLINE bool IsCaptureRenderDoc() const { return bCaptureRenderDoc; } FORCEINLINE void SetNoCache(bool bInNoCache) { bNoCache = bInNoCache; } FORCEINLINE bool IsNoCache() const { return bNoCache; } FORCEINLINE std::shared_ptr GetCycle() const { return Cycle; } FORCEINLINE size_t NumJobs() const { return AllJobs.size(); } FORCEINLINE uint64 GetFrameId() const { return FrameId; } FORCEINLINE uint64 GetBatchId() const { return BatchId; } FORCEINLINE JobPtrW GetJobAt(uint64_t jobNum) const { return (AllJobs.size() > jobNum ? AllJobs[jobNum] : JobPtrW()); } FORCEINLINE double GetStartTime() const { return StartTime; } FORCEINLINE double GetEndTime() const { return EndTime; } FORCEINLINE int32 GetReplayCount() const { return ReplayCount; } /// For debug purpose, report the replay number FORCEINLINE uint32 GetNumJobsRunning() const { return NumJobsRunning; } FORCEINLINE bool WasGeneratedFromIdleService() const { return bIsIdle; } FORCEINLINE bool& IsIdle() { return bIsIdle; } FORCEINLINE bool IsFinished() const { return bIsFinished; } FORCEINLINE void SetAsync(bool bIsAsyncIn) { bIsAsync = bIsAsyncIn; } FORCEINLINE bool IsAsync() const { return bIsAsync; } ////////////////////////////////////////////////////////////////////////// /// Static functions ////////////////////////////////////////////////////////////////////////// static FORCEINLINE uint64 CurrentBatchId() { return GBatchId; } static std::shared_ptr Create(const FInvalidationDetails& details); };