#include "RuntimeUpdateController.h" #include "RenderEngine.h" #include "RuntimeEventDispatcher.h" #include "RuntimeServices.h" #include "RuntimeStore.h" #include "ShaderBuildQueue.h" #include "VideoBackend.h" #include RuntimeUpdateController::RuntimeUpdateController( RuntimeStore& runtimeStore, RuntimeCoordinator& runtimeCoordinator, RuntimeEventDispatcher& runtimeEventDispatcher, RuntimeServices& runtimeServices, RenderEngine& renderEngine, ShaderBuildQueue& shaderBuildQueue, VideoBackend& videoBackend) : mRuntimeStore(runtimeStore), mRuntimeCoordinator(runtimeCoordinator), mRuntimeEventDispatcher(runtimeEventDispatcher), mRuntimeServices(runtimeServices), mRenderEngine(renderEngine), mShaderBuildQueue(shaderBuildQueue), mVideoBackend(videoBackend) { mRuntimeEventDispatcher.Subscribe( RuntimeEventType::RuntimeStateBroadcastRequested, [this](const RuntimeEvent& event) { HandleRuntimeStateBroadcastRequested(event); }); } bool RuntimeUpdateController::ApplyRuntimeCoordinatorResult(const RuntimeCoordinatorResult& result, std::string* error) { if (!result.accepted) { if (error) *error = result.errorMessage; return false; } if (result.compileStatusChanged) mRuntimeStore.SetCompileStatus(result.compileStatusSucceeded, result.compileStatusMessage); if (result.clearReloadRequest) mRuntimeStore.ClearReloadRequest(); mRuntimeCoordinator.ApplyCommittedStateMode(result.committedStateMode); if (result.clearTransientOscState) { mRenderEngine.ClearOscOverlayState(); mRuntimeServices.ClearOscState(); } mRenderEngine.ApplyRuntimeCoordinatorRenderReset(result.renderResetScope); if (result.shaderBuildRequested) RequestShaderBuild(); if (result.runtimeStateBroadcastRequired) BroadcastRuntimeState(); return true; } bool RuntimeUpdateController::ProcessRuntimeWork() { mRuntimeEventDispatcher.DispatchPending(); bool shaderBuildRequested = false; std::vector serviceResults; mRuntimeServices.ConsumeRuntimeCoordinatorResults(serviceResults); for (const RuntimeCoordinatorServiceResult& serviceResult : serviceResults) { shaderBuildRequested = shaderBuildRequested || serviceResult.result.shaderBuildRequested; ApplyRuntimeCoordinatorResult(serviceResult.result); if (serviceResult.failed) return false; } if (shaderBuildRequested) return true; const RenderEngine::PreparedShaderBuildApplyResult buildResult = mRenderEngine.TryApplyReadyShaderBuild( mShaderBuildQueue, mVideoBackend.InputFrameWidth(), mVideoBackend.InputFrameHeight(), mRuntimeCoordinator.PreserveFeedbackOnNextShaderBuild()); if (!buildResult.hadReadyBuild) return true; if (!buildResult.applied) { ApplyRuntimeCoordinatorResult(mRuntimeCoordinator.HandlePreparedShaderBuildFailure(buildResult.errorMessage)); return false; } ApplyRuntimeCoordinatorResult(mRuntimeCoordinator.HandlePreparedShaderBuildSuccess()); return true; } void RuntimeUpdateController::RequestShaderBuild() { mShaderBuildQueue.RequestBuild(mVideoBackend.InputFrameWidth(), mVideoBackend.InputFrameHeight()); } void RuntimeUpdateController::BroadcastRuntimeState() { RuntimeStateBroadcastRequestedEvent event; event.reason = "runtime-state-changed"; if (!mRuntimeEventDispatcher.PublishPayload(event, "RuntimeUpdateController")) { mRuntimeServices.BroadcastState(); return; } mRuntimeEventDispatcher.DispatchPending(); } void RuntimeUpdateController::HandleRuntimeStateBroadcastRequested(const RuntimeEvent& event) { (void)event; mRuntimeServices.BroadcastState(); }