phase 1 runtime complete
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,103 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "HealthTelemetry.h"
|
||||
#include "RuntimeJson.h"
|
||||
#include "ShaderTypes.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class RuntimeStore;
|
||||
class RuntimeHost
|
||||
{
|
||||
public:
|
||||
RuntimeHost();
|
||||
HealthTelemetry& GetHealthTelemetry() { return mHealthTelemetry; }
|
||||
const HealthTelemetry& GetHealthTelemetry() const { return mHealthTelemetry; }
|
||||
bool AutoReloadEnabled() const { return mAutoReloadEnabled; }
|
||||
|
||||
private:
|
||||
struct AppConfig
|
||||
{
|
||||
std::string shaderLibrary = "shaders";
|
||||
unsigned short serverPort = 8080;
|
||||
unsigned short oscPort = 9000;
|
||||
std::string oscBindAddress = "127.0.0.1";
|
||||
double oscSmoothing = 0.18;
|
||||
bool autoReload = true;
|
||||
unsigned maxTemporalHistoryFrames = 4;
|
||||
unsigned previewFps = 30;
|
||||
bool enableExternalKeying = false;
|
||||
std::string inputVideoFormat = "1080p";
|
||||
std::string inputFrameRate = "59.94";
|
||||
std::string outputVideoFormat = "1080p";
|
||||
std::string outputFrameRate = "59.94";
|
||||
};
|
||||
|
||||
struct LayerPersistentState
|
||||
{
|
||||
std::string id;
|
||||
std::string shaderId;
|
||||
bool bypass = false;
|
||||
std::map<std::string, ShaderParameterValue> parameterValues;
|
||||
};
|
||||
|
||||
struct PersistentState
|
||||
{
|
||||
std::vector<LayerPersistentState> layers;
|
||||
};
|
||||
|
||||
bool NormalizeAndValidateValue(const ShaderParameterDefinition& definition, const JsonValue& value, ShaderParameterValue& normalizedValue, std::string& error) const;
|
||||
ShaderParameterValue DefaultValueForDefinition(const ShaderParameterDefinition& definition) const;
|
||||
void EnsureLayerDefaultsLocked(LayerPersistentState& layerState, const ShaderPackage& shaderPackage) const;
|
||||
JsonValue SerializeLayerStackLocked() const;
|
||||
bool DeserializeLayerStackLocked(const JsonValue& layersValue, std::vector<LayerPersistentState>& layers, std::string& error);
|
||||
void NormalizePersistentLayerIdsLocked();
|
||||
JsonValue SerializeParameterValue(const ShaderParameterDefinition& definition, const ShaderParameterValue& value) const;
|
||||
std::string TemporalHistorySourceToString(TemporalHistorySource source) const;
|
||||
LayerPersistentState* FindLayerById(const std::string& layerId);
|
||||
const LayerPersistentState* FindLayerById(const std::string& layerId) const;
|
||||
std::string GenerateLayerId();
|
||||
void MarkRenderStateDirtyLocked();
|
||||
void MarkParameterStateDirtyLocked();
|
||||
|
||||
private:
|
||||
friend class RuntimeStore;
|
||||
friend class RuntimeCoordinator;
|
||||
HealthTelemetry mHealthTelemetry;
|
||||
mutable std::mutex mMutex;
|
||||
AppConfig mConfig;
|
||||
PersistentState mPersistentState;
|
||||
std::filesystem::path mRepoRoot;
|
||||
std::filesystem::path mUiRoot;
|
||||
std::filesystem::path mDocsRoot;
|
||||
std::filesystem::path mShaderRoot;
|
||||
std::filesystem::path mRuntimeRoot;
|
||||
std::filesystem::path mPresetRoot;
|
||||
std::filesystem::path mRuntimeStatePath;
|
||||
std::filesystem::path mConfigPath;
|
||||
std::filesystem::path mWrapperPath;
|
||||
std::filesystem::path mGeneratedGlslPath;
|
||||
std::filesystem::path mPatchedGlslPath;
|
||||
std::map<std::string, ShaderPackage> mPackagesById;
|
||||
std::vector<std::string> mPackageOrder;
|
||||
std::vector<ShaderPackageStatus> mPackageStatuses;
|
||||
bool mReloadRequested;
|
||||
bool mCompileSucceeded;
|
||||
std::string mCompileMessage;
|
||||
double mStartupRandom;
|
||||
unsigned short mServerPort;
|
||||
bool mAutoReloadEnabled;
|
||||
std::chrono::steady_clock::time_point mStartTime;
|
||||
std::chrono::steady_clock::time_point mLastScanTime;
|
||||
std::atomic<uint64_t> mFrameCounter{ 0 };
|
||||
std::atomic<uint64_t> mRenderStateVersion{ 0 };
|
||||
std::atomic<uint64_t> mParameterStateVersion{ 0 };
|
||||
uint64_t mNextLayerId;
|
||||
};
|
||||
@@ -22,37 +22,50 @@ std::string ShaderParameterTypeToString(ShaderParameterType type)
|
||||
|
||||
JsonValue RuntimeStateJson::SerializeLayerStack(const LayerStackStore& layerStack, const ShaderPackageCatalog& shaderCatalog)
|
||||
{
|
||||
JsonValue layers = JsonValue::MakeArray();
|
||||
for (const LayerStackStore::LayerPersistentState& layer : layerStack.Layers())
|
||||
std::map<std::string, ShaderPackage> packagesById;
|
||||
for (const std::string& packageId : shaderCatalog.PackageOrder())
|
||||
{
|
||||
const ShaderPackage* shaderPackage = shaderCatalog.FindPackage(layer.shaderId);
|
||||
if (!shaderPackage)
|
||||
ShaderPackage shaderPackage;
|
||||
if (shaderCatalog.CopyPackage(packageId, shaderPackage))
|
||||
packagesById[packageId] = shaderPackage;
|
||||
}
|
||||
return SerializeLayerStack(layerStack.Layers(), packagesById);
|
||||
}
|
||||
|
||||
JsonValue RuntimeStateJson::SerializeLayerStack(const std::vector<LayerStackStore::LayerPersistentState>& layerStates, const std::map<std::string, ShaderPackage>& packagesById)
|
||||
{
|
||||
JsonValue layersValue = JsonValue::MakeArray();
|
||||
for (const LayerStackStore::LayerPersistentState& layer : layerStates)
|
||||
{
|
||||
auto shaderIt = packagesById.find(layer.shaderId);
|
||||
if (shaderIt == packagesById.end())
|
||||
continue;
|
||||
const ShaderPackage& shaderPackage = shaderIt->second;
|
||||
|
||||
JsonValue layerValue = JsonValue::MakeObject();
|
||||
layerValue.set("id", JsonValue(layer.id));
|
||||
layerValue.set("shaderId", JsonValue(layer.shaderId));
|
||||
layerValue.set("shaderName", JsonValue(shaderPackage->displayName));
|
||||
layerValue.set("shaderName", JsonValue(shaderPackage.displayName));
|
||||
layerValue.set("bypass", JsonValue(layer.bypass));
|
||||
if (shaderPackage->temporal.enabled)
|
||||
if (shaderPackage.temporal.enabled)
|
||||
{
|
||||
JsonValue temporal = JsonValue::MakeObject();
|
||||
temporal.set("enabled", JsonValue(true));
|
||||
temporal.set("historySource", JsonValue(TemporalHistorySourceToString(shaderPackage->temporal.historySource)));
|
||||
temporal.set("requestedHistoryLength", JsonValue(static_cast<double>(shaderPackage->temporal.requestedHistoryLength)));
|
||||
temporal.set("effectiveHistoryLength", JsonValue(static_cast<double>(shaderPackage->temporal.effectiveHistoryLength)));
|
||||
temporal.set("historySource", JsonValue(TemporalHistorySourceToString(shaderPackage.temporal.historySource)));
|
||||
temporal.set("requestedHistoryLength", JsonValue(static_cast<double>(shaderPackage.temporal.requestedHistoryLength)));
|
||||
temporal.set("effectiveHistoryLength", JsonValue(static_cast<double>(shaderPackage.temporal.effectiveHistoryLength)));
|
||||
layerValue.set("temporal", temporal);
|
||||
}
|
||||
if (shaderPackage->feedback.enabled)
|
||||
if (shaderPackage.feedback.enabled)
|
||||
{
|
||||
JsonValue feedback = JsonValue::MakeObject();
|
||||
feedback.set("enabled", JsonValue(true));
|
||||
feedback.set("writePass", JsonValue(shaderPackage->feedback.writePassId));
|
||||
feedback.set("writePass", JsonValue(shaderPackage.feedback.writePassId));
|
||||
layerValue.set("feedback", feedback);
|
||||
}
|
||||
|
||||
JsonValue parameters = JsonValue::MakeArray();
|
||||
for (const ShaderParameterDefinition& definition : shaderPackage->parameters)
|
||||
for (const ShaderParameterDefinition& definition : shaderPackage.parameters)
|
||||
{
|
||||
JsonValue parameter = JsonValue::MakeObject();
|
||||
parameter.set("id", JsonValue(definition.id));
|
||||
@@ -111,9 +124,9 @@ JsonValue RuntimeStateJson::SerializeLayerStack(const LayerStackStore& layerStac
|
||||
}
|
||||
|
||||
layerValue.set("parameters", parameters);
|
||||
layers.pushBack(layerValue);
|
||||
layersValue.pushBack(layerValue);
|
||||
}
|
||||
return layers;
|
||||
return layersValue;
|
||||
}
|
||||
|
||||
JsonValue RuntimeStateJson::SerializeParameterValue(const ShaderParameterDefinition& definition, const ShaderParameterValue& value)
|
||||
|
||||
@@ -5,12 +5,15 @@
|
||||
#include "ShaderPackageCatalog.h"
|
||||
#include "ShaderTypes.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class RuntimeStateJson
|
||||
{
|
||||
public:
|
||||
static JsonValue SerializeLayerStack(const LayerStackStore& layerStack, const ShaderPackageCatalog& shaderCatalog);
|
||||
static JsonValue SerializeLayerStack(const std::vector<LayerStackStore::LayerPersistentState>& layers, const std::map<std::string, ShaderPackage>& packagesById);
|
||||
static JsonValue SerializeParameterValue(const ShaderParameterDefinition& definition, const ShaderParameterValue& value);
|
||||
static std::string TemporalHistorySourceToString(TemporalHistorySource source);
|
||||
};
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
#include "RuntimeStateJson.h"
|
||||
#include "RuntimeStore.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
std::string RuntimeStatePresenter::BuildRuntimeStateJson(const RuntimeStore& runtimeStore)
|
||||
{
|
||||
return SerializeJson(BuildRuntimeStateValue(runtimeStore), true);
|
||||
@@ -12,30 +10,30 @@ std::string RuntimeStatePresenter::BuildRuntimeStateJson(const RuntimeStore& run
|
||||
|
||||
JsonValue RuntimeStatePresenter::BuildRuntimeStateValue(const RuntimeStore& runtimeStore)
|
||||
{
|
||||
const HealthTelemetry::Snapshot telemetrySnapshot = runtimeStore.mHealthTelemetry.GetSnapshot();
|
||||
std::lock_guard<std::mutex> lock(runtimeStore.mMutex);
|
||||
const RuntimeStatePresentationReadModel model = runtimeStore.BuildRuntimeStatePresentationReadModel();
|
||||
const HealthTelemetry::Snapshot& telemetrySnapshot = model.telemetry;
|
||||
|
||||
JsonValue root = JsonValue::MakeObject();
|
||||
|
||||
JsonValue app = JsonValue::MakeObject();
|
||||
app.set("serverPort", JsonValue(static_cast<double>(runtimeStore.mServerPort)));
|
||||
app.set("oscPort", JsonValue(static_cast<double>(runtimeStore.mConfigStore.GetConfig().oscPort)));
|
||||
app.set("oscBindAddress", JsonValue(runtimeStore.mConfigStore.GetConfig().oscBindAddress));
|
||||
app.set("oscSmoothing", JsonValue(runtimeStore.mConfigStore.GetConfig().oscSmoothing));
|
||||
app.set("autoReload", JsonValue(runtimeStore.mAutoReloadEnabled));
|
||||
app.set("maxTemporalHistoryFrames", JsonValue(static_cast<double>(runtimeStore.mConfigStore.GetConfig().maxTemporalHistoryFrames)));
|
||||
app.set("previewFps", JsonValue(static_cast<double>(runtimeStore.mConfigStore.GetConfig().previewFps)));
|
||||
app.set("enableExternalKeying", JsonValue(runtimeStore.mConfigStore.GetConfig().enableExternalKeying));
|
||||
app.set("inputVideoFormat", JsonValue(runtimeStore.mConfigStore.GetConfig().inputVideoFormat));
|
||||
app.set("inputFrameRate", JsonValue(runtimeStore.mConfigStore.GetConfig().inputFrameRate));
|
||||
app.set("outputVideoFormat", JsonValue(runtimeStore.mConfigStore.GetConfig().outputVideoFormat));
|
||||
app.set("outputFrameRate", JsonValue(runtimeStore.mConfigStore.GetConfig().outputFrameRate));
|
||||
app.set("serverPort", JsonValue(static_cast<double>(model.serverPort)));
|
||||
app.set("oscPort", JsonValue(static_cast<double>(model.config.oscPort)));
|
||||
app.set("oscBindAddress", JsonValue(model.config.oscBindAddress));
|
||||
app.set("oscSmoothing", JsonValue(model.config.oscSmoothing));
|
||||
app.set("autoReload", JsonValue(model.autoReloadEnabled));
|
||||
app.set("maxTemporalHistoryFrames", JsonValue(static_cast<double>(model.config.maxTemporalHistoryFrames)));
|
||||
app.set("previewFps", JsonValue(static_cast<double>(model.config.previewFps)));
|
||||
app.set("enableExternalKeying", JsonValue(model.config.enableExternalKeying));
|
||||
app.set("inputVideoFormat", JsonValue(model.config.inputVideoFormat));
|
||||
app.set("inputFrameRate", JsonValue(model.config.inputFrameRate));
|
||||
app.set("outputVideoFormat", JsonValue(model.config.outputVideoFormat));
|
||||
app.set("outputFrameRate", JsonValue(model.config.outputFrameRate));
|
||||
root.set("app", app);
|
||||
|
||||
JsonValue runtime = JsonValue::MakeObject();
|
||||
runtime.set("layerCount", JsonValue(static_cast<double>(runtimeStore.mLayerStack.LayerCount())));
|
||||
runtime.set("compileSucceeded", JsonValue(runtimeStore.mCompileSucceeded));
|
||||
runtime.set("compileMessage", JsonValue(runtimeStore.mCompileMessage));
|
||||
runtime.set("layerCount", JsonValue(static_cast<double>(model.layerStack.LayerCount())));
|
||||
runtime.set("compileSucceeded", JsonValue(model.compileSucceeded));
|
||||
runtime.set("compileMessage", JsonValue(model.compileMessage));
|
||||
root.set("runtime", runtime);
|
||||
|
||||
JsonValue video = JsonValue::MakeObject();
|
||||
@@ -83,7 +81,7 @@ JsonValue RuntimeStatePresenter::BuildRuntimeStateValue(const RuntimeStore& runt
|
||||
root.set("performance", performance);
|
||||
|
||||
JsonValue shaderLibrary = JsonValue::MakeArray();
|
||||
for (const ShaderPackageStatus& status : runtimeStore.mShaderCatalog.PackageStatuses())
|
||||
for (const ShaderPackageStatus& status : model.packageStatuses)
|
||||
{
|
||||
JsonValue shader = JsonValue::MakeObject();
|
||||
shader.set("id", JsonValue(status.id));
|
||||
@@ -94,21 +92,23 @@ JsonValue RuntimeStatePresenter::BuildRuntimeStateValue(const RuntimeStore& runt
|
||||
if (!status.available)
|
||||
shader.set("error", JsonValue(status.error));
|
||||
|
||||
const ShaderPackage* shaderPackage = runtimeStore.mShaderCatalog.FindPackage(status.id);
|
||||
if (status.available && shaderPackage && shaderPackage->temporal.enabled)
|
||||
auto shaderIt = model.shaderCatalog.packagesById.find(status.id);
|
||||
if (status.available && shaderIt != model.shaderCatalog.packagesById.end() && shaderIt->second.temporal.enabled)
|
||||
{
|
||||
const ShaderPackage& shaderPackage = shaderIt->second;
|
||||
JsonValue temporal = JsonValue::MakeObject();
|
||||
temporal.set("enabled", JsonValue(true));
|
||||
temporal.set("historySource", JsonValue(RuntimeStateJson::TemporalHistorySourceToString(shaderPackage->temporal.historySource)));
|
||||
temporal.set("requestedHistoryLength", JsonValue(static_cast<double>(shaderPackage->temporal.requestedHistoryLength)));
|
||||
temporal.set("effectiveHistoryLength", JsonValue(static_cast<double>(shaderPackage->temporal.effectiveHistoryLength)));
|
||||
temporal.set("historySource", JsonValue(RuntimeStateJson::TemporalHistorySourceToString(shaderPackage.temporal.historySource)));
|
||||
temporal.set("requestedHistoryLength", JsonValue(static_cast<double>(shaderPackage.temporal.requestedHistoryLength)));
|
||||
temporal.set("effectiveHistoryLength", JsonValue(static_cast<double>(shaderPackage.temporal.effectiveHistoryLength)));
|
||||
shader.set("temporal", temporal);
|
||||
}
|
||||
if (status.available && shaderPackage && shaderPackage->feedback.enabled)
|
||||
if (status.available && shaderIt != model.shaderCatalog.packagesById.end() && shaderIt->second.feedback.enabled)
|
||||
{
|
||||
const ShaderPackage& shaderPackage = shaderIt->second;
|
||||
JsonValue feedback = JsonValue::MakeObject();
|
||||
feedback.set("enabled", JsonValue(true));
|
||||
feedback.set("writePass", JsonValue(shaderPackage->feedback.writePassId));
|
||||
feedback.set("writePass", JsonValue(shaderPackage.feedback.writePassId));
|
||||
shader.set("feedback", feedback);
|
||||
}
|
||||
shaderLibrary.pushBack(shader);
|
||||
@@ -116,10 +116,10 @@ JsonValue RuntimeStatePresenter::BuildRuntimeStateValue(const RuntimeStore& runt
|
||||
root.set("shaders", shaderLibrary);
|
||||
|
||||
JsonValue stackPresets = JsonValue::MakeArray();
|
||||
for (const std::string& presetName : runtimeStore.GetStackPresetNamesLocked())
|
||||
for (const std::string& presetName : model.stackPresetNames)
|
||||
stackPresets.pushBack(JsonValue(presetName));
|
||||
root.set("stackPresets", stackPresets);
|
||||
|
||||
root.set("layers", RuntimeStateJson::SerializeLayerStack(runtimeStore.mLayerStack, runtimeStore.mShaderCatalog));
|
||||
root.set("layers", RuntimeStateJson::SerializeLayerStack(model.layerStack.Layers(), model.shaderCatalog.packagesById));
|
||||
return root;
|
||||
}
|
||||
|
||||
@@ -24,19 +24,14 @@ bool RenderSnapshotBuilder::BuildLayerPassFragmentShaderSources(const std::strin
|
||||
if (!mRuntimeStore.CopyShaderPackageForStoredLayer(layerId, shaderPackage, error))
|
||||
return false;
|
||||
|
||||
std::filesystem::path repoRoot;
|
||||
std::filesystem::path wrapperPath;
|
||||
std::filesystem::path generatedGlslPath;
|
||||
std::filesystem::path patchedGlslPath;
|
||||
unsigned maxTemporalHistoryFrames = 0;
|
||||
mRuntimeStore.GetShaderCompilerInputs(repoRoot, wrapperPath, generatedGlslPath, patchedGlslPath, maxTemporalHistoryFrames);
|
||||
const ShaderCompilerInputs inputs = mRuntimeStore.GetShaderCompilerInputs();
|
||||
|
||||
ShaderCompiler compiler(
|
||||
repoRoot,
|
||||
wrapperPath,
|
||||
generatedGlslPath,
|
||||
patchedGlslPath,
|
||||
maxTemporalHistoryFrames);
|
||||
inputs.repoRoot,
|
||||
inputs.wrapperPath,
|
||||
inputs.generatedGlslPath,
|
||||
inputs.patchedGlslPath,
|
||||
inputs.maxTemporalHistoryFrames);
|
||||
passSources.clear();
|
||||
passSources.reserve(shaderPackage.passes.size());
|
||||
for (const ShaderPassDefinition& pass : shaderPackage.passes)
|
||||
@@ -83,34 +78,24 @@ void RenderSnapshotBuilder::AdvanceFrame()
|
||||
|
||||
void RenderSnapshotBuilder::BuildLayerRenderStates(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeStore.mMutex);
|
||||
BuildLayerRenderStatesLocked(outputWidth, outputHeight, states);
|
||||
BuildLayerRenderStates(outputWidth, outputHeight, mRuntimeStore.BuildRenderSnapshotReadModel(), states);
|
||||
}
|
||||
|
||||
bool RenderSnapshotBuilder::TryBuildLayerRenderStates(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mRuntimeStore.mMutex, std::try_to_lock);
|
||||
if (!lock.owns_lock())
|
||||
return false;
|
||||
|
||||
BuildLayerRenderStatesLocked(outputWidth, outputHeight, states);
|
||||
BuildLayerRenderStates(outputWidth, outputHeight, mRuntimeStore.BuildRenderSnapshotReadModel(), states);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RenderSnapshotBuilder::TryRefreshLayerParameters(std::vector<RuntimeRenderState>& states) const
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(mRuntimeStore.mMutex, std::try_to_lock);
|
||||
if (!lock.owns_lock())
|
||||
return false;
|
||||
|
||||
RefreshLayerParametersLocked(states);
|
||||
RefreshLayerParameters(mRuntimeStore.CopyLayerStates(), states);
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderSnapshotBuilder::RefreshDynamicRenderStateFields(std::vector<RuntimeRenderState>& states) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeStore.mMutex);
|
||||
RefreshDynamicRenderStateFieldsLocked(states);
|
||||
RefreshDynamicRenderStateFields(mRuntimeStore.GetRenderTimingSnapshot(), states);
|
||||
}
|
||||
|
||||
void RenderSnapshotBuilder::MarkRenderStateDirty()
|
||||
@@ -124,37 +109,37 @@ void RenderSnapshotBuilder::MarkParameterStateDirty()
|
||||
mParameterStateVersion.fetch_add(1, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void RenderSnapshotBuilder::BuildLayerRenderStatesLocked(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const
|
||||
void RenderSnapshotBuilder::BuildLayerRenderStates(unsigned outputWidth, unsigned outputHeight, const RenderSnapshotReadModel& readModel, std::vector<RuntimeRenderState>& states) const
|
||||
{
|
||||
states.clear();
|
||||
const HealthTelemetry::SignalStatusSnapshot signalStatus = mRuntimeStore.mHealthTelemetry.GetSignalStatusSnapshot();
|
||||
|
||||
for (const RuntimeStore::LayerPersistentState& layer : mRuntimeStore.mLayerStack.Layers())
|
||||
for (const LayerStackStore::LayerPersistentState& layer : readModel.layers)
|
||||
{
|
||||
const ShaderPackage* shaderPackage = mRuntimeStore.mShaderCatalog.FindPackage(layer.shaderId);
|
||||
if (!shaderPackage)
|
||||
auto shaderIt = readModel.packagesById.find(layer.shaderId);
|
||||
if (shaderIt == readModel.packagesById.end())
|
||||
continue;
|
||||
const ShaderPackage& shaderPackage = shaderIt->second;
|
||||
|
||||
RuntimeRenderState state;
|
||||
state.layerId = layer.id;
|
||||
state.shaderId = layer.shaderId;
|
||||
state.shaderName = shaderPackage->displayName;
|
||||
state.shaderName = shaderPackage.displayName;
|
||||
state.mixAmount = 1.0;
|
||||
state.bypass = layer.bypass ? 1.0 : 0.0;
|
||||
state.inputWidth = signalStatus.width;
|
||||
state.inputHeight = signalStatus.height;
|
||||
state.inputWidth = readModel.signalStatus.width;
|
||||
state.inputHeight = readModel.signalStatus.height;
|
||||
state.outputWidth = outputWidth;
|
||||
state.outputHeight = outputHeight;
|
||||
state.parameterDefinitions = shaderPackage->parameters;
|
||||
state.textureAssets = shaderPackage->textureAssets;
|
||||
state.fontAssets = shaderPackage->fontAssets;
|
||||
state.isTemporal = shaderPackage->temporal.enabled;
|
||||
state.temporalHistorySource = shaderPackage->temporal.historySource;
|
||||
state.requestedTemporalHistoryLength = shaderPackage->temporal.requestedHistoryLength;
|
||||
state.effectiveTemporalHistoryLength = shaderPackage->temporal.effectiveHistoryLength;
|
||||
state.feedback = shaderPackage->feedback;
|
||||
state.parameterDefinitions = shaderPackage.parameters;
|
||||
state.textureAssets = shaderPackage.textureAssets;
|
||||
state.fontAssets = shaderPackage.fontAssets;
|
||||
state.isTemporal = shaderPackage.temporal.enabled;
|
||||
state.temporalHistorySource = shaderPackage.temporal.historySource;
|
||||
state.requestedTemporalHistoryLength = shaderPackage.temporal.requestedHistoryLength;
|
||||
state.effectiveTemporalHistoryLength = shaderPackage.temporal.effectiveHistoryLength;
|
||||
state.feedback = shaderPackage.feedback;
|
||||
|
||||
for (const ShaderParameterDefinition& definition : shaderPackage->parameters)
|
||||
for (const ShaderParameterDefinition& definition : shaderPackage.parameters)
|
||||
{
|
||||
ShaderParameterValue value = DefaultValueForDefinition(definition);
|
||||
auto valueIt = layer.parameterValues.find(definition.id);
|
||||
@@ -166,16 +151,16 @@ void RenderSnapshotBuilder::BuildLayerRenderStatesLocked(unsigned outputWidth, u
|
||||
states.push_back(state);
|
||||
}
|
||||
|
||||
RefreshDynamicRenderStateFieldsLocked(states);
|
||||
RefreshDynamicRenderStateFields(readModel.timing, states);
|
||||
}
|
||||
|
||||
void RenderSnapshotBuilder::RefreshLayerParametersLocked(std::vector<RuntimeRenderState>& states) const
|
||||
void RenderSnapshotBuilder::RefreshLayerParameters(const std::vector<LayerStackStore::LayerPersistentState>& layers, std::vector<RuntimeRenderState>& states) const
|
||||
{
|
||||
for (RuntimeRenderState& state : states)
|
||||
{
|
||||
const auto layerIt = std::find_if(mRuntimeStore.mLayerStack.Layers().begin(), mRuntimeStore.mLayerStack.Layers().end(),
|
||||
[&state](const RuntimeStore::LayerPersistentState& layer) { return layer.id == state.layerId; });
|
||||
if (layerIt == mRuntimeStore.mLayerStack.Layers().end())
|
||||
const auto layerIt = std::find_if(layers.begin(), layers.end(),
|
||||
[&state](const LayerStackStore::LayerPersistentState& layer) { return layer.id == state.layerId; });
|
||||
if (layerIt == layers.end())
|
||||
continue;
|
||||
|
||||
state.bypass = layerIt->bypass ? 1.0 : 0.0;
|
||||
@@ -191,10 +176,10 @@ void RenderSnapshotBuilder::RefreshLayerParametersLocked(std::vector<RuntimeRend
|
||||
}
|
||||
}
|
||||
|
||||
void RenderSnapshotBuilder::RefreshDynamicRenderStateFieldsLocked(std::vector<RuntimeRenderState>& states) const
|
||||
void RenderSnapshotBuilder::RefreshDynamicRenderStateFields(const RenderTimingSnapshot& timing, 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() - mRuntimeStore.mStartTime).count();
|
||||
const double timeSeconds = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now() - timing.startTime).count();
|
||||
const double frameCount = static_cast<double>(mFrameCounter.load(std::memory_order_relaxed));
|
||||
|
||||
for (RuntimeRenderState& state : states)
|
||||
@@ -202,7 +187,7 @@ void RenderSnapshotBuilder::RefreshDynamicRenderStateFieldsLocked(std::vector<Ru
|
||||
state.timeSeconds = timeSeconds;
|
||||
state.utcTimeSeconds = clock.utcTimeSeconds;
|
||||
state.utcOffsetSeconds = clock.utcOffsetSeconds;
|
||||
state.startupRandom = mRuntimeStore.mStartupRandom;
|
||||
state.startupRandom = timing.startupRandom;
|
||||
state.frameCount = frameCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "RuntimeStoreReadModels.h"
|
||||
#include "ShaderTypes.h"
|
||||
|
||||
#include <atomic>
|
||||
@@ -32,9 +33,9 @@ public:
|
||||
void MarkParameterStateDirty();
|
||||
|
||||
private:
|
||||
void BuildLayerRenderStatesLocked(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const;
|
||||
void RefreshLayerParametersLocked(std::vector<RuntimeRenderState>& states) const;
|
||||
void RefreshDynamicRenderStateFieldsLocked(std::vector<RuntimeRenderState>& states) const;
|
||||
void BuildLayerRenderStates(unsigned outputWidth, unsigned outputHeight, const RenderSnapshotReadModel& readModel, std::vector<RuntimeRenderState>& states) const;
|
||||
void RefreshLayerParameters(const std::vector<LayerStackStore::LayerPersistentState>& layers, std::vector<RuntimeRenderState>& states) const;
|
||||
void RefreshDynamicRenderStateFields(const RenderTimingSnapshot& timing, std::vector<RuntimeRenderState>& states) const;
|
||||
|
||||
RuntimeStore& mRuntimeStore;
|
||||
std::atomic<uint64_t> mFrameCounter{ 0 };
|
||||
|
||||
@@ -564,15 +564,60 @@ bool RuntimeStore::CopyShaderPackageForStoredLayer(const std::string& layerId, S
|
||||
return true;
|
||||
}
|
||||
|
||||
void RuntimeStore::GetShaderCompilerInputs(std::filesystem::path& repoRoot, std::filesystem::path& wrapperPath,
|
||||
std::filesystem::path& generatedGlslPath, std::filesystem::path& patchedGlslPath, unsigned& maxTemporalHistoryFrames) const
|
||||
ShaderCompilerInputs RuntimeStore::GetShaderCompilerInputs() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
repoRoot = mConfigStore.GetRepoRoot();
|
||||
wrapperPath = mConfigStore.GetWrapperPath();
|
||||
generatedGlslPath = mConfigStore.GetGeneratedGlslPath();
|
||||
patchedGlslPath = mConfigStore.GetPatchedGlslPath();
|
||||
maxTemporalHistoryFrames = mConfigStore.GetConfig().maxTemporalHistoryFrames;
|
||||
ShaderCompilerInputs inputs;
|
||||
inputs.repoRoot = mConfigStore.GetRepoRoot();
|
||||
inputs.wrapperPath = mConfigStore.GetWrapperPath();
|
||||
inputs.generatedGlslPath = mConfigStore.GetGeneratedGlslPath();
|
||||
inputs.patchedGlslPath = mConfigStore.GetPatchedGlslPath();
|
||||
inputs.maxTemporalHistoryFrames = mConfigStore.GetConfig().maxTemporalHistoryFrames;
|
||||
return inputs;
|
||||
}
|
||||
|
||||
RenderSnapshotReadModel RuntimeStore::BuildRenderSnapshotReadModel() const
|
||||
{
|
||||
RenderSnapshotReadModel model;
|
||||
model.signalStatus = mHealthTelemetry.GetSignalStatusSnapshot();
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
model.layers = mLayerStack.Layers();
|
||||
model.packagesById = mShaderCatalog.CaptureSnapshot().packagesById;
|
||||
model.timing.startTime = mStartTime;
|
||||
model.timing.startupRandom = mStartupRandom;
|
||||
return model;
|
||||
}
|
||||
|
||||
std::vector<RuntimeStore::LayerPersistentState> RuntimeStore::CopyLayerStates() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
return mLayerStack.Layers();
|
||||
}
|
||||
|
||||
RenderTimingSnapshot RuntimeStore::GetRenderTimingSnapshot() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
RenderTimingSnapshot snapshot;
|
||||
snapshot.startTime = mStartTime;
|
||||
snapshot.startupRandom = mStartupRandom;
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
RuntimeStatePresentationReadModel RuntimeStore::BuildRuntimeStatePresentationReadModel() const
|
||||
{
|
||||
RuntimeStatePresentationReadModel model;
|
||||
model.telemetry = mHealthTelemetry.GetSnapshot();
|
||||
std::lock_guard<std::mutex> lock(mMutex);
|
||||
model.config = mConfigStore.GetConfig();
|
||||
model.layerStack = mLayerStack;
|
||||
model.shaderCatalog = mShaderCatalog.CaptureSnapshot();
|
||||
model.packageStatuses = mShaderCatalog.PackageStatuses();
|
||||
model.stackPresetNames = GetStackPresetNamesLocked();
|
||||
model.serverPort = mServerPort;
|
||||
model.autoReloadEnabled = mAutoReloadEnabled;
|
||||
model.compileSucceeded = mCompileSucceeded;
|
||||
model.compileMessage = mCompileMessage;
|
||||
return model;
|
||||
}
|
||||
|
||||
void RuntimeStore::MarkRenderStateDirtyLocked()
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "RenderSnapshotBuilder.h"
|
||||
#include "RuntimeConfigStore.h"
|
||||
#include "RuntimeJson.h"
|
||||
#include "RuntimeStoreReadModels.h"
|
||||
#include "ShaderPackageCatalog.h"
|
||||
#include "ShaderTypes.h"
|
||||
|
||||
@@ -14,8 +15,6 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class RuntimeStatePresenter;
|
||||
|
||||
class RuntimeStore
|
||||
{
|
||||
public:
|
||||
@@ -70,19 +69,20 @@ public:
|
||||
|
||||
void SetCompileStatus(bool succeeded, const std::string& message);
|
||||
void ClearReloadRequest();
|
||||
bool CopyShaderPackageForStoredLayer(const std::string& layerId, ShaderPackage& shaderPackage, std::string& error) const;
|
||||
::ShaderCompilerInputs GetShaderCompilerInputs() const;
|
||||
::RenderSnapshotReadModel BuildRenderSnapshotReadModel() const;
|
||||
std::vector<LayerPersistentState> CopyLayerStates() const;
|
||||
::RenderTimingSnapshot GetRenderTimingSnapshot() const;
|
||||
::RuntimeStatePresentationReadModel BuildRuntimeStatePresentationReadModel() const;
|
||||
|
||||
private:
|
||||
friend class RenderSnapshotBuilder;
|
||||
friend class RuntimeStatePresenter;
|
||||
bool LoadPersistentState(std::string& error);
|
||||
bool SavePersistentState(std::string& error) const;
|
||||
bool ScanShaderPackages(std::string& error);
|
||||
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;
|
||||
std::vector<std::string> GetStackPresetNamesLocked() const;
|
||||
bool CopyShaderPackageForStoredLayer(const std::string& layerId, ShaderPackage& shaderPackage, std::string& error) const;
|
||||
void GetShaderCompilerInputs(std::filesystem::path& repoRoot, std::filesystem::path& wrapperPath,
|
||||
std::filesystem::path& generatedGlslPath, std::filesystem::path& patchedGlslPath, unsigned& maxTemporalHistoryFrames) const;
|
||||
void MarkRenderStateDirtyLocked();
|
||||
void MarkParameterStateDirtyLocked();
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include "HealthTelemetry.h"
|
||||
#include "LayerStackStore.h"
|
||||
#include "RuntimeConfigStore.h"
|
||||
#include "ShaderPackageCatalog.h"
|
||||
#include "ShaderTypes.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
struct ShaderCompilerInputs
|
||||
{
|
||||
std::filesystem::path repoRoot;
|
||||
std::filesystem::path wrapperPath;
|
||||
std::filesystem::path generatedGlslPath;
|
||||
std::filesystem::path patchedGlslPath;
|
||||
unsigned maxTemporalHistoryFrames = 0;
|
||||
};
|
||||
|
||||
struct RenderTimingSnapshot
|
||||
{
|
||||
std::chrono::steady_clock::time_point startTime;
|
||||
double startupRandom = 0.0;
|
||||
};
|
||||
|
||||
struct RenderSnapshotReadModel
|
||||
{
|
||||
std::vector<LayerStackStore::LayerPersistentState> layers;
|
||||
std::map<std::string, ShaderPackage> packagesById;
|
||||
HealthTelemetry::SignalStatusSnapshot signalStatus;
|
||||
RenderTimingSnapshot timing;
|
||||
};
|
||||
|
||||
struct RuntimeStatePresentationReadModel
|
||||
{
|
||||
RuntimeConfigStore::AppConfig config;
|
||||
HealthTelemetry::Snapshot telemetry;
|
||||
LayerStackStore layerStack;
|
||||
ShaderPackageCatalog::Snapshot shaderCatalog;
|
||||
std::vector<ShaderPackageStatus> packageStatuses;
|
||||
std::vector<std::string> stackPresetNames;
|
||||
unsigned short serverPort = 0;
|
||||
bool autoReloadEnabled = false;
|
||||
bool compileSucceeded = false;
|
||||
std::string compileMessage;
|
||||
};
|
||||
@@ -5,8 +5,8 @@
|
||||
#include <string>
|
||||
|
||||
// Phase 1 compatibility seam for status and timing reporting. HealthTelemetry
|
||||
// now owns the current operational status snapshot directly, so callers can
|
||||
// target it without flowing through RuntimeHost-owned backing fields.
|
||||
// owns the current operational status snapshot directly, so callers can report
|
||||
// health without sharing runtime-store state.
|
||||
class HealthTelemetry
|
||||
{
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user