dispatch event intergration
This commit is contained in:
@@ -7,8 +7,26 @@
|
||||
#include "ShaderBuildQueue.h"
|
||||
#include "VideoBackend.h"
|
||||
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
namespace
|
||||
{
|
||||
RuntimeCoordinatorRenderResetScope ToRuntimeCoordinatorRenderResetScope(RuntimeEventRenderResetScope scope)
|
||||
{
|
||||
switch (scope)
|
||||
{
|
||||
case RuntimeEventRenderResetScope::TemporalHistoryOnly:
|
||||
return RuntimeCoordinatorRenderResetScope::TemporalHistoryOnly;
|
||||
case RuntimeEventRenderResetScope::TemporalHistoryAndFeedback:
|
||||
return RuntimeCoordinatorRenderResetScope::TemporalHistoryAndFeedback;
|
||||
case RuntimeEventRenderResetScope::None:
|
||||
default:
|
||||
return RuntimeCoordinatorRenderResetScope::None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RuntimeUpdateController::RuntimeUpdateController(
|
||||
RuntimeStore& runtimeStore,
|
||||
RuntimeCoordinator& runtimeCoordinator,
|
||||
@@ -28,6 +46,21 @@ RuntimeUpdateController::RuntimeUpdateController(
|
||||
mRuntimeEventDispatcher.Subscribe(
|
||||
RuntimeEventType::RuntimeStateBroadcastRequested,
|
||||
[this](const RuntimeEvent& event) { HandleRuntimeStateBroadcastRequested(event); });
|
||||
mRuntimeEventDispatcher.Subscribe(
|
||||
RuntimeEventType::ShaderBuildRequested,
|
||||
[this](const RuntimeEvent& event) { HandleShaderBuildRequested(event); });
|
||||
mRuntimeEventDispatcher.Subscribe(
|
||||
RuntimeEventType::ShaderBuildPrepared,
|
||||
[this](const RuntimeEvent& event) { HandleShaderBuildPrepared(event); });
|
||||
mRuntimeEventDispatcher.Subscribe(
|
||||
RuntimeEventType::ShaderBuildFailed,
|
||||
[this](const RuntimeEvent& event) { HandleShaderBuildFailed(event); });
|
||||
mRuntimeEventDispatcher.Subscribe(
|
||||
RuntimeEventType::CompileStatusChanged,
|
||||
[this](const RuntimeEvent& event) { HandleCompileStatusChanged(event); });
|
||||
mRuntimeEventDispatcher.Subscribe(
|
||||
RuntimeEventType::RenderResetRequested,
|
||||
[this](const RuntimeEvent& event) { HandleRenderResetRequested(event); });
|
||||
}
|
||||
|
||||
bool RuntimeUpdateController::ApplyRuntimeCoordinatorResult(const RuntimeCoordinatorResult& result, std::string* error)
|
||||
@@ -40,7 +73,10 @@ bool RuntimeUpdateController::ApplyRuntimeCoordinatorResult(const RuntimeCoordin
|
||||
}
|
||||
|
||||
if (result.compileStatusChanged)
|
||||
{
|
||||
mRuntimeStore.SetCompileStatus(result.compileStatusSucceeded, result.compileStatusMessage);
|
||||
++mPendingCoordinatorCompileStatusEvents;
|
||||
}
|
||||
|
||||
if (result.clearReloadRequest)
|
||||
mRuntimeStore.ClearReloadRequest();
|
||||
@@ -54,9 +90,14 @@ bool RuntimeUpdateController::ApplyRuntimeCoordinatorResult(const RuntimeCoordin
|
||||
}
|
||||
|
||||
mRenderEngine.ApplyRuntimeCoordinatorRenderReset(result.renderResetScope);
|
||||
if (result.renderResetScope != RuntimeCoordinatorRenderResetScope::None)
|
||||
++mPendingCoordinatorRenderResetEvents;
|
||||
|
||||
if (result.shaderBuildRequested)
|
||||
{
|
||||
RequestShaderBuild();
|
||||
++mPendingCoordinatorShaderBuildEvents;
|
||||
}
|
||||
|
||||
if (result.runtimeStateBroadcastRequired)
|
||||
BroadcastRuntimeState();
|
||||
@@ -66,8 +107,6 @@ bool RuntimeUpdateController::ApplyRuntimeCoordinatorResult(const RuntimeCoordin
|
||||
|
||||
bool RuntimeUpdateController::ProcessRuntimeWork()
|
||||
{
|
||||
mRuntimeEventDispatcher.DispatchPending();
|
||||
|
||||
bool shaderBuildRequested = false;
|
||||
std::vector<RuntimeCoordinatorServiceResult> serviceResults;
|
||||
mRuntimeServices.ConsumeRuntimeCoordinatorResults(serviceResults);
|
||||
@@ -82,22 +121,9 @@ bool RuntimeUpdateController::ProcessRuntimeWork()
|
||||
if (shaderBuildRequested)
|
||||
return true;
|
||||
|
||||
const RenderEngine::PreparedShaderBuildApplyResult buildResult = mRenderEngine.TryApplyReadyShaderBuild(
|
||||
mShaderBuildQueue,
|
||||
mVideoBackend.InputFrameWidth(),
|
||||
mVideoBackend.InputFrameHeight(),
|
||||
mRuntimeCoordinator.PreserveFeedbackOnNextShaderBuild());
|
||||
if (!buildResult.hadReadyBuild)
|
||||
return true;
|
||||
DispatchRuntimeEvents();
|
||||
|
||||
if (!buildResult.applied)
|
||||
{
|
||||
ApplyRuntimeCoordinatorResult(mRuntimeCoordinator.HandlePreparedShaderBuildFailure(buildResult.errorMessage));
|
||||
return false;
|
||||
}
|
||||
|
||||
ApplyRuntimeCoordinatorResult(mRuntimeCoordinator.HandlePreparedShaderBuildSuccess());
|
||||
return true;
|
||||
return ConsumeReadyShaderBuild(0, true, true);
|
||||
}
|
||||
|
||||
void RuntimeUpdateController::RequestShaderBuild()
|
||||
@@ -115,11 +141,188 @@ void RuntimeUpdateController::BroadcastRuntimeState()
|
||||
return;
|
||||
}
|
||||
|
||||
mRuntimeEventDispatcher.DispatchPending();
|
||||
DispatchRuntimeEvents();
|
||||
}
|
||||
|
||||
void RuntimeUpdateController::HandleRuntimeStateBroadcastRequested(const RuntimeEvent& event)
|
||||
{
|
||||
(void)event;
|
||||
if (event.source == "ControlServices")
|
||||
return;
|
||||
|
||||
mRuntimeServices.BroadcastState();
|
||||
}
|
||||
|
||||
void RuntimeUpdateController::HandleShaderBuildRequested(const RuntimeEvent& event)
|
||||
{
|
||||
const ShaderBuildEvent* payload = std::get_if<ShaderBuildEvent>(&event.payload);
|
||||
if (!payload || payload->phase != RuntimeEventShaderBuildPhase::Requested)
|
||||
return;
|
||||
if (ShouldSuppressCoordinatorFollowUp(event, mPendingCoordinatorShaderBuildEvents))
|
||||
return;
|
||||
|
||||
RequestShaderBuild();
|
||||
}
|
||||
|
||||
void RuntimeUpdateController::HandleShaderBuildPrepared(const RuntimeEvent& event)
|
||||
{
|
||||
const ShaderBuildEvent* payload = std::get_if<ShaderBuildEvent>(&event.payload);
|
||||
if (!payload || payload->phase != RuntimeEventShaderBuildPhase::Prepared)
|
||||
return;
|
||||
|
||||
ConsumeReadyShaderBuild(payload->generation, false, true);
|
||||
}
|
||||
|
||||
void RuntimeUpdateController::HandleShaderBuildFailed(const RuntimeEvent& event)
|
||||
{
|
||||
const ShaderBuildEvent* payload = std::get_if<ShaderBuildEvent>(&event.payload);
|
||||
if (!payload || payload->phase != RuntimeEventShaderBuildPhase::Failed)
|
||||
return;
|
||||
|
||||
ConsumeReadyShaderBuild(payload->generation, false, false);
|
||||
}
|
||||
|
||||
void RuntimeUpdateController::HandleCompileStatusChanged(const RuntimeEvent& event)
|
||||
{
|
||||
const CompileStatusChangedEvent* payload = std::get_if<CompileStatusChangedEvent>(&event.payload);
|
||||
if (!payload)
|
||||
return;
|
||||
if (ShouldSuppressCoordinatorFollowUp(event, mPendingCoordinatorCompileStatusEvents))
|
||||
return;
|
||||
|
||||
mRuntimeStore.SetCompileStatus(payload->succeeded, payload->message);
|
||||
}
|
||||
|
||||
void RuntimeUpdateController::HandleRenderResetRequested(const RuntimeEvent& event)
|
||||
{
|
||||
const RenderResetEvent* payload = std::get_if<RenderResetEvent>(&event.payload);
|
||||
if (!payload || payload->applied)
|
||||
return;
|
||||
if (ShouldSuppressCoordinatorFollowUp(event, mPendingCoordinatorRenderResetEvents))
|
||||
return;
|
||||
|
||||
mRenderEngine.ApplyRuntimeCoordinatorRenderReset(ToRuntimeCoordinatorRenderResetScope(payload->scope));
|
||||
}
|
||||
|
||||
bool RuntimeUpdateController::ConsumeReadyShaderBuild(uint64_t expectedGeneration, bool publishPreparedEvent, bool publishFailureEvent)
|
||||
{
|
||||
PreparedShaderBuild readyBuild;
|
||||
const bool consumed = expectedGeneration == 0
|
||||
? mShaderBuildQueue.TryConsumeReadyBuild(readyBuild)
|
||||
: mShaderBuildQueue.TryConsumeReadyBuild(expectedGeneration, readyBuild);
|
||||
if (!consumed)
|
||||
return true;
|
||||
|
||||
const unsigned inputWidth = mVideoBackend.InputFrameWidth();
|
||||
const unsigned inputHeight = mVideoBackend.InputFrameHeight();
|
||||
if (!readyBuild.succeeded)
|
||||
{
|
||||
if (publishFailureEvent)
|
||||
{
|
||||
PublishShaderBuildLifecycleEvent(
|
||||
RuntimeEventShaderBuildPhase::Failed,
|
||||
readyBuild.generation,
|
||||
inputWidth,
|
||||
inputHeight,
|
||||
false,
|
||||
readyBuild.message);
|
||||
DispatchRuntimeEvents();
|
||||
}
|
||||
ApplyRuntimeCoordinatorResult(mRuntimeCoordinator.HandlePreparedShaderBuildFailure(readyBuild.message));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (publishPreparedEvent)
|
||||
{
|
||||
PublishShaderBuildLifecycleEvent(
|
||||
RuntimeEventShaderBuildPhase::Prepared,
|
||||
readyBuild.generation,
|
||||
inputWidth,
|
||||
inputHeight,
|
||||
true,
|
||||
readyBuild.message);
|
||||
DispatchRuntimeEvents();
|
||||
}
|
||||
|
||||
char compilerErrorMessage[1024] = {};
|
||||
if (!mRenderEngine.ApplyPreparedShaderBuild(
|
||||
readyBuild,
|
||||
inputWidth,
|
||||
inputHeight,
|
||||
mRuntimeCoordinator.PreserveFeedbackOnNextShaderBuild(),
|
||||
sizeof(compilerErrorMessage),
|
||||
compilerErrorMessage))
|
||||
{
|
||||
const std::string errorMessage = compilerErrorMessage;
|
||||
if (publishFailureEvent)
|
||||
{
|
||||
PublishShaderBuildLifecycleEvent(
|
||||
RuntimeEventShaderBuildPhase::Failed,
|
||||
readyBuild.generation,
|
||||
inputWidth,
|
||||
inputHeight,
|
||||
false,
|
||||
errorMessage);
|
||||
DispatchRuntimeEvents();
|
||||
}
|
||||
ApplyRuntimeCoordinatorResult(mRuntimeCoordinator.HandlePreparedShaderBuildFailure(errorMessage));
|
||||
return false;
|
||||
}
|
||||
|
||||
PublishShaderBuildLifecycleEvent(
|
||||
RuntimeEventShaderBuildPhase::Applied,
|
||||
readyBuild.generation,
|
||||
inputWidth,
|
||||
inputHeight,
|
||||
true,
|
||||
"Shader layers applied successfully.");
|
||||
ApplyRuntimeCoordinatorResult(mRuntimeCoordinator.HandlePreparedShaderBuildSuccess());
|
||||
return true;
|
||||
}
|
||||
|
||||
void RuntimeUpdateController::PublishShaderBuildLifecycleEvent(
|
||||
RuntimeEventShaderBuildPhase phase,
|
||||
uint64_t generation,
|
||||
unsigned inputWidth,
|
||||
unsigned inputHeight,
|
||||
bool succeeded,
|
||||
const std::string& message)
|
||||
{
|
||||
ShaderBuildEvent event;
|
||||
event.phase = phase;
|
||||
event.generation = generation;
|
||||
event.inputWidth = inputWidth;
|
||||
event.inputHeight = inputHeight;
|
||||
event.preserveFeedbackState = mRuntimeCoordinator.PreserveFeedbackOnNextShaderBuild();
|
||||
event.succeeded = succeeded;
|
||||
event.message = message;
|
||||
mRuntimeEventDispatcher.PublishPayload(event, "RuntimeUpdateController");
|
||||
}
|
||||
|
||||
bool RuntimeUpdateController::ShouldSuppressCoordinatorFollowUp(const RuntimeEvent& event, std::size_t& pendingSuppressions)
|
||||
{
|
||||
if (event.source != "RuntimeCoordinator")
|
||||
return false;
|
||||
|
||||
if (pendingSuppressions > 0)
|
||||
--pendingSuppressions;
|
||||
return true;
|
||||
}
|
||||
|
||||
RuntimeEventDispatchResult RuntimeUpdateController::DispatchRuntimeEvents(std::size_t maxEvents)
|
||||
{
|
||||
RuntimeEventDispatchResult result = mRuntimeEventDispatcher.DispatchPending(maxEvents);
|
||||
const RuntimeEventQueueMetrics queueMetrics = mRuntimeEventDispatcher.GetQueueMetrics();
|
||||
HealthTelemetry& telemetry = mRuntimeStore.GetHealthTelemetry();
|
||||
telemetry.TryRecordRuntimeEventDispatchStats(
|
||||
result.dispatchedEvents,
|
||||
result.handlerInvocations,
|
||||
result.handlerFailures,
|
||||
result.dispatchDurationMilliseconds);
|
||||
telemetry.TryRecordRuntimeEventQueueMetrics(
|
||||
"runtime-events",
|
||||
queueMetrics.depth,
|
||||
queueMetrics.capacity,
|
||||
static_cast<uint64_t>(queueMetrics.droppedCount),
|
||||
queueMetrics.oldestEventAgeMilliseconds);
|
||||
return result;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user