Pacing problems
This commit is contained in:
@@ -53,12 +53,17 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
OpenGLComposite::OpenGLComposite(HWND hWnd, HDC hDC, HGLRC hRC) :
|
OpenGLComposite::OpenGLComposite(HWND hWnd, HDC hDC, HGLRC hRC) :
|
||||||
hGLWnd(hWnd), hGLDC(hDC), hGLRC(hRC),
|
hGLWnd(hWnd), hGLDC(hDC), hGLRC(hRC),
|
||||||
mDeckLink(std::make_unique<DeckLinkSession>()),
|
mDeckLink(std::make_unique<DeckLinkSession>()),
|
||||||
mRenderer(std::make_unique<OpenGLRenderer>())
|
mRenderer(std::make_unique<OpenGLRenderer>()),
|
||||||
|
mRuntimePollRunning(false),
|
||||||
|
mRuntimeRegistryChanged(false),
|
||||||
|
mRuntimeReloadRequested(false),
|
||||||
|
mRuntimePollFailed(false)
|
||||||
{
|
{
|
||||||
InitializeCriticalSection(&pMutex);
|
InitializeCriticalSection(&pMutex);
|
||||||
mRuntimeHost = std::make_unique<RuntimeHost>();
|
mRuntimeHost = std::make_unique<RuntimeHost>();
|
||||||
@@ -79,6 +84,7 @@ OpenGLComposite::OpenGLComposite(HWND hWnd, HDC hDC, HGLRC hRC) :
|
|||||||
|
|
||||||
OpenGLComposite::~OpenGLComposite()
|
OpenGLComposite::~OpenGLComposite()
|
||||||
{
|
{
|
||||||
|
StopRuntimePolling();
|
||||||
mDeckLink->ReleaseResources();
|
mDeckLink->ReleaseResources();
|
||||||
mRenderer->DestroyResources();
|
mRenderer->DestroyResources();
|
||||||
if (mOscServer)
|
if (mOscServer)
|
||||||
@@ -284,6 +290,7 @@ bool OpenGLComposite::InitOpenGLState()
|
|||||||
}
|
}
|
||||||
|
|
||||||
broadcastRuntimeState();
|
broadcastRuntimeState();
|
||||||
|
StartRuntimePolling();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -305,6 +312,8 @@ bool OpenGLComposite::Start()
|
|||||||
|
|
||||||
bool OpenGLComposite::Stop()
|
bool OpenGLComposite::Stop()
|
||||||
{
|
{
|
||||||
|
StopRuntimePolling();
|
||||||
|
|
||||||
if (mOscServer)
|
if (mOscServer)
|
||||||
mOscServer->Stop();
|
mOscServer->Stop();
|
||||||
|
|
||||||
@@ -351,10 +360,17 @@ bool OpenGLComposite::ReloadShader()
|
|||||||
|
|
||||||
void OpenGLComposite::renderEffect()
|
void OpenGLComposite::renderEffect()
|
||||||
{
|
{
|
||||||
PollRuntimeChanges();
|
ProcessRuntimePollResults();
|
||||||
|
|
||||||
const bool hasInputSource = mDeckLink->HasInputSource();
|
const bool hasInputSource = mDeckLink->HasInputSource();
|
||||||
const std::vector<RuntimeRenderState> layerStates = mRuntimeHost ? mRuntimeHost->GetLayerRenderStates(mDeckLink->InputFrameWidth(), mDeckLink->InputFrameHeight()) : std::vector<RuntimeRenderState>();
|
std::vector<RuntimeRenderState> layerStates;
|
||||||
|
if (mRuntimeHost)
|
||||||
|
{
|
||||||
|
if (mRuntimeHost->TryGetLayerRenderStates(mDeckLink->InputFrameWidth(), mDeckLink->InputFrameHeight(), layerStates))
|
||||||
|
mCachedLayerRenderStates = layerStates;
|
||||||
|
else
|
||||||
|
layerStates = mCachedLayerRenderStates;
|
||||||
|
}
|
||||||
const unsigned historyCap = mRuntimeHost ? mRuntimeHost->GetMaxTemporalHistoryFrames() : 0;
|
const unsigned historyCap = mRuntimeHost ? mRuntimeHost->GetMaxTemporalHistoryFrames() : 0;
|
||||||
mRenderPass->Render(
|
mRenderPass->Render(
|
||||||
hasInputSource,
|
hasInputSource,
|
||||||
@@ -370,25 +386,72 @@ void OpenGLComposite::renderEffect()
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLComposite::PollRuntimeChanges()
|
void OpenGLComposite::StartRuntimePolling()
|
||||||
|
{
|
||||||
|
if (!mRuntimeHost || mRuntimePollRunning.exchange(true))
|
||||||
|
return;
|
||||||
|
|
||||||
|
mRuntimePollThread = std::thread([this]() { RuntimePollLoop(); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLComposite::StopRuntimePolling()
|
||||||
|
{
|
||||||
|
if (!mRuntimePollRunning.exchange(false))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (mRuntimePollThread.joinable())
|
||||||
|
mRuntimePollThread.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLComposite::RuntimePollLoop()
|
||||||
|
{
|
||||||
|
while (mRuntimePollRunning)
|
||||||
|
{
|
||||||
|
bool registryChanged = false;
|
||||||
|
bool reloadRequested = false;
|
||||||
|
std::string runtimeError;
|
||||||
|
if (!mRuntimeHost->PollFileChanges(registryChanged, reloadRequested, runtimeError))
|
||||||
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mRuntimePollErrorMutex);
|
||||||
|
mRuntimePollError = runtimeError;
|
||||||
|
}
|
||||||
|
mRuntimePollFailed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (registryChanged)
|
||||||
|
mRuntimeRegistryChanged = true;
|
||||||
|
if (reloadRequested)
|
||||||
|
mRuntimeReloadRequested = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 25 && mRuntimePollRunning; ++i)
|
||||||
|
Sleep(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OpenGLComposite::ProcessRuntimePollResults()
|
||||||
{
|
{
|
||||||
if (!mRuntimeHost)
|
if (!mRuntimeHost)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
bool registryChanged = false;
|
if (mRuntimePollFailed.exchange(false))
|
||||||
bool reloadRequested = false;
|
|
||||||
std::string runtimeError;
|
|
||||||
if (!mRuntimeHost->PollFileChanges(registryChanged, reloadRequested, runtimeError))
|
|
||||||
{
|
{
|
||||||
|
std::string runtimeError;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mRuntimePollErrorMutex);
|
||||||
|
runtimeError = mRuntimePollError;
|
||||||
|
}
|
||||||
mRuntimeHost->SetCompileStatus(false, runtimeError);
|
mRuntimeHost->SetCompileStatus(false, runtimeError);
|
||||||
broadcastRuntimeState();
|
broadcastRuntimeState();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (registryChanged)
|
if (mRuntimeRegistryChanged.exchange(false))
|
||||||
broadcastRuntimeState();
|
broadcastRuntimeState();
|
||||||
|
|
||||||
if (!reloadRequested)
|
if (!mRuntimeReloadRequested.exchange(false))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
char compilerErrorMessage[1024] = {};
|
char compilerErrorMessage[1024] = {};
|
||||||
|
|||||||
@@ -60,6 +60,9 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
@@ -119,10 +122,21 @@ private:
|
|||||||
std::unique_ptr<OpenGLShaderPrograms> mShaderPrograms;
|
std::unique_ptr<OpenGLShaderPrograms> mShaderPrograms;
|
||||||
std::unique_ptr<ControlServer> mControlServer;
|
std::unique_ptr<ControlServer> mControlServer;
|
||||||
std::unique_ptr<OscServer> mOscServer;
|
std::unique_ptr<OscServer> mOscServer;
|
||||||
|
std::thread mRuntimePollThread;
|
||||||
|
std::atomic<bool> mRuntimePollRunning;
|
||||||
|
std::atomic<bool> mRuntimeRegistryChanged;
|
||||||
|
std::atomic<bool> mRuntimeReloadRequested;
|
||||||
|
std::atomic<bool> mRuntimePollFailed;
|
||||||
|
std::mutex mRuntimePollErrorMutex;
|
||||||
|
std::string mRuntimePollError;
|
||||||
|
std::vector<RuntimeRenderState> mCachedLayerRenderStates;
|
||||||
|
|
||||||
bool InitOpenGLState();
|
bool InitOpenGLState();
|
||||||
void renderEffect();
|
void renderEffect();
|
||||||
bool PollRuntimeChanges();
|
void StartRuntimePolling();
|
||||||
|
void StopRuntimePolling();
|
||||||
|
void RuntimePollLoop();
|
||||||
|
bool ProcessRuntimePollResults();
|
||||||
void broadcastRuntimeState();
|
void broadcastRuntimeState();
|
||||||
void resetTemporalHistoryState();
|
void resetTemporalHistoryState();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ void OpenGLDeckLinkBridge::RecordFramePacing(BMDOutputFrameCompletionResult comp
|
|||||||
else if (completionResult == bmdOutputFrameFlushed)
|
else if (completionResult == bmdOutputFrameFlushed)
|
||||||
++mFlushedFrameCount;
|
++mFlushedFrameCount;
|
||||||
|
|
||||||
mRuntimeHost.SetFramePacingStats(
|
mRuntimeHost.TrySetFramePacingStats(
|
||||||
mCompletionIntervalMilliseconds,
|
mCompletionIntervalMilliseconds,
|
||||||
mSmoothedCompletionIntervalMilliseconds,
|
mSmoothedCompletionIntervalMilliseconds,
|
||||||
mMaxCompletionIntervalMilliseconds,
|
mMaxCompletionIntervalMilliseconds,
|
||||||
@@ -64,7 +64,7 @@ void OpenGLDeckLinkBridge::RecordFramePacing(BMDOutputFrameCompletionResult comp
|
|||||||
void OpenGLDeckLinkBridge::VideoFrameArrived(IDeckLinkVideoInputFrame* inputFrame, bool hasNoInputSource)
|
void OpenGLDeckLinkBridge::VideoFrameArrived(IDeckLinkVideoInputFrame* inputFrame, bool hasNoInputSource)
|
||||||
{
|
{
|
||||||
mDeckLink.SetInputSourceMissing(hasNoInputSource);
|
mDeckLink.SetInputSourceMissing(hasNoInputSource);
|
||||||
mRuntimeHost.SetSignalStatus(!hasNoInputSource, mDeckLink.InputFrameWidth(), mDeckLink.InputFrameHeight(), mDeckLink.InputDisplayModeName());
|
mRuntimeHost.TrySetSignalStatus(!hasNoInputSource, mDeckLink.InputFrameWidth(), mDeckLink.InputFrameHeight(), mDeckLink.InputDisplayModeName());
|
||||||
|
|
||||||
if (!mDeckLink.HasInputSource())
|
if (!mDeckLink.HasInputSource())
|
||||||
return; // don't transfer texture when there's no input
|
return; // don't transfer texture when there's no input
|
||||||
@@ -147,8 +147,8 @@ void OpenGLDeckLinkBridge::PlayoutFrameCompleted(IDeckLinkVideoFrame* completedF
|
|||||||
const auto renderEndTime = std::chrono::steady_clock::now();
|
const auto renderEndTime = std::chrono::steady_clock::now();
|
||||||
const double frameBudgetMilliseconds = mDeckLink.FrameBudgetMilliseconds();
|
const double frameBudgetMilliseconds = mDeckLink.FrameBudgetMilliseconds();
|
||||||
const double renderMilliseconds = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(renderEndTime - renderStartTime).count();
|
const double renderMilliseconds = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(renderEndTime - renderStartTime).count();
|
||||||
mRuntimeHost.SetPerformanceStats(frameBudgetMilliseconds, renderMilliseconds);
|
mRuntimeHost.TrySetPerformanceStats(frameBudgetMilliseconds, renderMilliseconds);
|
||||||
mRuntimeHost.AdvanceFrame();
|
mRuntimeHost.TryAdvanceFrame();
|
||||||
|
|
||||||
IDeckLinkVideoBuffer* outputVideoFrameBuffer;
|
IDeckLinkVideoBuffer* outputVideoFrameBuffer;
|
||||||
if (outputVideoFrame->QueryInterface(IID_IDeckLinkVideoBuffer, (void**)&outputVideoFrameBuffer) != S_OK)
|
if (outputVideoFrame->QueryInterface(IID_IDeckLinkVideoBuffer, (void**)&outputVideoFrameBuffer) != S_OK)
|
||||||
|
|||||||
@@ -1155,6 +1155,21 @@ void RuntimeHost::SetCompileStatus(bool succeeded, const std::string& message)
|
|||||||
void RuntimeHost::SetSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName)
|
void RuntimeHost::SetSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mMutex);
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
SetSignalStatusLocked(hasSignal, width, height, modeName);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RuntimeHost::TrySetSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mMutex, std::try_to_lock);
|
||||||
|
if (!lock.owns_lock())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SetSignalStatusLocked(hasSignal, width, height, modeName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuntimeHost::SetSignalStatusLocked(bool hasSignal, unsigned width, unsigned height, const std::string& modeName)
|
||||||
|
{
|
||||||
mHasSignal = hasSignal;
|
mHasSignal = hasSignal;
|
||||||
mSignalWidth = width;
|
mSignalWidth = width;
|
||||||
mSignalHeight = height;
|
mSignalHeight = height;
|
||||||
@@ -1177,6 +1192,21 @@ void RuntimeHost::SetDeckLinkOutputStatus(const std::string& modelName, bool sup
|
|||||||
void RuntimeHost::SetPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds)
|
void RuntimeHost::SetPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mMutex);
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
SetPerformanceStatsLocked(frameBudgetMilliseconds, renderMilliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RuntimeHost::TrySetPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mMutex, std::try_to_lock);
|
||||||
|
if (!lock.owns_lock())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SetPerformanceStatsLocked(frameBudgetMilliseconds, renderMilliseconds);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuntimeHost::SetPerformanceStatsLocked(double frameBudgetMilliseconds, double renderMilliseconds)
|
||||||
|
{
|
||||||
mFrameBudgetMilliseconds = std::max(frameBudgetMilliseconds, 0.0);
|
mFrameBudgetMilliseconds = std::max(frameBudgetMilliseconds, 0.0);
|
||||||
mRenderMilliseconds = std::max(renderMilliseconds, 0.0);
|
mRenderMilliseconds = std::max(renderMilliseconds, 0.0);
|
||||||
if (mSmoothedRenderMilliseconds <= 0.0)
|
if (mSmoothedRenderMilliseconds <= 0.0)
|
||||||
@@ -1189,6 +1219,25 @@ void RuntimeHost::SetFramePacingStats(double completionIntervalMilliseconds, dou
|
|||||||
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount)
|
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount)
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mMutex);
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
|
SetFramePacingStatsLocked(completionIntervalMilliseconds, smoothedCompletionIntervalMilliseconds,
|
||||||
|
maxCompletionIntervalMilliseconds, lateFrameCount, droppedFrameCount, flushedFrameCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RuntimeHost::TrySetFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
|
||||||
|
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount)
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mMutex, std::try_to_lock);
|
||||||
|
if (!lock.owns_lock())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
SetFramePacingStatsLocked(completionIntervalMilliseconds, smoothedCompletionIntervalMilliseconds,
|
||||||
|
maxCompletionIntervalMilliseconds, lateFrameCount, droppedFrameCount, flushedFrameCount);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuntimeHost::SetFramePacingStatsLocked(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
|
||||||
|
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount)
|
||||||
|
{
|
||||||
mCompletionIntervalMilliseconds = std::max(completionIntervalMilliseconds, 0.0);
|
mCompletionIntervalMilliseconds = std::max(completionIntervalMilliseconds, 0.0);
|
||||||
mSmoothedCompletionIntervalMilliseconds = std::max(smoothedCompletionIntervalMilliseconds, 0.0);
|
mSmoothedCompletionIntervalMilliseconds = std::max(smoothedCompletionIntervalMilliseconds, 0.0);
|
||||||
mMaxCompletionIntervalMilliseconds = std::max(maxCompletionIntervalMilliseconds, 0.0);
|
mMaxCompletionIntervalMilliseconds = std::max(maxCompletionIntervalMilliseconds, 0.0);
|
||||||
@@ -1203,6 +1252,16 @@ void RuntimeHost::AdvanceFrame()
|
|||||||
++mFrameCounter;
|
++mFrameCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RuntimeHost::TryAdvanceFrame()
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mMutex, std::try_to_lock);
|
||||||
|
if (!lock.owns_lock())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
++mFrameCounter;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool RuntimeHost::BuildLayerFragmentShaderSource(const std::string& layerId, std::string& fragmentShaderSource, std::string& error)
|
bool RuntimeHost::BuildLayerFragmentShaderSource(const std::string& layerId, std::string& fragmentShaderSource, std::string& error)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -1245,7 +1304,23 @@ std::vector<RuntimeRenderState> RuntimeHost::GetLayerRenderStates(unsigned outpu
|
|||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock(mMutex);
|
std::lock_guard<std::mutex> lock(mMutex);
|
||||||
std::vector<RuntimeRenderState> states;
|
std::vector<RuntimeRenderState> states;
|
||||||
|
BuildLayerRenderStatesLocked(outputWidth, outputHeight, states);
|
||||||
|
return states;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RuntimeHost::TryGetLayerRenderStates(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const
|
||||||
|
{
|
||||||
|
std::unique_lock<std::mutex> lock(mMutex, std::try_to_lock);
|
||||||
|
if (!lock.owns_lock())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
states.clear();
|
||||||
|
BuildLayerRenderStatesLocked(outputWidth, outputHeight, states);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RuntimeHost::BuildLayerRenderStatesLocked(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const
|
||||||
|
{
|
||||||
for (const LayerPersistentState& layer : mPersistentState.layers)
|
for (const LayerPersistentState& layer : mPersistentState.layers)
|
||||||
{
|
{
|
||||||
auto shaderIt = mPackagesById.find(layer.shaderId);
|
auto shaderIt = mPackagesById.find(layer.shaderId);
|
||||||
@@ -1282,8 +1357,6 @@ std::vector<RuntimeRenderState> RuntimeHost::GetLayerRenderStates(unsigned outpu
|
|||||||
|
|
||||||
states.push_back(state);
|
states.push_back(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
return states;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RuntimeHost::BuildStateJson() const
|
std::string RuntimeHost::BuildStateJson() const
|
||||||
|
|||||||
@@ -35,15 +35,21 @@ public:
|
|||||||
|
|
||||||
void SetCompileStatus(bool succeeded, const std::string& message);
|
void SetCompileStatus(bool succeeded, const std::string& message);
|
||||||
void SetSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName);
|
void SetSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName);
|
||||||
|
bool TrySetSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName);
|
||||||
void SetDeckLinkOutputStatus(const std::string& modelName, bool supportsInternalKeying, bool supportsExternalKeying,
|
void SetDeckLinkOutputStatus(const std::string& modelName, bool supportsInternalKeying, bool supportsExternalKeying,
|
||||||
bool keyerInterfaceAvailable, bool externalKeyingRequested, bool externalKeyingActive, const std::string& statusMessage);
|
bool keyerInterfaceAvailable, bool externalKeyingRequested, bool externalKeyingActive, const std::string& statusMessage);
|
||||||
void SetPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds);
|
void SetPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds);
|
||||||
|
bool TrySetPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds);
|
||||||
void SetFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
|
void SetFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
|
||||||
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount);
|
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount);
|
||||||
|
bool TrySetFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
|
||||||
|
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount);
|
||||||
void AdvanceFrame();
|
void AdvanceFrame();
|
||||||
|
bool TryAdvanceFrame();
|
||||||
|
|
||||||
bool BuildLayerFragmentShaderSource(const std::string& layerId, std::string& fragmentShaderSource, std::string& error);
|
bool BuildLayerFragmentShaderSource(const std::string& layerId, std::string& fragmentShaderSource, std::string& error);
|
||||||
std::vector<RuntimeRenderState> GetLayerRenderStates(unsigned outputWidth, unsigned outputHeight) const;
|
std::vector<RuntimeRenderState> GetLayerRenderStates(unsigned outputWidth, unsigned outputHeight) const;
|
||||||
|
bool TryGetLayerRenderStates(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const;
|
||||||
std::string BuildStateJson() const;
|
std::string BuildStateJson() const;
|
||||||
|
|
||||||
const std::filesystem::path& GetRepoRoot() const { return mRepoRoot; }
|
const std::filesystem::path& GetRepoRoot() const { return mRepoRoot; }
|
||||||
@@ -111,6 +117,7 @@ private:
|
|||||||
std::string ReadTextFile(const std::filesystem::path& path, std::string& error) const;
|
std::string ReadTextFile(const std::filesystem::path& path, std::string& error) const;
|
||||||
bool WriteTextFile(const std::filesystem::path& path, const std::string& contents, std::string& error) const;
|
bool WriteTextFile(const std::filesystem::path& path, const std::string& contents, std::string& error) const;
|
||||||
bool ResolvePaths(std::string& error);
|
bool ResolvePaths(std::string& error);
|
||||||
|
void BuildLayerRenderStatesLocked(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const;
|
||||||
JsonValue BuildStateValue() const;
|
JsonValue BuildStateValue() const;
|
||||||
JsonValue SerializeLayerStackLocked() const;
|
JsonValue SerializeLayerStackLocked() const;
|
||||||
bool DeserializeLayerStackLocked(const JsonValue& layersValue, std::vector<LayerPersistentState>& layers, std::string& error);
|
bool DeserializeLayerStackLocked(const JsonValue& layersValue, std::vector<LayerPersistentState>& layers, std::string& error);
|
||||||
@@ -122,6 +129,10 @@ private:
|
|||||||
LayerPersistentState* FindLayerById(const std::string& layerId);
|
LayerPersistentState* FindLayerById(const std::string& layerId);
|
||||||
const LayerPersistentState* FindLayerById(const std::string& layerId) const;
|
const LayerPersistentState* FindLayerById(const std::string& layerId) const;
|
||||||
std::string GenerateLayerId();
|
std::string GenerateLayerId();
|
||||||
|
void SetSignalStatusLocked(bool hasSignal, unsigned width, unsigned height, const std::string& modeName);
|
||||||
|
void SetPerformanceStatsLocked(double frameBudgetMilliseconds, double renderMilliseconds);
|
||||||
|
void SetFramePacingStatsLocked(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
|
||||||
|
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable std::mutex mMutex;
|
mutable std::mutex mMutex;
|
||||||
|
|||||||
Reference in New Issue
Block a user