input buffer
This commit is contained in:
@@ -1,11 +1,7 @@
|
||||
#include "RuntimeLayerController.h"
|
||||
|
||||
#include "AppConfigProvider.h"
|
||||
#include "RuntimeJson.h"
|
||||
#include "../logging/Logger.h"
|
||||
|
||||
#include <filesystem>
|
||||
|
||||
namespace RenderCadenceCompositor
|
||||
{
|
||||
RuntimeLayerController::RuntimeLayerController(RenderLayerPublisher publisher) :
|
||||
@@ -48,137 +44,6 @@ void RuntimeLayerController::Stop()
|
||||
StopAllRuntimeShaderBuilds();
|
||||
}
|
||||
|
||||
ControlActionResult RuntimeLayerController::HandleAddLayer(const std::string& body)
|
||||
{
|
||||
CleanupRetiredShaderBuilds();
|
||||
|
||||
std::string shaderId;
|
||||
std::string error;
|
||||
if (!ExtractStringField(body, "shaderId", shaderId, error))
|
||||
return { false, error };
|
||||
|
||||
std::string layerId;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
if (!mRuntimeLayerModel.AddLayer(mShaderCatalog, shaderId, layerId, error))
|
||||
return { false, error };
|
||||
}
|
||||
|
||||
Log("runtime-shader", "Layer added: " + layerId + " shader=" + shaderId);
|
||||
StartLayerShaderBuild(layerId, shaderId);
|
||||
return { true, std::string() };
|
||||
}
|
||||
|
||||
ControlActionResult RuntimeLayerController::HandleRemoveLayer(const std::string& body)
|
||||
{
|
||||
CleanupRetiredShaderBuilds();
|
||||
|
||||
std::string layerId;
|
||||
std::string error;
|
||||
if (!ExtractStringField(body, "layerId", layerId, error))
|
||||
return { false, error };
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
if (!mRuntimeLayerModel.RemoveLayer(layerId, error))
|
||||
return { false, error };
|
||||
}
|
||||
|
||||
Log("runtime-shader", "Layer removed: " + layerId);
|
||||
RetireLayerShaderBuild(layerId);
|
||||
PublishRuntimeRenderLayers();
|
||||
return { true, std::string() };
|
||||
}
|
||||
|
||||
ControlActionResult RuntimeLayerController::HandleControlCommand(const RuntimeControlCommand& command)
|
||||
{
|
||||
CleanupRetiredShaderBuilds();
|
||||
|
||||
std::string error;
|
||||
switch (command.type)
|
||||
{
|
||||
case RuntimeControlCommandType::AddLayer:
|
||||
{
|
||||
std::string layerId;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
if (!mRuntimeLayerModel.AddLayer(mShaderCatalog, command.shaderId, layerId, error))
|
||||
return { false, error };
|
||||
}
|
||||
Log("runtime-shader", "Layer added: " + layerId + " shader=" + command.shaderId);
|
||||
StartLayerShaderBuild(layerId, command.shaderId);
|
||||
return { true, std::string() };
|
||||
}
|
||||
case RuntimeControlCommandType::RemoveLayer:
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
if (!mRuntimeLayerModel.RemoveLayer(command.layerId, error))
|
||||
return { false, error };
|
||||
}
|
||||
Log("runtime-shader", "Layer removed: " + command.layerId);
|
||||
RetireLayerShaderBuild(command.layerId);
|
||||
PublishRuntimeRenderLayers();
|
||||
return { true, std::string() };
|
||||
}
|
||||
case RuntimeControlCommandType::ReorderLayer:
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
if (!mRuntimeLayerModel.ReorderLayer(command.layerId, command.targetIndex, error))
|
||||
return { false, error };
|
||||
}
|
||||
PublishRuntimeRenderLayers();
|
||||
return { true, std::string() };
|
||||
}
|
||||
case RuntimeControlCommandType::SetLayerBypass:
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
if (!mRuntimeLayerModel.SetLayerBypass(command.layerId, command.bypass, error))
|
||||
return { false, error };
|
||||
}
|
||||
PublishRuntimeRenderLayers();
|
||||
return { true, std::string() };
|
||||
}
|
||||
case RuntimeControlCommandType::SetLayerShader:
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
if (!mRuntimeLayerModel.SetLayerShader(mShaderCatalog, command.layerId, command.shaderId, error))
|
||||
return { false, error };
|
||||
}
|
||||
Log("runtime-shader", "Layer shader changed: " + command.layerId + " shader=" + command.shaderId);
|
||||
StartLayerShaderBuild(command.layerId, command.shaderId);
|
||||
return { true, std::string() };
|
||||
}
|
||||
case RuntimeControlCommandType::UpdateLayerParameter:
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
if (!mRuntimeLayerModel.UpdateParameter(command.layerId, command.parameterId, command.value, error))
|
||||
return { false, error };
|
||||
}
|
||||
PublishRuntimeRenderLayers();
|
||||
return { true, std::string() };
|
||||
}
|
||||
case RuntimeControlCommandType::ResetLayerParameters:
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
if (!mRuntimeLayerModel.ResetParameters(command.layerId, error))
|
||||
return { false, error };
|
||||
}
|
||||
PublishRuntimeRenderLayers();
|
||||
return { true, std::string() };
|
||||
}
|
||||
case RuntimeControlCommandType::Unsupported:
|
||||
break;
|
||||
}
|
||||
|
||||
return { false, "Unsupported runtime control command." };
|
||||
}
|
||||
|
||||
RuntimeLayerModelSnapshot RuntimeLayerController::Snapshot(const CadenceTelemetrySnapshot& telemetry) const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
@@ -191,113 +56,6 @@ RuntimeLayerModelSnapshot RuntimeLayerController::Snapshot(const CadenceTelemetr
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
void RuntimeLayerController::LoadSupportedShaderCatalog(const std::string& shaderLibrary, unsigned maxTemporalHistoryFrames)
|
||||
{
|
||||
const std::filesystem::path shaderRoot = FindRepoPath(shaderLibrary);
|
||||
std::string error;
|
||||
if (!mShaderCatalog.Load(shaderRoot, maxTemporalHistoryFrames, error))
|
||||
{
|
||||
LogWarning("runtime-shader", "Supported shader catalog is empty: " + error);
|
||||
return;
|
||||
}
|
||||
|
||||
Log("runtime-shader", "Supported shader catalog loaded with " + std::to_string(mShaderCatalog.Shaders().size()) + " shader(s).");
|
||||
}
|
||||
|
||||
void RuntimeLayerController::InitializeLayerModel(std::string& runtimeShaderId)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
std::string error;
|
||||
if (!mRuntimeLayerModel.InitializeSingleLayer(mShaderCatalog, runtimeShaderId, error))
|
||||
{
|
||||
LogWarning("runtime-shader", error + " Runtime shader build disabled.");
|
||||
runtimeShaderId.clear();
|
||||
mRuntimeLayerModel.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeLayerController::StartLayerShaderBuild(const std::string& layerId, const std::string& shaderId)
|
||||
{
|
||||
CleanupRetiredShaderBuilds();
|
||||
RetireLayerShaderBuild(layerId);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
std::string error;
|
||||
mRuntimeLayerModel.MarkBuildStarted(layerId, "Runtime Slang build started for shader '" + shaderId + "'.", error);
|
||||
}
|
||||
|
||||
auto bridge = std::make_unique<RuntimeShaderBridge>();
|
||||
RuntimeShaderBridge* bridgePtr = bridge.get();
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mShaderBuildMutex);
|
||||
mShaderBuilds[layerId] = std::move(bridge);
|
||||
}
|
||||
|
||||
bridgePtr->Start(
|
||||
layerId,
|
||||
shaderId,
|
||||
[this](const RuntimeShaderArtifact& artifact) {
|
||||
if (MarkRuntimeBuildReady(artifact))
|
||||
PublishRuntimeRenderLayers();
|
||||
},
|
||||
[this, layerId](const std::string& message) {
|
||||
MarkRuntimeBuildFailedForLayer(layerId, message);
|
||||
LogError("runtime-shader", "Runtime Slang build failed: " + message);
|
||||
});
|
||||
}
|
||||
|
||||
void RuntimeLayerController::RetireLayerShaderBuild(const std::string& layerId)
|
||||
{
|
||||
std::unique_ptr<RuntimeShaderBridge> bridge;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mShaderBuildMutex);
|
||||
auto bridgeIt = mShaderBuilds.find(layerId);
|
||||
if (bridgeIt == mShaderBuilds.end())
|
||||
return;
|
||||
bridge = std::move(bridgeIt->second);
|
||||
mShaderBuilds.erase(bridgeIt);
|
||||
bridge->RequestStop();
|
||||
mRetiredShaderBuilds.push_back(std::move(bridge));
|
||||
}
|
||||
}
|
||||
|
||||
void RuntimeLayerController::CleanupRetiredShaderBuilds()
|
||||
{
|
||||
std::vector<std::unique_ptr<RuntimeShaderBridge>> readyToStop;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mShaderBuildMutex);
|
||||
for (auto it = mRetiredShaderBuilds.begin(); it != mRetiredShaderBuilds.end();)
|
||||
{
|
||||
if ((*it)->CanStopWithoutWaiting())
|
||||
{
|
||||
readyToStop.push_back(std::move(*it));
|
||||
it = mRetiredShaderBuilds.erase(it);
|
||||
continue;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
for (std::unique_ptr<RuntimeShaderBridge>& bridge : readyToStop)
|
||||
bridge->Stop();
|
||||
}
|
||||
|
||||
void RuntimeLayerController::StopAllRuntimeShaderBuilds()
|
||||
{
|
||||
std::map<std::string, std::unique_ptr<RuntimeShaderBridge>> builds;
|
||||
std::vector<std::unique_ptr<RuntimeShaderBridge>> retiredBuilds;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mShaderBuildMutex);
|
||||
builds.swap(mShaderBuilds);
|
||||
retiredBuilds.swap(mRetiredShaderBuilds);
|
||||
}
|
||||
for (auto& entry : builds)
|
||||
entry.second->Stop();
|
||||
for (auto& bridge : retiredBuilds)
|
||||
bridge->Stop();
|
||||
}
|
||||
|
||||
void RuntimeLayerController::PublishRuntimeRenderLayers()
|
||||
{
|
||||
if (!mPublisher)
|
||||
@@ -331,31 +89,4 @@ void RuntimeLayerController::MarkRuntimeBuildFailedForLayer(const std::string& l
|
||||
LogWarning("runtime-shader", error);
|
||||
}
|
||||
|
||||
std::string RuntimeLayerController::FirstRuntimeLayerId() const
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
||||
return mRuntimeLayerModel.FirstLayerId();
|
||||
}
|
||||
|
||||
bool RuntimeLayerController::ExtractStringField(const std::string& body, const char* fieldName, std::string& value, std::string& error)
|
||||
{
|
||||
JsonValue root;
|
||||
std::string parseError;
|
||||
if (!ParseJson(body.empty() ? "{}" : body, root, parseError) || !root.isObject())
|
||||
{
|
||||
error = parseError.empty() ? "Request body must be a JSON object." : parseError;
|
||||
return false;
|
||||
}
|
||||
|
||||
const JsonValue* field = root.find(fieldName);
|
||||
if (!field || !field->isString() || field->asString().empty())
|
||||
{
|
||||
error = std::string("Request field '") + fieldName + "' must be a non-empty string.";
|
||||
return false;
|
||||
}
|
||||
|
||||
value = field->asString();
|
||||
error.clear();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user