diff --git a/apps/RenderCadenceCompositor/render/runtime/RuntimeShaderParams.cpp b/apps/RenderCadenceCompositor/render/runtime/RuntimeShaderParams.cpp index dccbf46..622153a 100644 --- a/apps/RenderCadenceCompositor/render/runtime/RuntimeShaderParams.cpp +++ b/apps/RenderCadenceCompositor/render/runtime/RuntimeShaderParams.cpp @@ -112,8 +112,8 @@ std::vector BuildRuntimeShaderGlobalParamsStd140( case ShaderParameterType::Text: break; case ShaderParameterType::Trigger: - AppendStd140Int(buffer, 0); - AppendStd140Float(buffer, -1000000.0f); + AppendStd140Int(buffer, value.numberValues.empty() ? 0 : static_cast(value.numberValues[0])); + AppendStd140Float(buffer, value.numberValues.size() > 1 ? static_cast(value.numberValues[1]) : -1000000.0f); break; } } diff --git a/apps/RenderCadenceCompositor/runtime/RuntimeLayerModel.cpp b/apps/RenderCadenceCompositor/runtime/RuntimeLayerModel.cpp index 4684323..db86c1d 100644 --- a/apps/RenderCadenceCompositor/runtime/RuntimeLayerModel.cpp +++ b/apps/RenderCadenceCompositor/runtime/RuntimeLayerModel.cpp @@ -3,6 +3,7 @@ #include "RuntimeParameterUtils.h" #include +#include #include namespace RenderCadenceCompositor @@ -156,8 +157,18 @@ bool RuntimeLayerModel::UpdateParameter(const std::string& layerId, const std::s } ShaderParameterValue normalizedValue; - if (!NormalizeAndValidateParameterValue(*definition, value, normalizedValue, error)) + if (definition->type == ShaderParameterType::Trigger) + { + const auto currentIt = layer->parameterValues.find(parameterId); + const double previousCount = currentIt == layer->parameterValues.end() || currentIt->second.numberValues.empty() + ? 0.0 + : currentIt->second.numberValues.front(); + normalizedValue.numberValues = { previousCount + 1.0, RuntimeElapsedSeconds() }; + } + else if (!NormalizeAndValidateParameterValue(*definition, value, normalizedValue, error)) + { return false; + } layer->parameterValues[parameterId] = normalizedValue; if (layer->renderReady) @@ -360,4 +371,9 @@ RuntimeLayerReadModel RuntimeLayerModel::ToReadModel(const Layer& layer) readModel.parameterValues = layer.parameterValues; return readModel; } + +double RuntimeLayerModel::RuntimeElapsedSeconds() const +{ + return std::chrono::duration_cast>(std::chrono::steady_clock::now() - mStartTime).count(); +} } diff --git a/apps/RenderCadenceCompositor/runtime/RuntimeLayerModel.h b/apps/RenderCadenceCompositor/runtime/RuntimeLayerModel.h index 35dcca3..c03e7e2 100644 --- a/apps/RenderCadenceCompositor/runtime/RuntimeLayerModel.h +++ b/apps/RenderCadenceCompositor/runtime/RuntimeLayerModel.h @@ -4,6 +4,7 @@ #include "RuntimeShaderArtifact.h" #include "SupportedShaderCatalog.h" +#include #include #include #include @@ -91,8 +92,10 @@ private: static const ShaderParameterDefinition* FindParameterDefinition(const Layer& layer, const std::string& parameterId); std::string AllocateLayerId(); static RuntimeLayerReadModel ToReadModel(const Layer& layer); + double RuntimeElapsedSeconds() const; std::vector mLayers; uint64_t mNextLayerNumber = 1; + std::chrono::steady_clock::time_point mStartTime = std::chrono::steady_clock::now(); }; } diff --git a/tests/RenderCadenceCompositorRuntimeLayerModelTests.cpp b/tests/RenderCadenceCompositorRuntimeLayerModelTests.cpp index cdec60e..55f3c75 100644 --- a/tests/RenderCadenceCompositorRuntimeLayerModelTests.cpp +++ b/tests/RenderCadenceCompositorRuntimeLayerModelTests.cpp @@ -45,7 +45,8 @@ RenderCadenceCompositor::SupportedShaderCatalog MakeCatalog(std::filesystem::pat "category": "Tests", "entryPoint": "shadeVideo", "parameters": [ - { "id": "gain", "label": "Gain", "type": "float", "default": 0.5 } + { "id": "gain", "label": "Gain", "type": "float", "default": 0.5 }, + { "id": "drop", "label": "Drop", "type": "trigger" } ] })"); @@ -166,6 +167,15 @@ void TestLayerControlsUpdateDisplayAndRenderModels() Expect(model.UpdateParameter(firstLayerId, "gain", gainValue, error), "parameter value can be updated"); snapshot = model.Snapshot(); Expect(snapshot.displayLayers[1].parameterValues.at("gain").numberValues.front() == 0.75, "updated parameter value is visible"); + JsonValue dropPulse(true); + Expect(model.UpdateParameter(firstLayerId, "drop", dropPulse, error), "trigger parameter can be pulsed"); + snapshot = model.Snapshot(); + const std::vector firstTrigger = snapshot.displayLayers[1].parameterValues.at("drop").numberValues; + Expect(firstTrigger.size() == 2 && firstTrigger[0] == 1.0 && firstTrigger[1] >= 0.0, "trigger pulse increments count and records runtime time"); + Expect(model.UpdateParameter(firstLayerId, "drop", dropPulse, error), "trigger parameter can be pulsed again"); + snapshot = model.Snapshot(); + const std::vector secondTrigger = snapshot.displayLayers[1].parameterValues.at("drop").numberValues; + Expect(secondTrigger.size() == 2 && secondTrigger[0] == 2.0 && secondTrigger[1] >= firstTrigger[1], "second trigger pulse increments count again"); RuntimeShaderArtifact artifact; artifact.layerId = firstLayerId; diff --git a/tests/RenderCadenceCompositorRuntimeShaderParamsTests.cpp b/tests/RenderCadenceCompositorRuntimeShaderParamsTests.cpp index bbab7ad..6c53459 100644 --- a/tests/RenderCadenceCompositorRuntimeShaderParamsTests.cpp +++ b/tests/RenderCadenceCompositorRuntimeShaderParamsTests.cpp @@ -80,6 +80,15 @@ ShaderParameterDefinition EnumParam() definition.enumOptions = { { "soft", "Soft" }, { "hard", "Hard" } }; return definition; } + +ShaderParameterDefinition TriggerParam() +{ + ShaderParameterDefinition definition; + definition.id = "drop"; + definition.label = "Drop"; + definition.type = ShaderParameterType::Trigger; + return definition; +} } int main() @@ -90,6 +99,11 @@ int main() artifact.parameterDefinitions.push_back(ColorParam()); artifact.parameterDefinitions.push_back(BoolParam()); artifact.parameterDefinitions.push_back(EnumParam()); + artifact.parameterDefinitions.push_back(TriggerParam()); + + ShaderParameterValue triggerValue; + triggerValue.numberValues = { 3.0, 1.25 }; + artifact.parameterValues["drop"] = triggerValue; const std::vector buffer = BuildRuntimeShaderGlobalParamsStd140(artifact, 120, 1920, 1080); @@ -104,6 +118,8 @@ int main() Expect(ReadFloat(buffer, 92) == 1.0f, "color default alpha is packed"); Expect(ReadInt(buffer, 96) == 1, "bool default is packed as int"); Expect(ReadInt(buffer, 100) == 1, "enum default is packed as selected option index"); + Expect(ReadInt(buffer, 104) == 3, "trigger count is packed as int"); + Expect(ReadFloat(buffer, 108) == 1.25f, "trigger time is packed after trigger count"); std::cout << "RenderCadenceCompositorRuntimeShaderParams tests passed.\n"; return 0;