pass 1
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m39s
CI / Windows Release Package (push) Successful in 2m45s

This commit is contained in:
Aiden
2026-05-11 01:12:24 +10:00
parent 53e78890a8
commit c4883d3413
16 changed files with 618 additions and 303 deletions

View File

@@ -1,9 +1,11 @@
#include "RuntimeStore.h"
#include "RuntimeClock.h"
#include "ShaderPackageRegistry.h"
#include "RuntimeParameterUtils.h"
#include <fstream>
#include <mutex>
#include <random>
#include <sstream>
#include <windows.h>
@@ -129,11 +131,20 @@ bool FontAssetsEqual(const std::vector<ShaderFontAsset>& left, const std::vector
}
}
RuntimeStore::RuntimeStore(RuntimeHost& runtimeHost) :
mRuntimeHost(runtimeHost)
RuntimeStore::RuntimeStore()
{
}
HealthTelemetry& RuntimeStore::GetHealthTelemetry()
{
return mRuntimeHost.GetHealthTelemetry();
}
const HealthTelemetry& RuntimeStore::GetHealthTelemetry() const
{
return mRuntimeHost.GetHealthTelemetry();
}
bool RuntimeStore::InitializeStore(std::string& error)
{
try
@@ -422,7 +433,7 @@ bool RuntimeStore::SetStoredLayerShaderSelection(const std::string& layerId, con
return SavePersistentState(error);
}
bool RuntimeStore::SetStoredParameterValue(const std::string& layerId, const std::string& parameterId, const JsonValue& newValue, std::string& error)
bool RuntimeStore::SetStoredParameterValue(const std::string& layerId, const std::string& parameterId, const ShaderParameterValue& value, bool persistState, std::string& error)
{
std::lock_guard<std::mutex> lock(mRuntimeHost.mMutex);
@@ -433,71 +444,7 @@ bool RuntimeStore::SetStoredParameterValue(const std::string& layerId, const std
return false;
}
auto shaderIt = mRuntimeHost.mPackagesById.find(layer->shaderId);
if (shaderIt == mRuntimeHost.mPackagesById.end())
{
error = "Unknown shader id: " + layer->shaderId;
return false;
}
const ShaderPackage& shaderPackage = shaderIt->second;
auto parameterIt = std::find_if(shaderPackage.parameters.begin(), shaderPackage.parameters.end(),
[&parameterId](const ShaderParameterDefinition& definition) { return definition.id == parameterId; });
if (parameterIt == shaderPackage.parameters.end())
{
error = "Unknown parameter id: " + parameterId;
return false;
}
if (parameterIt->type == ShaderParameterType::Trigger)
{
ShaderParameterValue& value = layer->parameterValues[parameterId];
const double previousCount = value.numberValues.empty() ? 0.0 : value.numberValues[0];
const double triggerTime = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now() - mRuntimeHost.mStartTime).count();
value.numberValues = { previousCount + 1.0, triggerTime };
mRuntimeHost.MarkParameterStateDirtyLocked();
return true;
}
ShaderParameterValue normalized;
if (!mRuntimeHost.NormalizeAndValidateValue(*parameterIt, newValue, normalized, error))
return false;
layer->parameterValues[parameterId] = normalized;
mRuntimeHost.MarkParameterStateDirtyLocked();
return SavePersistentState(error);
}
bool RuntimeStore::SetStoredParameterValueByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue, std::string& error)
{
return SetStoredParameterValueByControlKey(layerKey, parameterKey, newValue, true, error);
}
bool RuntimeStore::SetStoredParameterValueByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue, bool persistState, std::string& error)
{
std::lock_guard<std::mutex> lock(mRuntimeHost.mMutex);
RuntimeHost::LayerPersistentState* matchedLayer = nullptr;
const ShaderPackage* matchedPackage = nullptr;
std::vector<ShaderParameterDefinition>::const_iterator parameterIt;
if (!TryResolveStoredLayerAndParameterByControlKeyLocked(layerKey, parameterKey, matchedLayer, matchedPackage, parameterIt, error))
return false;
if (parameterIt->type == ShaderParameterType::Trigger)
{
ShaderParameterValue& value = matchedLayer->parameterValues[parameterIt->id];
const double previousCount = value.numberValues.empty() ? 0.0 : value.numberValues[0];
const double triggerTime = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now() - mRuntimeHost.mStartTime).count();
value.numberValues = { previousCount + 1.0, triggerTime };
mRuntimeHost.MarkParameterStateDirtyLocked();
return true;
}
ShaderParameterValue normalized;
if (!mRuntimeHost.NormalizeAndValidateValue(*parameterIt, newValue, normalized, error))
return false;
matchedLayer->parameterValues[parameterIt->id] = normalized;
layer->parameterValues[parameterId] = value;
mRuntimeHost.MarkParameterStateDirtyLocked();
return !persistState || SavePersistentState(error);
}
@@ -1194,3 +1141,165 @@ bool RuntimeStore::TryResolveStoredLayerAndParameterByControlKeyLocked(const std
return true;
}
bool RuntimeStore::CopyShaderPackageForStoredLayer(const std::string& layerId, ShaderPackage& shaderPackage, std::string& error) const
{
std::lock_guard<std::mutex> lock(mRuntimeHost.mMutex);
const RuntimeHost::LayerPersistentState* layer = mRuntimeHost.FindLayerById(layerId);
if (!layer)
{
error = "Unknown layer id: " + layerId;
return false;
}
auto it = mRuntimeHost.mPackagesById.find(layer->shaderId);
if (it == mRuntimeHost.mPackagesById.end())
{
error = "Unknown shader id: " + layer->shaderId;
return false;
}
shaderPackage = it->second;
return true;
}
void RuntimeStore::GetShaderCompilerInputs(std::filesystem::path& repoRoot, std::filesystem::path& wrapperPath,
std::filesystem::path& generatedGlslPath, std::filesystem::path& patchedGlslPath, unsigned& maxTemporalHistoryFrames) const
{
std::lock_guard<std::mutex> lock(mRuntimeHost.mMutex);
repoRoot = mRuntimeHost.mRepoRoot;
wrapperPath = mRuntimeHost.mWrapperPath;
generatedGlslPath = mRuntimeHost.mGeneratedGlslPath;
patchedGlslPath = mRuntimeHost.mPatchedGlslPath;
maxTemporalHistoryFrames = mRuntimeHost.mConfig.maxTemporalHistoryFrames;
}
uint64_t RuntimeStore::GetRenderStateVersion() const
{
return mRuntimeHost.mRenderStateVersion.load(std::memory_order_relaxed);
}
uint64_t RuntimeStore::GetParameterStateVersion() const
{
return mRuntimeHost.mParameterStateVersion.load(std::memory_order_relaxed);
}
void RuntimeStore::AdvanceFrameCounter()
{
++mRuntimeHost.mFrameCounter;
}
void RuntimeStore::BuildLayerRenderStates(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const
{
std::lock_guard<std::mutex> lock(mRuntimeHost.mMutex);
BuildLayerRenderStatesLocked(outputWidth, outputHeight, states);
}
bool RuntimeStore::TryBuildLayerRenderStates(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const
{
std::unique_lock<std::mutex> lock(mRuntimeHost.mMutex, std::try_to_lock);
if (!lock.owns_lock())
return false;
BuildLayerRenderStatesLocked(outputWidth, outputHeight, states);
return true;
}
bool RuntimeStore::TryRefreshLayerParameters(std::vector<RuntimeRenderState>& states) const
{
std::unique_lock<std::mutex> lock(mRuntimeHost.mMutex, std::try_to_lock);
if (!lock.owns_lock())
return false;
RefreshLayerParametersLocked(states);
return true;
}
void RuntimeStore::RefreshDynamicRenderStateFields(std::vector<RuntimeRenderState>& states) const
{
std::lock_guard<std::mutex> lock(mRuntimeHost.mMutex);
RefreshDynamicRenderStateFieldsLocked(states);
}
void RuntimeStore::BuildLayerRenderStatesLocked(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const
{
states.clear();
const HealthTelemetry::SignalStatusSnapshot signalStatus = mRuntimeHost.mHealthTelemetry.GetSignalStatusSnapshot();
for (const RuntimeHost::LayerPersistentState& layer : mRuntimeHost.mPersistentState.layers)
{
auto shaderIt = mRuntimeHost.mPackagesById.find(layer.shaderId);
if (shaderIt == mRuntimeHost.mPackagesById.end())
continue;
RuntimeRenderState state;
state.layerId = layer.id;
state.shaderId = layer.shaderId;
state.shaderName = shaderIt->second.displayName;
state.mixAmount = 1.0;
state.bypass = layer.bypass ? 1.0 : 0.0;
state.inputWidth = signalStatus.width;
state.inputHeight = signalStatus.height;
state.outputWidth = outputWidth;
state.outputHeight = outputHeight;
state.parameterDefinitions = shaderIt->second.parameters;
state.textureAssets = shaderIt->second.textureAssets;
state.fontAssets = shaderIt->second.fontAssets;
state.isTemporal = shaderIt->second.temporal.enabled;
state.temporalHistorySource = shaderIt->second.temporal.historySource;
state.requestedTemporalHistoryLength = shaderIt->second.temporal.requestedHistoryLength;
state.effectiveTemporalHistoryLength = shaderIt->second.temporal.effectiveHistoryLength;
state.feedback = shaderIt->second.feedback;
for (const ShaderParameterDefinition& definition : shaderIt->second.parameters)
{
ShaderParameterValue value = mRuntimeHost.DefaultValueForDefinition(definition);
auto valueIt = layer.parameterValues.find(definition.id);
if (valueIt != layer.parameterValues.end())
value = valueIt->second;
state.parameterValues[definition.id] = value;
}
states.push_back(state);
}
RefreshDynamicRenderStateFieldsLocked(states);
}
void RuntimeStore::RefreshLayerParametersLocked(std::vector<RuntimeRenderState>& states) const
{
for (RuntimeRenderState& state : states)
{
const auto layerIt = std::find_if(mRuntimeHost.mPersistentState.layers.begin(), mRuntimeHost.mPersistentState.layers.end(),
[&state](const RuntimeHost::LayerPersistentState& layer) { return layer.id == state.layerId; });
if (layerIt == mRuntimeHost.mPersistentState.layers.end())
continue;
state.bypass = layerIt->bypass ? 1.0 : 0.0;
state.parameterValues.clear();
for (const ShaderParameterDefinition& definition : state.parameterDefinitions)
{
ShaderParameterValue value = mRuntimeHost.DefaultValueForDefinition(definition);
auto valueIt = layerIt->parameterValues.find(definition.id);
if (valueIt != layerIt->parameterValues.end())
value = valueIt->second;
state.parameterValues[definition.id] = value;
}
}
}
void RuntimeStore::RefreshDynamicRenderStateFieldsLocked(std::vector<RuntimeRenderState>& states) const
{
const RuntimeClockSnapshot clock = GetRuntimeClockSnapshot();
const double timeSeconds = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now() - mRuntimeHost.mStartTime).count();
const double frameCount = static_cast<double>(mRuntimeHost.mFrameCounter.load(std::memory_order_relaxed));
for (RuntimeRenderState& state : states)
{
state.timeSeconds = timeSeconds;
state.utcTimeSeconds = clock.utcTimeSeconds;
state.utcOffsetSeconds = clock.utcOffsetSeconds;
state.startupRandom = mRuntimeHost.mStartupRandom;
state.frameCount = frameCount;
}
}