197 lines
6.6 KiB
C++
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");
|
|
}
|
|
}
|