123 lines
3.5 KiB
C++
123 lines
3.5 KiB
C++
#include "RuntimeLayerController.h"
|
|
|
|
#include "AppConfigProvider.h"
|
|
#include "../logging/Logger.h"
|
|
|
|
#include <filesystem>
|
|
|
|
namespace RenderCadenceCompositor
|
|
{
|
|
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();
|
|
}
|
|
|
|
std::string RuntimeLayerController::FirstRuntimeLayerId() const
|
|
{
|
|
std::lock_guard<std::mutex> lock(mRuntimeLayerMutex);
|
|
return mRuntimeLayerModel.FirstLayerId();
|
|
}
|
|
}
|