96 lines
2.8 KiB
C++
96 lines
2.8 KiB
C++
#pragma once
|
|
|
|
#include "RenderCadenceClock.h"
|
|
#include "../runtime/RuntimeLayerModel.h"
|
|
#include "../runtime/RuntimeShaderArtifact.h"
|
|
#include "runtime/RuntimeRenderScene.h"
|
|
|
|
#include <atomic>
|
|
#include <condition_variable>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <mutex>
|
|
#include <string>
|
|
#include <thread>
|
|
|
|
class SystemFrameExchange;
|
|
class InputFrameMailbox;
|
|
|
|
class RenderThread
|
|
{
|
|
public:
|
|
struct Config
|
|
{
|
|
unsigned width = 1920;
|
|
unsigned height = 1080;
|
|
double frameDurationMilliseconds = 1000.0 / 59.94;
|
|
std::size_t pboDepth = 6;
|
|
};
|
|
|
|
struct Metrics
|
|
{
|
|
uint64_t renderedFrames = 0;
|
|
uint64_t completedReadbacks = 0;
|
|
uint64_t acquireMisses = 0;
|
|
uint64_t pboQueueMisses = 0;
|
|
uint64_t clockOverruns = 0;
|
|
uint64_t skippedFrames = 0;
|
|
uint64_t shaderBuildsCommitted = 0;
|
|
uint64_t shaderBuildFailures = 0;
|
|
};
|
|
|
|
RenderThread(SystemFrameExchange& frameExchange, Config config);
|
|
RenderThread(SystemFrameExchange& frameExchange, InputFrameMailbox* inputMailbox, Config config);
|
|
RenderThread(const RenderThread&) = delete;
|
|
RenderThread& operator=(const RenderThread&) = delete;
|
|
~RenderThread();
|
|
|
|
bool Start(std::string& error);
|
|
void Stop();
|
|
void SubmitRuntimeShaderArtifact(const RuntimeShaderArtifact& artifact);
|
|
void SubmitRuntimeRenderLayers(const std::vector<RenderCadenceCompositor::RuntimeRenderLayerModel>& layers);
|
|
|
|
Metrics GetMetrics() const;
|
|
bool IsRunning() const { return mRunning.load(std::memory_order_acquire); }
|
|
|
|
private:
|
|
void ThreadMain();
|
|
void SignalStarted();
|
|
void SignalStartupFailure(const std::string& error);
|
|
void CountRendered();
|
|
void CountCompleted();
|
|
void CountAcquireMiss();
|
|
void TryCommitReadyRuntimeShader(RuntimeRenderScene& runtimeRenderScene);
|
|
bool TryTakePendingRuntimeShaderArtifact(RuntimeShaderArtifact& artifact);
|
|
bool TryTakePendingRenderLayers(std::vector<RenderCadenceCompositor::RuntimeRenderLayerModel>& layers);
|
|
|
|
SystemFrameExchange& mFrameExchange;
|
|
InputFrameMailbox* mInputMailbox = nullptr;
|
|
Config mConfig;
|
|
std::thread mThread;
|
|
std::atomic<bool> mStopping{ false };
|
|
std::atomic<bool> mRunning{ false };
|
|
|
|
mutable std::mutex mStartupMutex;
|
|
std::condition_variable mStartupCondition;
|
|
bool mStarted = false;
|
|
std::string mStartupError;
|
|
|
|
std::atomic<uint64_t> mRenderedFrames{ 0 };
|
|
std::atomic<uint64_t> mCompletedReadbacks{ 0 };
|
|
std::atomic<uint64_t> mAcquireMisses{ 0 };
|
|
std::atomic<uint64_t> mPboQueueMisses{ 0 };
|
|
std::atomic<uint64_t> mClockOverruns{ 0 };
|
|
std::atomic<uint64_t> mSkippedFrames{ 0 };
|
|
std::atomic<uint64_t> mShaderBuildsCommitted{ 0 };
|
|
std::atomic<uint64_t> mShaderBuildFailures{ 0 };
|
|
|
|
std::mutex mShaderArtifactMutex;
|
|
bool mHasPendingShaderArtifact = false;
|
|
RuntimeShaderArtifact mPendingShaderArtifact;
|
|
|
|
std::mutex mRenderLayersMutex;
|
|
bool mHasPendingRenderLayers = false;
|
|
std::vector<RenderCadenceCompositor::RuntimeRenderLayerModel> mPendingRenderLayers;
|
|
};
|