#include "RuntimeSnapshotProvider.h" #include "ShaderCompiler.h" #include #include RuntimeSnapshotProvider::RuntimeSnapshotProvider(RuntimeStore& runtimeStore) : mRuntimeStore(runtimeStore) { } bool RuntimeSnapshotProvider::BuildLayerPassFragmentShaderSources(const std::string& layerId, std::vector& passSources, std::string& error) const { try { ShaderPackage shaderPackage; 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); ShaderCompiler compiler( repoRoot, wrapperPath, generatedGlslPath, patchedGlslPath, maxTemporalHistoryFrames); passSources.clear(); passSources.reserve(shaderPackage.passes.size()); for (const ShaderPassDefinition& pass : shaderPackage.passes) { ShaderPassBuildSource passSource; passSource.passId = pass.id; passSource.inputNames = pass.inputNames; passSource.outputName = pass.outputName; if (!compiler.BuildPassFragmentShaderSource(shaderPackage, pass, passSource.fragmentShaderSource, error)) return false; passSources.push_back(std::move(passSource)); } return true; } catch (const std::exception& exception) { error = std::string("RuntimeSnapshotProvider::BuildLayerPassFragmentShaderSources exception: ") + exception.what(); return false; } catch (...) { error = "RuntimeSnapshotProvider::BuildLayerPassFragmentShaderSources threw a non-standard exception."; return false; } } unsigned RuntimeSnapshotProvider::GetMaxTemporalHistoryFrames() const { return mRuntimeStore.GetConfiguredMaxTemporalHistoryFrames(); } RuntimeSnapshotVersions RuntimeSnapshotProvider::GetVersions() const { RuntimeSnapshotVersions versions; versions.renderStateVersion = mRuntimeStore.GetRenderStateVersion(); versions.parameterStateVersion = mRuntimeStore.GetParameterStateVersion(); return versions; } void RuntimeSnapshotProvider::AdvanceFrame() { mRuntimeStore.AdvanceFrameCounter(); } RuntimeRenderStateSnapshot RuntimeSnapshotProvider::PublishRenderStateSnapshot(unsigned outputWidth, unsigned outputHeight) const { for (;;) { const RuntimeSnapshotVersions versionsBefore = GetVersions(); RuntimeRenderStateSnapshot publishedSnapshot; if (TryGetPublishedRenderStateSnapshot(outputWidth, outputHeight, versionsBefore, publishedSnapshot)) return publishedSnapshot; RuntimeRenderStateSnapshot snapshot; snapshot.outputWidth = outputWidth; snapshot.outputHeight = outputHeight; mRuntimeStore.BuildLayerRenderStates(outputWidth, outputHeight, snapshot.states); const RuntimeSnapshotVersions versionsAfter = GetVersions(); if (versionsBefore.renderStateVersion == versionsAfter.renderStateVersion && versionsBefore.parameterStateVersion == versionsAfter.parameterStateVersion) { snapshot.versions = versionsAfter; StorePublishedRenderStateSnapshot(snapshot); return snapshot; } } } bool RuntimeSnapshotProvider::TryPublishRenderStateSnapshot(unsigned outputWidth, unsigned outputHeight, RuntimeRenderStateSnapshot& snapshot) const { const RuntimeSnapshotVersions versionsBefore = GetVersions(); if (TryGetPublishedRenderStateSnapshot(outputWidth, outputHeight, versionsBefore, snapshot)) return true; std::vector states; if (!mRuntimeStore.TryBuildLayerRenderStates(outputWidth, outputHeight, states)) return false; const RuntimeSnapshotVersions versionsAfter = GetVersions(); if (versionsBefore.renderStateVersion != versionsAfter.renderStateVersion || versionsBefore.parameterStateVersion != versionsAfter.parameterStateVersion) { return false; } snapshot.outputWidth = outputWidth; snapshot.outputHeight = outputHeight; snapshot.versions = versionsAfter; snapshot.states = std::move(states); StorePublishedRenderStateSnapshot(snapshot); return true; } bool RuntimeSnapshotProvider::TryRefreshPublishedSnapshotParameters(RuntimeRenderStateSnapshot& snapshot) const { const uint64_t expectedRenderStateVersion = snapshot.versions.renderStateVersion; if (!mRuntimeStore.TryRefreshLayerParameters(snapshot.states)) return false; const RuntimeSnapshotVersions versions = GetVersions(); if (versions.renderStateVersion != expectedRenderStateVersion) return false; snapshot.versions = versions; StorePublishedRenderStateSnapshot(snapshot); return true; } void RuntimeSnapshotProvider::RefreshDynamicRenderStateFields(std::vector& states) const { mRuntimeStore.RefreshDynamicRenderStateFields(states); } bool RuntimeSnapshotProvider::TryGetPublishedRenderStateSnapshot(unsigned outputWidth, unsigned outputHeight, const RuntimeSnapshotVersions& versions, RuntimeRenderStateSnapshot& snapshot) const { std::lock_guard lock(mPublishedSnapshotMutex); if (!mHasPublishedRenderStateSnapshot || !SnapshotMatches(mPublishedRenderStateSnapshot, outputWidth, outputHeight, versions)) { return false; } snapshot = mPublishedRenderStateSnapshot; return true; } void RuntimeSnapshotProvider::StorePublishedRenderStateSnapshot(const RuntimeRenderStateSnapshot& snapshot) const { std::lock_guard lock(mPublishedSnapshotMutex); mPublishedRenderStateSnapshot = snapshot; mHasPublishedRenderStateSnapshot = true; } bool RuntimeSnapshotProvider::SnapshotMatches(const RuntimeRenderStateSnapshot& snapshot, unsigned outputWidth, unsigned outputHeight, const RuntimeSnapshotVersions& versions) { return snapshot.outputWidth == outputWidth && snapshot.outputHeight == outputHeight && snapshot.versions.renderStateVersion == versions.renderStateVersion && snapshot.versions.parameterStateVersion == versions.parameterStateVersion; }