Files
Aiden 6e600be112
All checks were successful
CI / React UI Build (push) Successful in 10s
CI / Native Windows Build And Tests (push) Successful in 2m26s
CI / Windows Release Package (push) Successful in 2m28s
Tests
2026-05-11 15:59:29 +10:00

197 lines
6.6 KiB
C++

#include "RuntimeSnapshotProvider.h"
#include "RuntimeEventDispatcher.h"
#include <windows.h>
#include <utility>
RuntimeSnapshotProvider::RuntimeSnapshotProvider(RenderSnapshotBuilder& renderSnapshotBuilder, RuntimeEventDispatcher& runtimeEventDispatcher) :
mRenderSnapshotBuilder(renderSnapshotBuilder),
mRuntimeEventDispatcher(runtimeEventDispatcher)
{
}
bool RuntimeSnapshotProvider::BuildLayerPassFragmentShaderSources(const std::string& layerId, std::vector<ShaderPassBuildSource>& passSources, std::string& error) const
{
try
{
return mRenderSnapshotBuilder.BuildLayerPassFragmentShaderSources(layerId, passSources, error);
}
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 mRenderSnapshotBuilder.GetMaxTemporalHistoryFrames();
}
RuntimeSnapshotVersions RuntimeSnapshotProvider::GetVersions() const
{
return mRenderSnapshotBuilder.GetVersions();
}
void RuntimeSnapshotProvider::AdvanceFrame()
{
mRenderSnapshotBuilder.AdvanceFrame();
}
RuntimeRenderStateSnapshot RuntimeSnapshotProvider::PublishRenderStateSnapshot(unsigned outputWidth, unsigned outputHeight) const
{
PublishRenderSnapshotPublishRequested(outputWidth, outputHeight, "publish-render-state-snapshot");
for (;;)
{
const RuntimeSnapshotVersions versionsBefore = GetVersions();
RuntimeRenderStateSnapshot publishedSnapshot;
if (TryGetPublishedRenderStateSnapshot(outputWidth, outputHeight, versionsBefore, publishedSnapshot))
{
PublishRenderSnapshotPublished(publishedSnapshot);
return publishedSnapshot;
}
RuntimeRenderStateSnapshot snapshot;
snapshot.outputWidth = outputWidth;
snapshot.outputHeight = outputHeight;
mRenderSnapshotBuilder.BuildLayerRenderStates(outputWidth, outputHeight, snapshot.states);
const RuntimeSnapshotVersions versionsAfter = GetVersions();
if (versionsBefore.renderStateVersion == versionsAfter.renderStateVersion &&
versionsBefore.parameterStateVersion == versionsAfter.parameterStateVersion)
{
snapshot.versions = versionsAfter;
StorePublishedRenderStateSnapshot(snapshot);
PublishRenderSnapshotPublished(snapshot);
return snapshot;
}
}
}
bool RuntimeSnapshotProvider::TryPublishRenderStateSnapshot(unsigned outputWidth, unsigned outputHeight, RuntimeRenderStateSnapshot& snapshot) const
{
PublishRenderSnapshotPublishRequested(outputWidth, outputHeight, "try-publish-render-state-snapshot");
const RuntimeSnapshotVersions versionsBefore = GetVersions();
if (TryGetPublishedRenderStateSnapshot(outputWidth, outputHeight, versionsBefore, snapshot))
{
PublishRenderSnapshotPublished(snapshot);
return true;
}
std::vector<RuntimeRenderState> states;
if (!mRenderSnapshotBuilder.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);
PublishRenderSnapshotPublished(snapshot);
return true;
}
bool RuntimeSnapshotProvider::TryRefreshPublishedSnapshotParameters(RuntimeRenderStateSnapshot& snapshot) const
{
const uint64_t expectedRenderStateVersion = snapshot.versions.renderStateVersion;
if (!mRenderSnapshotBuilder.TryRefreshLayerParameters(snapshot.states))
return false;
const RuntimeSnapshotVersions versions = GetVersions();
if (versions.renderStateVersion != expectedRenderStateVersion)
return false;
snapshot.versions = versions;
StorePublishedRenderStateSnapshot(snapshot);
PublishRenderSnapshotPublished(snapshot);
return true;
}
void RuntimeSnapshotProvider::RefreshDynamicRenderStateFields(std::vector<RuntimeRenderState>& states) const
{
mRenderSnapshotBuilder.RefreshDynamicRenderStateFields(states);
}
bool RuntimeSnapshotProvider::TryGetPublishedRenderStateSnapshot(unsigned outputWidth, unsigned outputHeight,
const RuntimeSnapshotVersions& versions, RuntimeRenderStateSnapshot& snapshot) const
{
std::lock_guard<std::mutex> 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<std::mutex> 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;
}
void RuntimeSnapshotProvider::PublishRenderSnapshotPublishRequested(unsigned outputWidth, unsigned outputHeight, const std::string& reason) const
{
try
{
RenderSnapshotPublishRequestedEvent event;
event.outputWidth = outputWidth;
event.outputHeight = outputHeight;
event.reason = reason;
if (!mRuntimeEventDispatcher.PublishPayload(event, "RuntimeSnapshotProvider"))
OutputDebugStringA("RenderSnapshotPublishRequested event publish failed.\n");
}
catch (...)
{
OutputDebugStringA("RenderSnapshotPublishRequested event publish threw.\n");
}
}
void RuntimeSnapshotProvider::PublishRenderSnapshotPublished(const RuntimeRenderStateSnapshot& snapshot) const
{
try
{
RenderSnapshotPublishedEvent event;
event.snapshotVersion = snapshot.versions.renderStateVersion;
event.structureVersion = snapshot.versions.renderStateVersion;
event.parameterVersion = snapshot.versions.parameterStateVersion;
event.outputWidth = snapshot.outputWidth;
event.outputHeight = snapshot.outputHeight;
event.layerCount = snapshot.states.size();
if (!mRuntimeEventDispatcher.PublishPayload(event, "RuntimeSnapshotProvider"))
OutputDebugStringA("RenderSnapshotPublished event publish failed.\n");
}
catch (...)
{
OutputDebugStringA("RenderSnapshotPublished event publish threw.\n");
}
}