dispatch event intergration
All checks were successful
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m28s
CI / Windows Release Package (push) Successful in 2m24s

This commit is contained in:
Aiden
2026-05-11 15:42:14 +10:00
parent ccfc0237fd
commit a9b08f7f27
16 changed files with 785 additions and 59 deletions

View File

@@ -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;
}