Phase 1 clean-up and separation of concerns
All checks were successful
CI / React UI Build (push) Successful in 10s
CI / Native Windows Build And Tests (push) Successful in 2m34s
CI / Windows Release Package (push) Successful in 2m42s

This commit is contained in:
Aiden
2026-05-10 23:21:13 +10:00
parent 3629227aa9
commit 739231d5a1
24 changed files with 1043 additions and 449 deletions

View File

@@ -148,10 +148,10 @@ bool OpenGLComposite::InitVideoIO()
VideoFormatSelection videoModes;
std::string initFailureReason;
if (mRuntimeStore && mRuntimeStore->GetRepoRoot().empty())
if (mRuntimeStore && mRuntimeStore->GetRuntimeRepositoryRoot().empty())
{
std::string runtimeError;
if (!mRuntimeStore->Initialize(runtimeError))
if (!mRuntimeStore->InitializeStore(runtimeError))
{
MessageBoxA(NULL, runtimeError.c_str(), "Runtime host failed to initialize", MB_OK);
return false;
@@ -161,10 +161,10 @@ bool OpenGLComposite::InitVideoIO()
if (mRuntimeStore)
{
if (!ResolveConfiguredVideoFormats(
mRuntimeStore->GetInputVideoFormat(),
mRuntimeStore->GetInputFrameRate(),
mRuntimeStore->GetOutputVideoFormat(),
mRuntimeStore->GetOutputFrameRate(),
mRuntimeStore->GetConfiguredInputVideoFormat(),
mRuntimeStore->GetConfiguredInputFrameRate(),
mRuntimeStore->GetConfiguredOutputVideoFormat(),
mRuntimeStore->GetConfiguredOutputFrameRate(),
videoModes,
initFailureReason))
{
@@ -181,7 +181,7 @@ bool OpenGLComposite::InitVideoIO()
MessageBoxA(NULL, initFailureReason.c_str(), title, MB_OK | MB_ICONERROR);
return false;
}
const bool outputAlphaRequired = mRuntimeStore && mRuntimeStore->ExternalKeyingEnabled();
const bool outputAlphaRequired = mRuntimeStore && mRuntimeStore->IsExternalKeyingConfigured();
if (!mVideoIO->SelectPreferredFormats(videoModes, outputAlphaRequired, initFailureReason))
goto error;
@@ -216,7 +216,7 @@ bool OpenGLComposite::InitVideoIO()
mRuntimeHost->SetSignalStatus(false, mVideoIO->InputFrameWidth(), mVideoIO->InputFrameHeight(), mVideoIO->InputDisplayModeName());
}
if (!mVideoIO->ConfigureOutput([this](const VideoIOCompletion& completion) { mVideoIOBridge->PlayoutFrameCompleted(completion); }, videoModes.output, mRuntimeStore && mRuntimeStore->ExternalKeyingEnabled(), initFailureReason))
if (!mVideoIO->ConfigureOutput([this](const VideoIOCompletion& completion) { mVideoIOBridge->PlayoutFrameCompleted(completion); }, videoModes.output, mRuntimeStore && mRuntimeStore->IsExternalKeyingConfigured(), initFailureReason))
{
goto error;
}
@@ -239,7 +239,7 @@ void OpenGLComposite::paintGL(bool force)
if (IsIconic(hGLWnd))
return;
const unsigned previewFps = mRuntimeStore ? mRuntimeStore->GetPreviewFps() : 30u;
const unsigned previewFps = mRuntimeStore ? mRuntimeStore->GetConfiguredPreviewFps() : 30u;
if (previewFps == 0)
return;
@@ -294,7 +294,7 @@ void OpenGLComposite::PublishVideoIOStatus(const std::string& statusMessage)
mVideoIO->SupportsInternalKeying(),
mVideoIO->SupportsExternalKeying(),
mVideoIO->KeyerInterfaceAvailable(),
mRuntimeStore ? mRuntimeStore->ExternalKeyingEnabled() : false,
mRuntimeStore ? mRuntimeStore->IsExternalKeyingConfigured() : false,
mVideoIO->ExternalKeyingActive(),
mVideoIO->StatusMessage());
}
@@ -305,7 +305,7 @@ bool OpenGLComposite::InitOpenGLState()
return false;
std::string runtimeError;
if (mRuntimeStore->GetRepoRoot().empty() && !mRuntimeStore->Initialize(runtimeError))
if (mRuntimeStore->GetRuntimeRepositoryRoot().empty() && !mRuntimeStore->InitializeStore(runtimeError))
{
MessageBoxA(NULL, runtimeError.c_str(), "Runtime host failed to initialize", MB_OK);
return false;
@@ -458,7 +458,7 @@ void OpenGLComposite::renderEffect()
if (states.empty() || mOscOverlayStates.empty() || !mRuntimeHost)
return;
const double smoothing = ClampOscAlpha(mRuntimeStore ? mRuntimeStore->GetOscSmoothing() : 0.0);
const double smoothing = ClampOscAlpha(mRuntimeStore ? mRuntimeStore->GetConfiguredOscSmoothing() : 0.0);
std::vector<std::string> overlayKeysToRemove;
for (auto& item : mOscOverlayStates)
{
@@ -600,35 +600,44 @@ void OpenGLComposite::renderEffect()
{
const unsigned renderWidth = mVideoIO->InputFrameWidth();
const unsigned renderHeight = mVideoIO->InputFrameHeight();
const uint64_t renderStateVersion = mRuntimeSnapshotProvider->GetRenderStateVersion();
const uint64_t parameterStateVersion = mRuntimeSnapshotProvider->GetParameterStateVersion();
const RuntimeSnapshotVersions versions = mRuntimeSnapshotProvider->GetVersions();
const bool renderStateCacheValid =
!mCachedLayerRenderStates.empty() &&
mCachedRenderStateVersion == renderStateVersion &&
mCachedRenderStateVersion == versions.renderStateVersion &&
mCachedRenderStateWidth == renderWidth &&
mCachedRenderStateHeight == renderHeight;
if (renderStateCacheValid)
{
applyOscOverlays(mCachedLayerRenderStates, true);
if (mCachedParameterStateVersion != parameterStateVersion &&
mRuntimeSnapshotProvider->TryRefreshCachedLayerStates(mCachedLayerRenderStates))
RuntimeRenderStateSnapshot renderSnapshot;
renderSnapshot.outputWidth = renderWidth;
renderSnapshot.outputHeight = renderHeight;
renderSnapshot.versions.renderStateVersion = mCachedRenderStateVersion;
renderSnapshot.versions.parameterStateVersion = mCachedParameterStateVersion;
renderSnapshot.states = mCachedLayerRenderStates;
applyOscOverlays(renderSnapshot.states, true);
if (mCachedParameterStateVersion != versions.parameterStateVersion &&
mRuntimeSnapshotProvider->TryRefreshSnapshotParameters(renderSnapshot))
{
mCachedParameterStateVersion = parameterStateVersion;
applyOscOverlays(mCachedLayerRenderStates, true);
mCachedParameterStateVersion = renderSnapshot.versions.parameterStateVersion;
applyOscOverlays(renderSnapshot.states, true);
}
layerStates = mCachedLayerRenderStates;
mCachedLayerRenderStates = renderSnapshot.states;
layerStates = renderSnapshot.states;
mRuntimeSnapshotProvider->RefreshDynamicRenderStateFields(layerStates);
}
else
{
if (mRuntimeSnapshotProvider->TryGetLayerRenderStates(renderWidth, renderHeight, layerStates))
RuntimeRenderStateSnapshot renderSnapshot;
if (mRuntimeSnapshotProvider->TryGetRenderStateSnapshot(renderWidth, renderHeight, renderSnapshot))
{
mCachedLayerRenderStates = layerStates;
mCachedRenderStateVersion = renderStateVersion;
mCachedParameterStateVersion = parameterStateVersion;
mCachedRenderStateWidth = renderWidth;
mCachedRenderStateHeight = renderHeight;
mCachedLayerRenderStates = renderSnapshot.states;
mCachedRenderStateVersion = renderSnapshot.versions.renderStateVersion;
mCachedParameterStateVersion = renderSnapshot.versions.parameterStateVersion;
mCachedRenderStateWidth = renderSnapshot.outputWidth;
mCachedRenderStateHeight = renderSnapshot.outputHeight;
applyOscOverlays(mCachedLayerRenderStates, true);
layerStates = mCachedLayerRenderStates;
}
@@ -640,7 +649,7 @@ void OpenGLComposite::renderEffect()
}
}
}
const unsigned historyCap = mRuntimeStore ? mRuntimeStore->GetMaxTemporalHistoryFrames() : 0;
const unsigned historyCap = mRuntimeStore ? mRuntimeStore->GetConfiguredMaxTemporalHistoryFrames() : 0;
mRenderPass->Render(
hasInputSource,
layerStates,
@@ -701,8 +710,8 @@ void OpenGLComposite::ProcessScreenshotRequest()
std::filesystem::path OpenGLComposite::BuildScreenshotPath() const
{
const std::filesystem::path root = mRuntimeStore && !mRuntimeStore->GetRuntimeRoot().empty()
? mRuntimeStore->GetRuntimeRoot()
const std::filesystem::path root = mRuntimeStore && !mRuntimeStore->GetRuntimeDataRoot().empty()
? mRuntimeStore->GetRuntimeDataRoot()
: std::filesystem::current_path();
const auto now = std::chrono::system_clock::now();

View File

@@ -3,22 +3,22 @@
std::string OpenGLComposite::GetRuntimeStateJson() const
{
return mRuntimeStore ? mRuntimeStore->BuildStateJson() : "{}";
return mRuntimeStore ? mRuntimeStore->BuildPersistentStateJson() : "{}";
}
unsigned short OpenGLComposite::GetControlServerPort() const
{
return mRuntimeStore ? mRuntimeStore->GetServerPort() : 0;
return mRuntimeStore ? mRuntimeStore->GetConfiguredControlServerPort() : 0;
}
unsigned short OpenGLComposite::GetOscPort() const
{
return mRuntimeStore ? mRuntimeStore->GetOscPort() : 0;
return mRuntimeStore ? mRuntimeStore->GetConfiguredOscPort() : 0;
}
std::string OpenGLComposite::GetOscBindAddress() const
{
return mRuntimeStore ? mRuntimeStore->GetOscBindAddress() : "127.0.0.1";
return mRuntimeStore ? mRuntimeStore->GetConfiguredOscBindAddress() : "127.0.0.1";
}
std::string OpenGLComposite::GetControlUrl() const
@@ -38,7 +38,7 @@ std::string OpenGLComposite::GetOscAddress() const
bool OpenGLComposite::AddLayer(const std::string& shaderId, std::string& error)
{
if (!mRuntimeStore->AddLayer(shaderId, error))
if (!mRuntimeStore->CreateStoredLayer(shaderId, error))
return false;
ReloadShader(true);
@@ -48,7 +48,7 @@ bool OpenGLComposite::AddLayer(const std::string& shaderId, std::string& error)
bool OpenGLComposite::RemoveLayer(const std::string& layerId, std::string& error)
{
if (!mRuntimeStore->RemoveLayer(layerId, error))
if (!mRuntimeStore->DeleteStoredLayer(layerId, error))
return false;
ReloadShader(true);
@@ -58,7 +58,7 @@ bool OpenGLComposite::RemoveLayer(const std::string& layerId, std::string& error
bool OpenGLComposite::MoveLayer(const std::string& layerId, int direction, std::string& error)
{
if (!mRuntimeStore->MoveLayer(layerId, direction, error))
if (!mRuntimeStore->MoveStoredLayer(layerId, direction, error))
return false;
ReloadShader(true);
@@ -68,7 +68,7 @@ bool OpenGLComposite::MoveLayer(const std::string& layerId, int direction, std::
bool OpenGLComposite::MoveLayerToIndex(const std::string& layerId, std::size_t targetIndex, std::string& error)
{
if (!mRuntimeStore->MoveLayerToIndex(layerId, targetIndex, error))
if (!mRuntimeStore->MoveStoredLayerToIndex(layerId, targetIndex, error))
return false;
ReloadShader(true);
@@ -78,7 +78,7 @@ bool OpenGLComposite::MoveLayerToIndex(const std::string& layerId, std::size_t t
bool OpenGLComposite::SetLayerBypass(const std::string& layerId, bool bypassed, std::string& error)
{
if (!mRuntimeStore->SetLayerBypass(layerId, bypassed, error))
if (!mRuntimeStore->SetStoredLayerBypassState(layerId, bypassed, error))
return false;
ReloadShader();
@@ -88,7 +88,7 @@ bool OpenGLComposite::SetLayerBypass(const std::string& layerId, bool bypassed,
bool OpenGLComposite::SetLayerShader(const std::string& layerId, const std::string& shaderId, std::string& error)
{
if (!mRuntimeStore->SetLayerShader(layerId, shaderId, error))
if (!mRuntimeStore->SetStoredLayerShaderSelection(layerId, shaderId, error))
return false;
ReloadShader();
@@ -102,7 +102,7 @@ bool OpenGLComposite::UpdateLayerParameterJson(const std::string& layerId, const
if (!ParseJson(valueJson, parsedValue, error))
return false;
if (!mRuntimeStore->UpdateLayerParameter(layerId, parameterId, parsedValue, error))
if (!mRuntimeStore->SetStoredParameterValue(layerId, parameterId, parsedValue, error))
return false;
broadcastRuntimeState();
@@ -115,7 +115,7 @@ bool OpenGLComposite::UpdateLayerParameterByControlKeyJson(const std::string& la
if (!ParseJson(valueJson, parsedValue, error))
return false;
if (!mRuntimeStore->UpdateLayerParameterByControlKey(layerKey, parameterKey, parsedValue, error))
if (!mRuntimeStore->SetStoredParameterValueByControlKey(layerKey, parameterKey, parsedValue, error))
return false;
broadcastRuntimeState();
@@ -124,7 +124,7 @@ bool OpenGLComposite::UpdateLayerParameterByControlKeyJson(const std::string& la
bool OpenGLComposite::ResetLayerParameters(const std::string& layerId, std::string& error)
{
if (!mRuntimeStore->ResetLayerParameters(layerId, error))
if (!mRuntimeStore->ResetStoredLayerParameterValues(layerId, error))
return false;
mOscOverlayStates.clear();
@@ -138,7 +138,7 @@ bool OpenGLComposite::ResetLayerParameters(const std::string& layerId, std::stri
bool OpenGLComposite::SaveStackPreset(const std::string& presetName, std::string& error)
{
if (!mRuntimeStore->SaveStackPreset(presetName, error))
if (!mRuntimeStore->SaveStackPresetSnapshot(presetName, error))
return false;
broadcastRuntimeState();
@@ -147,7 +147,7 @@ bool OpenGLComposite::SaveStackPreset(const std::string& presetName, std::string
bool OpenGLComposite::LoadStackPreset(const std::string& presetName, std::string& error)
{
if (!mRuntimeStore->LoadStackPreset(presetName, error))
if (!mRuntimeStore->LoadStackPresetSnapshot(presetName, error))
return false;
ReloadShader();

View File

@@ -47,7 +47,7 @@ bool OpenGLRenderPipeline::RenderFrame(const RenderPipelineFrameContext& context
const auto renderEndTime = std::chrono::steady_clock::now();
const double renderMilliseconds = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(renderEndTime - renderStartTime).count();
mRuntimeHost.TrySetPerformanceStats(state.frameBudgetMilliseconds, renderMilliseconds);
mRuntimeHost.GetHealthTelemetry().TryRecordPerformanceStats(state.frameBudgetMilliseconds, renderMilliseconds);
mRuntimeHost.TryAdvanceFrame();
ReadOutputFrame(state, outputFrame);

View File

@@ -46,7 +46,7 @@ void OpenGLVideoIOBridge::RecordFramePacing(VideoIOCompletionResult completionRe
else if (completionResult == VideoIOCompletionResult::Flushed)
++mFlushedFrameCount;
mRuntimeHost.TrySetFramePacingStats(
mRuntimeHost.GetHealthTelemetry().TryRecordFramePacingStats(
mCompletionIntervalMilliseconds,
mSmoothedCompletionIntervalMilliseconds,
mMaxCompletionIntervalMilliseconds,
@@ -58,7 +58,7 @@ void OpenGLVideoIOBridge::RecordFramePacing(VideoIOCompletionResult completionRe
void OpenGLVideoIOBridge::VideoFrameArrived(const VideoIOFrame& inputFrame)
{
const VideoIOState& state = mVideoIO.State();
mRuntimeHost.TrySetSignalStatus(!inputFrame.hasNoInputSource, state.inputFrameSize.width, state.inputFrameSize.height, state.inputDisplayModeName);
mRuntimeHost.GetHealthTelemetry().TryReportSignalStatus(!inputFrame.hasNoInputSource, state.inputFrameSize.width, state.inputFrameSize.height, state.inputDisplayModeName);
if (inputFrame.hasNoInputSource || inputFrame.bytes == nullptr)
return; // don't transfer texture when there's no input

View File

@@ -40,7 +40,9 @@ OpenGLShaderPrograms::OpenGLShaderPrograms(OpenGLRenderer& renderer, RuntimeHost
bool OpenGLShaderPrograms::CompileLayerPrograms(unsigned inputFrameWidth, unsigned inputFrameHeight, int errorMessageSize, char* errorMessage)
{
const std::vector<RuntimeRenderState> layerStates = mRuntimeSnapshotProvider.GetLayerRenderStates(inputFrameWidth, inputFrameHeight);
const RuntimeRenderStateSnapshot renderSnapshot =
mRuntimeSnapshotProvider.GetRenderStateSnapshot(inputFrameWidth, inputFrameHeight);
const std::vector<RuntimeRenderState>& layerStates = renderSnapshot.states;
std::string temporalError;
const unsigned historyCap = mRuntimeHost.GetMaxTemporalHistoryFrames();
if (!mRenderer.TemporalHistory().ValidateTextureUnitBudget(layerStates, historyCap, temporalError))
@@ -88,7 +90,7 @@ bool OpenGLShaderPrograms::CompileLayerPrograms(unsigned inputFrameWidth, unsign
DestroyLayerPrograms();
mRenderer.ReplaceLayerPrograms(newPrograms);
mCommittedLayerStates = layerStates;
mCommittedLayerStates = renderSnapshot.states;
mRuntimeHost.SetCompileStatus(true, "Shader layers compiled successfully.");
mRuntimeHost.ClearReloadRequest();
@@ -106,18 +108,18 @@ bool OpenGLShaderPrograms::CommitPreparedLayerPrograms(const PreparedShaderBuild
std::string temporalError;
const unsigned historyCap = mRuntimeHost.GetMaxTemporalHistoryFrames();
if (!mRenderer.TemporalHistory().ValidateTextureUnitBudget(preparedBuild.layerStates, historyCap, temporalError))
if (!mRenderer.TemporalHistory().ValidateTextureUnitBudget(preparedBuild.renderSnapshot.states, historyCap, temporalError))
{
CopyErrorMessage(temporalError, errorMessageSize, errorMessage);
return false;
}
if (!mRenderer.TemporalHistory().EnsureResources(preparedBuild.layerStates, historyCap, inputFrameWidth, inputFrameHeight, temporalError))
if (!mRenderer.TemporalHistory().EnsureResources(preparedBuild.renderSnapshot.states, historyCap, inputFrameWidth, inputFrameHeight, temporalError))
{
CopyErrorMessage(temporalError, errorMessageSize, errorMessage);
return false;
}
if (mRenderer.ResourcesInitialized() &&
!mRenderer.FeedbackBuffers().EnsureResources(preparedBuild.layerStates, inputFrameWidth, inputFrameHeight, temporalError))
!mRenderer.FeedbackBuffers().EnsureResources(preparedBuild.renderSnapshot.states, inputFrameWidth, inputFrameHeight, temporalError))
{
CopyErrorMessage(temporalError, errorMessageSize, errorMessage);
return false;
@@ -151,7 +153,7 @@ bool OpenGLShaderPrograms::CommitPreparedLayerPrograms(const PreparedShaderBuild
DestroyLayerPrograms();
mRenderer.ReplaceLayerPrograms(newPrograms);
mCommittedLayerStates = preparedBuild.layerStates;
mCommittedLayerStates = preparedBuild.renderSnapshot.states;
mRuntimeHost.SetCompileStatus(true, "Shader layers compiled successfully.");
mRuntimeHost.ClearReloadRequest();

View File

@@ -111,10 +111,10 @@ PreparedShaderBuild ShaderBuildQueue::Build(uint64_t generation, unsigned output
{
PreparedShaderBuild build;
build.generation = generation;
build.layerStates = mRuntimeSnapshotProvider.GetLayerRenderStates(outputWidth, outputHeight);
build.layers.reserve(build.layerStates.size());
build.renderSnapshot = mRuntimeSnapshotProvider.GetRenderStateSnapshot(outputWidth, outputHeight);
build.layers.reserve(build.renderSnapshot.states.size());
for (const RuntimeRenderState& state : build.layerStates)
for (const RuntimeRenderState& state : build.renderSnapshot.states)
{
PreparedLayerShader layer;
layer.state = state;

View File

@@ -21,7 +21,7 @@ struct PreparedShaderBuild
uint64_t generation = 0;
bool succeeded = false;
std::string message;
std::vector<RuntimeRenderState> layerStates;
RuntimeRenderStateSnapshot renderSnapshot;
std::vector<PreparedLayerShader> layers;
};