Phase 1 clean-up and separation of concerns
All checks were successful
CI / React UI Build (push) Successful in 10s
CI / Native Windows Build And Tests (push) Successful in 2m34s
CI / Windows Release Package (push) Successful in 2m42s

This commit is contained in:
Aiden
2026-05-10 23:21:13 +10:00
parent 3629227aa9
commit 739231d5a1
24 changed files with 1043 additions and 449 deletions

View File

@@ -34,6 +34,8 @@ set(APP_SOURCES
"${APP_DIR}/videoio/decklink/DeckLinkAPI_i.c" "${APP_DIR}/videoio/decklink/DeckLinkAPI_i.c"
"${APP_DIR}/control/ControlServer.cpp" "${APP_DIR}/control/ControlServer.cpp"
"${APP_DIR}/control/ControlServer.h" "${APP_DIR}/control/ControlServer.h"
"${APP_DIR}/control/ControlServices.cpp"
"${APP_DIR}/control/ControlServices.h"
"${APP_DIR}/control/OscServer.cpp" "${APP_DIR}/control/OscServer.cpp"
"${APP_DIR}/control/OscServer.h" "${APP_DIR}/control/OscServer.h"
"${APP_DIR}/control/RuntimeControlBridge.cpp" "${APP_DIR}/control/RuntimeControlBridge.cpp"
@@ -98,6 +100,8 @@ set(APP_SOURCES
"${APP_DIR}/resource.h" "${APP_DIR}/resource.h"
"${APP_DIR}/runtime/RuntimeHost.cpp" "${APP_DIR}/runtime/RuntimeHost.cpp"
"${APP_DIR}/runtime/RuntimeHost.h" "${APP_DIR}/runtime/RuntimeHost.h"
"${APP_DIR}/runtime/HealthTelemetry.cpp"
"${APP_DIR}/runtime/HealthTelemetry.h"
"${APP_DIR}/runtime/RuntimeSnapshotProvider.cpp" "${APP_DIR}/runtime/RuntimeSnapshotProvider.cpp"
"${APP_DIR}/runtime/RuntimeSnapshotProvider.h" "${APP_DIR}/runtime/RuntimeSnapshotProvider.h"
"${APP_DIR}/runtime/RuntimeClock.cpp" "${APP_DIR}/runtime/RuntimeClock.cpp"

View File

@@ -89,7 +89,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;control;gl;gl\pipeline;gl\renderer;gl\shader;videoio;videoio\decklink;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.;control;gl;gl\pipeline;gl\renderer;gl\shader;platform;runtime;shader;videoio;videoio\decklink;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -99,7 +99,7 @@
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>opengl32.lib;Glu32.lib;Windowscodecs.lib;Ole32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;Glu32.lib;Ws2_32.lib;Crypt32.lib;Advapi32.lib;Gdiplus.lib;Ole32.lib;Windowscodecs.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX86</TargetMachine> <TargetMachine>MachineX86</TargetMachine>
@@ -111,7 +111,7 @@
</Midl> </Midl>
<ClCompile> <ClCompile>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;control;gl;gl\pipeline;gl\renderer;gl\shader;videoio;videoio\decklink;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.;control;gl;gl\pipeline;gl\renderer;gl\shader;platform;runtime;shader;videoio;videoio\decklink;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks> <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
@@ -121,7 +121,7 @@
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>opengl32.lib;Glu32.lib;Windowscodecs.lib;Ole32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;Glu32.lib;Ws2_32.lib;Crypt32.lib;Advapi32.lib;Gdiplus.lib;Ole32.lib;Windowscodecs.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<TargetMachine>MachineX64</TargetMachine> <TargetMachine>MachineX64</TargetMachine>
@@ -131,7 +131,7 @@
<ClCompile> <ClCompile>
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>.;control;gl;gl\pipeline;gl\renderer;gl\shader;videoio;videoio\decklink;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.;control;gl;gl\pipeline;gl\renderer;gl\shader;platform;runtime;shader;videoio;videoio\decklink;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
@@ -141,7 +141,7 @@
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>opengl32.lib;Glu32.lib;Windowscodecs.lib;Ole32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;Glu32.lib;Ws2_32.lib;Crypt32.lib;Advapi32.lib;Gdiplus.lib;Ole32.lib;Windowscodecs.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
@@ -156,7 +156,7 @@
<ClCompile> <ClCompile>
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<AdditionalIncludeDirectories>.;control;gl;gl\pipeline;gl\renderer;gl\shader;videoio;videoio\decklink;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>.;control;gl;gl\pipeline;gl\renderer;gl\shader;platform;runtime;shader;videoio;videoio\decklink;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary> <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
@@ -166,7 +166,7 @@
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalDependencies>opengl32.lib;Glu32.lib;Windowscodecs.lib;Ole32.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>opengl32.lib;Glu32.lib;Ws2_32.lib;Crypt32.lib;Advapi32.lib;Gdiplus.lib;Ole32.lib;Windowscodecs.lib;%(AdditionalDependencies)</AdditionalDependencies>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem> <SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences> <OptimizeReferences>true</OptimizeReferences>
@@ -175,18 +175,31 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="control\ControlServer.cpp" />
<ClCompile Include="control\ControlServices.cpp" />
<ClCompile Include="control\OscServer.cpp" />
<ClCompile Include="control\RuntimeControlBridge.cpp" />
<ClCompile Include="control\RuntimeServices.cpp" />
<ClCompile Include="gl\renderer\GLExtensions.cpp" /> <ClCompile Include="gl\renderer\GLExtensions.cpp" />
<ClCompile Include="gl\shader\GlobalParamsBuffer.cpp" />
<ClCompile Include="gl\shader\GlShaderSources.cpp" />
<ClCompile Include="LoopThroughWithOpenGLCompositing.cpp" /> <ClCompile Include="LoopThroughWithOpenGLCompositing.cpp" />
<ClCompile Include="gl\OpenGLComposite.cpp" /> <ClCompile Include="gl\OpenGLComposite.cpp" />
<ClCompile Include="gl\OpenGLCompositeRuntimeControls.cpp" />
<ClCompile Include="gl\pipeline\OpenGLRenderPass.cpp" /> <ClCompile Include="gl\pipeline\OpenGLRenderPass.cpp" />
<ClCompile Include="gl\pipeline\OpenGLRenderPipeline.cpp" /> <ClCompile Include="gl\pipeline\OpenGLRenderPipeline.cpp" />
<ClCompile Include="gl\pipeline\ShaderFeedbackBuffers.cpp" />
<ClCompile Include="gl\renderer\OpenGLRenderer.cpp" /> <ClCompile Include="gl\renderer\OpenGLRenderer.cpp" />
<ClCompile Include="gl\renderer\RenderTargetPool.cpp" /> <ClCompile Include="gl\renderer\RenderTargetPool.cpp" />
<ClCompile Include="gl\pipeline\OpenGLVideoIOBridge.cpp" />
<ClCompile Include="gl\shader\OpenGLShaderPrograms.cpp" /> <ClCompile Include="gl\shader\OpenGLShaderPrograms.cpp" />
<ClCompile Include="gl\pipeline\PngScreenshotWriter.cpp" /> <ClCompile Include="gl\pipeline\PngScreenshotWriter.cpp" />
<ClCompile Include="gl\shader\ShaderProgramCompiler.cpp" />
<ClCompile Include="gl\shader\ShaderBuildQueue.cpp" /> <ClCompile Include="gl\shader\ShaderBuildQueue.cpp" />
<ClCompile Include="gl\shader\ShaderTextureBindings.cpp" />
<ClCompile Include="gl\shader\TextRasterizer.cpp" />
<ClCompile Include="gl\shader\TextureAssetLoader.cpp" />
<ClCompile Include="gl\pipeline\TemporalHistoryBuffers.cpp" /> <ClCompile Include="gl\pipeline\TemporalHistoryBuffers.cpp" />
<ClCompile Include="gl\pipeline\OpenGLVideoIOBridge.cpp" />
<ClCompile Include="stdafx.cpp"> <ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
@@ -194,34 +207,71 @@
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader> <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile> </ClCompile>
<ClCompile Include="videoio\decklink\DeckLinkAPI_i.c" /> <ClCompile Include="videoio\decklink\DeckLinkAPI_i.c" />
<ClCompile Include="control\RuntimeServices.cpp" /> <ClCompile Include="videoio\decklink\DeckLinkDisplayMode.cpp" />
<ClCompile Include="videoio\decklink\DeckLinkFrameTransfer.cpp" />
<ClCompile Include="videoio\decklink\DeckLinkSession.cpp" /> <ClCompile Include="videoio\decklink\DeckLinkSession.cpp" />
<ClCompile Include="videoio\decklink\DeckLinkVideoIOFormat.cpp" /> <ClCompile Include="videoio\decklink\DeckLinkVideoIOFormat.cpp" />
<ClCompile Include="runtime\HealthTelemetry.cpp" />
<ClCompile Include="runtime\RuntimeClock.cpp" /> <ClCompile Include="runtime\RuntimeClock.cpp" />
<ClCompile Include="runtime\RuntimeHost.cpp" />
<ClCompile Include="runtime\RuntimeJson.cpp" />
<ClCompile Include="runtime\RuntimeParameterUtils.cpp" />
<ClCompile Include="runtime\RuntimeSnapshotProvider.cpp" />
<ClCompile Include="runtime\RuntimeStore.cpp" />
<ClCompile Include="shader\ShaderCompiler.cpp" />
<ClCompile Include="shader\ShaderPackageRegistry.cpp" />
<ClCompile Include="videoio\VideoIOFormat.cpp" /> <ClCompile Include="videoio\VideoIOFormat.cpp" />
<ClCompile Include="videoio\VideoPlayoutScheduler.cpp" /> <ClCompile Include="videoio\VideoPlayoutScheduler.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="control\ControlServer.h" />
<ClInclude Include="control\ControlServices.h" />
<ClInclude Include="control\OscServer.h" />
<ClInclude Include="control\RuntimeControlBridge.h" />
<ClInclude Include="control\RuntimeServices.h" />
<ClInclude Include="gl\renderer\GLExtensions.h" /> <ClInclude Include="gl\renderer\GLExtensions.h" />
<ClInclude Include="gl\shader\GlobalParamsBuffer.h" />
<ClInclude Include="gl\renderer\GlRenderConstants.h" />
<ClInclude Include="gl\renderer\GlScopedObjects.h" />
<ClInclude Include="gl\shader\GlShaderSources.h" />
<ClInclude Include="LoopThroughWithOpenGLCompositing.h" /> <ClInclude Include="LoopThroughWithOpenGLCompositing.h" />
<ClInclude Include="gl\OpenGLComposite.h" /> <ClInclude Include="gl\OpenGLComposite.h" />
<ClInclude Include="gl\pipeline\OpenGLRenderPass.h" /> <ClInclude Include="gl\pipeline\OpenGLRenderPass.h" />
<ClInclude Include="gl\pipeline\OpenGLRenderPipeline.h" /> <ClInclude Include="gl\pipeline\OpenGLRenderPipeline.h" />
<ClInclude Include="gl\pipeline\RenderPassDescriptor.h" /> <ClInclude Include="gl\pipeline\RenderPassDescriptor.h" />
<ClInclude Include="gl\pipeline\ShaderFeedbackBuffers.h" />
<ClInclude Include="gl\renderer\OpenGLRenderer.h" /> <ClInclude Include="gl\renderer\OpenGLRenderer.h" />
<ClInclude Include="gl\renderer\RenderTargetPool.h" /> <ClInclude Include="gl\renderer\RenderTargetPool.h" />
<ClInclude Include="gl\pipeline\OpenGLVideoIOBridge.h" />
<ClInclude Include="gl\shader\OpenGLShaderPrograms.h" /> <ClInclude Include="gl\shader\OpenGLShaderPrograms.h" />
<ClInclude Include="gl\pipeline\PngScreenshotWriter.h" /> <ClInclude Include="gl\pipeline\PngScreenshotWriter.h" />
<ClInclude Include="gl\shader\ShaderProgramCompiler.h" />
<ClInclude Include="gl\shader\ShaderBuildQueue.h" /> <ClInclude Include="gl\shader\ShaderBuildQueue.h" />
<ClInclude Include="gl\shader\ShaderTextureBindings.h" />
<ClInclude Include="gl\shader\Std140Buffer.h" />
<ClInclude Include="gl\shader\TextRasterizer.h" />
<ClInclude Include="gl\shader\TextureAssetLoader.h" />
<ClInclude Include="gl\pipeline\TemporalHistoryBuffers.h" /> <ClInclude Include="gl\pipeline\TemporalHistoryBuffers.h" />
<ClInclude Include="gl\pipeline\OpenGLVideoIOBridge.h" /> <ClInclude Include="platform\NativeHandles.h" />
<ClInclude Include="platform\NativeSockets.h" />
<ClInclude Include="resource.h" /> <ClInclude Include="resource.h" />
<ClInclude Include="runtime\HealthTelemetry.h" />
<ClInclude Include="runtime\RuntimeClock.h" />
<ClInclude Include="runtime\RuntimeHost.h" />
<ClInclude Include="runtime\RuntimeJson.h" />
<ClInclude Include="runtime\RuntimeParameterUtils.h" />
<ClInclude Include="runtime\RuntimeSnapshotProvider.h" />
<ClInclude Include="runtime\RuntimeStore.h" />
<ClInclude Include="shader\ShaderCompiler.h" />
<ClInclude Include="shader\ShaderPackageRegistry.h" />
<ClInclude Include="shader\ShaderTypes.h" />
<ClInclude Include="stdafx.h" /> <ClInclude Include="stdafx.h" />
<ClInclude Include="targetver.h" /> <ClInclude Include="targetver.h" />
<ClInclude Include="control\RuntimeServices.h" /> <ClInclude Include="videoio\decklink\DeckLinkAPI_h.h" />
<ClInclude Include="videoio\decklink\DeckLinkDisplayMode.h" />
<ClInclude Include="videoio\decklink\DeckLinkFrameTransfer.h" />
<ClInclude Include="videoio\decklink\DeckLinkSession.h" /> <ClInclude Include="videoio\decklink\DeckLinkSession.h" />
<ClInclude Include="videoio\decklink\DeckLinkVideoIOFormat.h" /> <ClInclude Include="videoio\decklink\DeckLinkVideoIOFormat.h" />
<ClInclude Include="runtime\RuntimeClock.h" />
<ClInclude Include="videoio\VideoIOFormat.h" /> <ClInclude Include="videoio\VideoIOFormat.h" />
<ClInclude Include="videoio\VideoIOTypes.h" /> <ClInclude Include="videoio\VideoIOTypes.h" />
<ClInclude Include="videoio\VideoPlayoutScheduler.h" /> <ClInclude Include="videoio\VideoPlayoutScheduler.h" />

View File

@@ -18,21 +18,45 @@
</Filter> </Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="control\ControlServer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="control\ControlServices.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="control\OscServer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="control\RuntimeControlBridge.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gl\renderer\GLExtensions.cpp"> <ClCompile Include="gl\renderer\GLExtensions.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="gl\shader\GlobalParamsBuffer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gl\shader\GlShaderSources.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="LoopThroughWithOpenGLCompositing.cpp"> <ClCompile Include="LoopThroughWithOpenGLCompositing.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="gl\OpenGLComposite.cpp"> <ClCompile Include="gl\OpenGLComposite.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="gl\OpenGLCompositeRuntimeControls.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gl\pipeline\OpenGLRenderPass.cpp"> <ClCompile Include="gl\pipeline\OpenGLRenderPass.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="gl\pipeline\OpenGLRenderPipeline.cpp"> <ClCompile Include="gl\pipeline\OpenGLRenderPipeline.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="gl\pipeline\ShaderFeedbackBuffers.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gl\renderer\OpenGLRenderer.cpp"> <ClCompile Include="gl\renderer\OpenGLRenderer.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@@ -45,9 +69,21 @@
<ClCompile Include="gl\pipeline\PngScreenshotWriter.cpp"> <ClCompile Include="gl\pipeline\PngScreenshotWriter.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="gl\shader\ShaderProgramCompiler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gl\shader\ShaderBuildQueue.cpp"> <ClCompile Include="gl\shader\ShaderBuildQueue.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="gl\shader\ShaderTextureBindings.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gl\shader\TextRasterizer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gl\shader\TextureAssetLoader.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="gl\pipeline\TemporalHistoryBuffers.cpp"> <ClCompile Include="gl\pipeline\TemporalHistoryBuffers.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@@ -63,15 +99,45 @@
<ClCompile Include="control\RuntimeServices.cpp"> <ClCompile Include="control\RuntimeServices.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="videoio\decklink\DeckLinkDisplayMode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="videoio\decklink\DeckLinkFrameTransfer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="videoio\decklink\DeckLinkSession.cpp"> <ClCompile Include="videoio\decklink\DeckLinkSession.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="videoio\decklink\DeckLinkVideoIOFormat.cpp"> <ClCompile Include="videoio\decklink\DeckLinkVideoIOFormat.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="runtime\HealthTelemetry.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="runtime\RuntimeClock.cpp"> <ClCompile Include="runtime\RuntimeClock.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="runtime\RuntimeHost.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="runtime\RuntimeJson.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="runtime\RuntimeParameterUtils.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="runtime\RuntimeSnapshotProvider.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="runtime\RuntimeStore.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="shader\ShaderCompiler.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="shader\ShaderPackageRegistry.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="videoio\VideoIOFormat.cpp"> <ClCompile Include="videoio\VideoIOFormat.cpp">
<Filter>Source Files</Filter> <Filter>Source Files</Filter>
</ClCompile> </ClCompile>
@@ -80,9 +146,33 @@
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="control\ControlServer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="control\ControlServices.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="control\OscServer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="control\RuntimeControlBridge.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gl\renderer\GLExtensions.h"> <ClInclude Include="gl\renderer\GLExtensions.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="gl\shader\GlobalParamsBuffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gl\renderer\GlRenderConstants.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gl\renderer\GlScopedObjects.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gl\shader\GlShaderSources.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="LoopThroughWithOpenGLCompositing.h"> <ClInclude Include="LoopThroughWithOpenGLCompositing.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@@ -98,6 +188,9 @@
<ClInclude Include="gl\pipeline\RenderPassDescriptor.h"> <ClInclude Include="gl\pipeline\RenderPassDescriptor.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="gl\pipeline\ShaderFeedbackBuffers.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gl\renderer\OpenGLRenderer.h"> <ClInclude Include="gl\renderer\OpenGLRenderer.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@@ -110,18 +203,66 @@
<ClInclude Include="gl\pipeline\PngScreenshotWriter.h"> <ClInclude Include="gl\pipeline\PngScreenshotWriter.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="gl\shader\ShaderProgramCompiler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gl\shader\ShaderBuildQueue.h"> <ClInclude Include="gl\shader\ShaderBuildQueue.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="gl\shader\ShaderTextureBindings.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gl\shader\Std140Buffer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gl\shader\TextRasterizer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gl\shader\TextureAssetLoader.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="gl\pipeline\TemporalHistoryBuffers.h"> <ClInclude Include="gl\pipeline\TemporalHistoryBuffers.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="gl\pipeline\OpenGLVideoIOBridge.h"> <ClInclude Include="gl\pipeline\OpenGLVideoIOBridge.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="platform\NativeHandles.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="platform\NativeSockets.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h"> <ClInclude Include="resource.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="runtime\HealthTelemetry.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="runtime\RuntimeHost.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="runtime\RuntimeJson.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="runtime\RuntimeParameterUtils.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="runtime\RuntimeSnapshotProvider.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="runtime\RuntimeStore.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="shader\ShaderCompiler.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="shader\ShaderPackageRegistry.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="shader\ShaderTypes.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="stdafx.h"> <ClInclude Include="stdafx.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
@@ -137,6 +278,15 @@
<ClInclude Include="videoio\decklink\DeckLinkVideoIOFormat.h"> <ClInclude Include="videoio\decklink\DeckLinkVideoIOFormat.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="videoio\decklink\DeckLinkAPI_h.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="videoio\decklink\DeckLinkDisplayMode.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="videoio\decklink\DeckLinkFrameTransfer.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="runtime\RuntimeClock.h"> <ClInclude Include="runtime\RuntimeClock.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>

View File

@@ -0,0 +1,247 @@
#include "ControlServices.h"
#include "ControlServer.h"
#include "OscServer.h"
#include "RuntimeControlBridge.h"
#include "RuntimeHost.h"
#include <windows.h>
ControlServices::ControlServices() :
mControlServer(std::make_unique<ControlServer>()),
mOscServer(std::make_unique<OscServer>()),
mPollRunning(false),
mRegistryChanged(false),
mReloadRequested(false),
mPollFailed(false)
{
}
ControlServices::~ControlServices()
{
Stop();
}
bool ControlServices::Start(OpenGLComposite& composite, RuntimeHost& runtimeHost, std::string& error)
{
Stop();
if (!StartControlServicesBoundary(composite, runtimeHost, *this, *mControlServer, *mOscServer, error))
{
Stop();
return false;
}
return true;
}
void ControlServices::BeginPolling(RuntimeHost& runtimeHost)
{
StartPolling(runtimeHost);
}
void ControlServices::Stop()
{
StopPolling();
if (mOscServer)
mOscServer->Stop();
if (mControlServer)
mControlServer->Stop();
}
void ControlServices::BroadcastState()
{
if (mControlServer)
mControlServer->BroadcastState();
}
void ControlServices::RequestBroadcastState()
{
if (mControlServer)
mControlServer->RequestBroadcastState();
}
bool ControlServices::QueueOscUpdate(const std::string& layerKey, const std::string& parameterKey, const std::string& valueJson, std::string& error)
{
(void)error;
PendingOscUpdate update;
update.layerKey = layerKey;
update.parameterKey = parameterKey;
update.valueJson = valueJson;
const std::string routeKey = layerKey + "\n" + parameterKey;
{
std::lock_guard<std::mutex> lock(mPendingOscMutex);
mPendingOscUpdates[routeKey] = std::move(update);
}
return true;
}
bool ControlServices::ApplyPendingOscUpdates(std::vector<AppliedOscUpdate>& appliedUpdates, std::string& error)
{
appliedUpdates.clear();
std::map<std::string, PendingOscUpdate> pending;
{
std::lock_guard<std::mutex> lock(mPendingOscMutex);
if (mPendingOscUpdates.empty())
return true;
pending.swap(mPendingOscUpdates);
}
for (const auto& entry : pending)
{
JsonValue targetValue;
std::string parseError;
if (!ParseJson(entry.second.valueJson, targetValue, parseError))
{
OutputDebugStringA(("OSC queued value parse failed: " + parseError + "\n").c_str());
continue;
}
AppliedOscUpdate appliedUpdate;
appliedUpdate.routeKey = entry.first;
appliedUpdate.layerKey = entry.second.layerKey;
appliedUpdate.parameterKey = entry.second.parameterKey;
appliedUpdate.targetValue = targetValue;
appliedUpdates.push_back(std::move(appliedUpdate));
}
(void)error;
return true;
}
bool ControlServices::QueueOscCommit(const std::string& routeKey, const std::string& layerKey, const std::string& parameterKey, const JsonValue& value, uint64_t generation, std::string& error)
{
(void)error;
PendingOscCommit commit;
commit.routeKey = routeKey;
commit.layerKey = layerKey;
commit.parameterKey = parameterKey;
commit.value = value;
commit.generation = generation;
{
std::lock_guard<std::mutex> lock(mPendingOscCommitMutex);
mPendingOscCommits[routeKey] = std::move(commit);
}
return true;
}
void ControlServices::ClearOscState()
{
{
std::lock_guard<std::mutex> lock(mPendingOscMutex);
mPendingOscUpdates.clear();
}
{
std::lock_guard<std::mutex> lock(mPendingOscCommitMutex);
mPendingOscCommits.clear();
}
{
std::lock_guard<std::mutex> lock(mCompletedOscCommitMutex);
mCompletedOscCommits.clear();
}
}
void ControlServices::ConsumeCompletedOscCommits(std::vector<CompletedOscCommit>& completedCommits)
{
completedCommits.clear();
std::lock_guard<std::mutex> lock(mCompletedOscCommitMutex);
if (mCompletedOscCommits.empty())
return;
completedCommits.swap(mCompletedOscCommits);
}
RuntimePollEvents ControlServices::ConsumePollEvents()
{
RuntimePollEvents events;
events.registryChanged = mRegistryChanged.exchange(false);
events.reloadRequested = mReloadRequested.exchange(false);
events.failed = mPollFailed.exchange(false);
if (events.failed)
{
std::lock_guard<std::mutex> lock(mPollErrorMutex);
events.error = mPollError;
}
return events;
}
void ControlServices::StartPolling(RuntimeHost& runtimeHost)
{
if (mPollRunning.exchange(true))
return;
mPollThread = std::thread([this, &runtimeHost]() { PollLoop(runtimeHost); });
}
void ControlServices::StopPolling()
{
if (!mPollRunning.exchange(false))
return;
if (mPollThread.joinable())
mPollThread.join();
}
void ControlServices::PollLoop(RuntimeHost& runtimeHost)
{
while (mPollRunning)
{
std::map<std::string, PendingOscCommit> pendingCommits;
{
std::lock_guard<std::mutex> lock(mPendingOscCommitMutex);
pendingCommits.swap(mPendingOscCommits);
}
for (const auto& entry : pendingCommits)
{
std::string commitError;
if (runtimeHost.UpdateLayerParameterByControlKey(
entry.second.layerKey,
entry.second.parameterKey,
entry.second.value,
false,
commitError))
{
CompletedOscCommit completedCommit;
completedCommit.routeKey = entry.second.routeKey;
completedCommit.generation = entry.second.generation;
std::lock_guard<std::mutex> lock(mCompletedOscCommitMutex);
mCompletedOscCommits.push_back(std::move(completedCommit));
}
else if (!commitError.empty())
{
OutputDebugStringA(("OSC commit failed: " + commitError + "\n").c_str());
}
}
bool registryChanged = false;
bool reloadRequested = false;
std::string runtimeError;
if (!runtimeHost.PollFileChanges(registryChanged, reloadRequested, runtimeError))
{
{
std::lock_guard<std::mutex> lock(mPollErrorMutex);
mPollError = runtimeError;
}
mPollFailed = true;
}
else
{
if (registryChanged)
mRegistryChanged = true;
if (reloadRequested)
mReloadRequested = true;
}
for (int i = 0; i < 25 && mPollRunning; ++i)
Sleep(10);
}
}

View File

@@ -0,0 +1,95 @@
#pragma once
#include "RuntimeJson.h"
#include "ShaderTypes.h"
#include <atomic>
#include <map>
#include <memory>
#include <mutex>
#include <string>
#include <thread>
#include <vector>
class ControlServer;
class OpenGLComposite;
class OscServer;
class RuntimeHost;
struct RuntimePollEvents
{
bool registryChanged = false;
bool reloadRequested = false;
bool failed = false;
std::string error;
};
class ControlServices
{
public:
struct AppliedOscUpdate
{
std::string routeKey;
std::string layerKey;
std::string parameterKey;
JsonValue targetValue;
};
struct CompletedOscCommit
{
std::string routeKey;
uint64_t generation = 0;
};
ControlServices();
~ControlServices();
bool Start(OpenGLComposite& composite, RuntimeHost& runtimeHost, std::string& error);
void BeginPolling(RuntimeHost& runtimeHost);
void Stop();
void BroadcastState();
void RequestBroadcastState();
bool QueueOscUpdate(const std::string& layerKey, const std::string& parameterKey, const std::string& valueJson, std::string& error);
bool ApplyPendingOscUpdates(std::vector<AppliedOscUpdate>& appliedUpdates, std::string& error);
bool QueueOscCommit(const std::string& routeKey, const std::string& layerKey, const std::string& parameterKey, const JsonValue& value, uint64_t generation, std::string& error);
void ClearOscState();
void ConsumeCompletedOscCommits(std::vector<CompletedOscCommit>& completedCommits);
RuntimePollEvents ConsumePollEvents();
private:
struct PendingOscUpdate
{
std::string layerKey;
std::string parameterKey;
std::string valueJson;
};
struct PendingOscCommit
{
std::string routeKey;
std::string layerKey;
std::string parameterKey;
JsonValue value;
uint64_t generation = 0;
};
void StartPolling(RuntimeHost& runtimeHost);
void StopPolling();
void PollLoop(RuntimeHost& runtimeHost);
std::unique_ptr<ControlServer> mControlServer;
std::unique_ptr<OscServer> mOscServer;
std::thread mPollThread;
std::atomic<bool> mPollRunning;
std::atomic<bool> mRegistryChanged;
std::atomic<bool> mReloadRequested;
std::atomic<bool> mPollFailed;
std::mutex mPollErrorMutex;
std::string mPollError;
std::mutex mPendingOscMutex;
std::map<std::string, PendingOscUpdate> mPendingOscUpdates;
std::mutex mPendingOscCommitMutex;
std::map<std::string, PendingOscCommit> mPendingOscCommits;
std::mutex mCompletedOscCommitMutex;
std::vector<CompletedOscCommit> mCompletedOscCommits;
};

View File

@@ -1,15 +1,15 @@
#include "RuntimeControlBridge.h" #include "RuntimeControlBridge.h"
#include "ControlServices.h"
#include "ControlServer.h" #include "ControlServer.h"
#include "OpenGLComposite.h" #include "OpenGLComposite.h"
#include "OscServer.h" #include "OscServer.h"
#include "RuntimeHost.h" #include "RuntimeHost.h"
#include "RuntimeServices.h"
bool StartRuntimeControlServices( bool StartControlServicesBoundary(
OpenGLComposite& composite, OpenGLComposite& composite,
RuntimeHost& runtimeHost, RuntimeHost& runtimeHost,
RuntimeServices& runtimeServices, ControlServices& controlServices,
ControlServer& controlServer, ControlServer& controlServer,
OscServer& oscServer, OscServer& oscServer,
std::string& error) std::string& error)
@@ -43,8 +43,8 @@ bool StartRuntimeControlServices(
runtimeHost.SetServerPort(controlServer.GetPort()); runtimeHost.SetServerPort(controlServer.GetPort());
OscServer::Callbacks oscCallbacks; OscServer::Callbacks oscCallbacks;
oscCallbacks.updateParameter = [&runtimeServices](const std::string& layerKey, const std::string& parameterKey, const std::string& valueJson, std::string& actionError) { oscCallbacks.updateParameter = [&controlServices](const std::string& layerKey, const std::string& parameterKey, const std::string& valueJson, std::string& actionError) {
return runtimeServices.QueueOscUpdate(layerKey, parameterKey, valueJson, actionError); return controlServices.QueueOscUpdate(layerKey, parameterKey, valueJson, actionError);
}; };
if (runtimeHost.GetOscPort() > 0 && !oscServer.Start(runtimeHost.GetOscBindAddress(), runtimeHost.GetOscPort(), oscCallbacks, error)) if (runtimeHost.GetOscPort() > 0 && !oscServer.Start(runtimeHost.GetOscBindAddress(), runtimeHost.GetOscPort(), oscCallbacks, error))
return false; return false;

View File

@@ -3,15 +3,15 @@
#include <string> #include <string>
class ControlServer; class ControlServer;
class ControlServices;
class OpenGLComposite; class OpenGLComposite;
class OscServer; class OscServer;
class RuntimeHost; class RuntimeHost;
class RuntimeServices;
bool StartRuntimeControlServices( bool StartControlServicesBoundary(
OpenGLComposite& composite, OpenGLComposite& composite,
RuntimeHost& runtimeHost, RuntimeHost& runtimeHost,
RuntimeServices& runtimeServices, ControlServices& controlServices,
ControlServer& controlServer, ControlServer& controlServer,
OscServer& oscServer, OscServer& oscServer,
std::string& error); std::string& error);

View File

@@ -1,18 +1,7 @@
#include "RuntimeServices.h" #include "RuntimeServices.h"
#include "ControlServer.h"
#include "OscServer.h"
#include "RuntimeControlBridge.h"
#include "RuntimeHost.h"
#include <windows.h>
RuntimeServices::RuntimeServices() : RuntimeServices::RuntimeServices() :
mControlServer(std::make_unique<ControlServer>()), mControlServices(std::make_unique<ControlServices>())
mOscServer(std::make_unique<OscServer>()),
mPollRunning(false),
mRegistryChanged(false),
mReloadRequested(false),
mPollFailed(false)
{ {
} }
@@ -23,225 +12,72 @@ RuntimeServices::~RuntimeServices()
bool RuntimeServices::Start(OpenGLComposite& composite, RuntimeHost& runtimeHost, std::string& error) bool RuntimeServices::Start(OpenGLComposite& composite, RuntimeHost& runtimeHost, std::string& error)
{ {
Stop(); return mControlServices && mControlServices->Start(composite, runtimeHost, error);
if (!StartRuntimeControlServices(composite, runtimeHost, *this, *mControlServer, *mOscServer, error))
{
Stop();
return false;
}
return true;
} }
void RuntimeServices::BeginPolling(RuntimeHost& runtimeHost) void RuntimeServices::BeginPolling(RuntimeHost& runtimeHost)
{ {
StartPolling(runtimeHost); if (mControlServices)
mControlServices->BeginPolling(runtimeHost);
} }
void RuntimeServices::Stop() void RuntimeServices::Stop()
{ {
StopPolling(); if (mControlServices)
mControlServices->Stop();
if (mOscServer)
mOscServer->Stop();
if (mControlServer)
mControlServer->Stop();
} }
void RuntimeServices::BroadcastState() void RuntimeServices::BroadcastState()
{ {
if (mControlServer) if (mControlServices)
mControlServer->BroadcastState(); mControlServices->BroadcastState();
} }
void RuntimeServices::RequestBroadcastState() void RuntimeServices::RequestBroadcastState()
{ {
if (mControlServer) if (mControlServices)
mControlServer->RequestBroadcastState(); mControlServices->RequestBroadcastState();
} }
bool RuntimeServices::QueueOscUpdate(const std::string& layerKey, const std::string& parameterKey, const std::string& valueJson, std::string& error) bool RuntimeServices::QueueOscUpdate(const std::string& layerKey, const std::string& parameterKey, const std::string& valueJson, std::string& error)
{ {
(void)error; return mControlServices && mControlServices->QueueOscUpdate(layerKey, parameterKey, valueJson, error);
PendingOscUpdate update;
update.layerKey = layerKey;
update.parameterKey = parameterKey;
update.valueJson = valueJson;
const std::string routeKey = layerKey + "\n" + parameterKey;
{
std::lock_guard<std::mutex> lock(mPendingOscMutex);
mPendingOscUpdates[routeKey] = std::move(update);
}
return true;
} }
bool RuntimeServices::ApplyPendingOscUpdates(std::vector<AppliedOscUpdate>& appliedUpdates, std::string& error) bool RuntimeServices::ApplyPendingOscUpdates(std::vector<AppliedOscUpdate>& appliedUpdates, std::string& error)
{ {
appliedUpdates.clear(); if (!mControlServices)
std::map<std::string, PendingOscUpdate> pending;
{ {
std::lock_guard<std::mutex> lock(mPendingOscMutex); appliedUpdates.clear();
if (mPendingOscUpdates.empty()) return true;
return true;
pending.swap(mPendingOscUpdates);
} }
for (const auto& entry : pending) return mControlServices->ApplyPendingOscUpdates(appliedUpdates, error);
{
JsonValue targetValue;
std::string parseError;
if (!ParseJson(entry.second.valueJson, targetValue, parseError))
{
OutputDebugStringA(("OSC queued value parse failed: " + parseError + "\n").c_str());
continue;
}
AppliedOscUpdate appliedUpdate;
appliedUpdate.routeKey = entry.first;
appliedUpdate.layerKey = entry.second.layerKey;
appliedUpdate.parameterKey = entry.second.parameterKey;
appliedUpdate.targetValue = targetValue;
appliedUpdates.push_back(std::move(appliedUpdate));
}
(void)error;
return true;
} }
bool RuntimeServices::QueueOscCommit(const std::string& routeKey, const std::string& layerKey, const std::string& parameterKey, const JsonValue& value, uint64_t generation, std::string& error) bool RuntimeServices::QueueOscCommit(const std::string& routeKey, const std::string& layerKey, const std::string& parameterKey, const JsonValue& value, uint64_t generation, std::string& error)
{ {
(void)error; return mControlServices && mControlServices->QueueOscCommit(routeKey, layerKey, parameterKey, value, generation, error);
PendingOscCommit commit;
commit.routeKey = routeKey;
commit.layerKey = layerKey;
commit.parameterKey = parameterKey;
commit.value = value;
commit.generation = generation;
{
std::lock_guard<std::mutex> lock(mPendingOscCommitMutex);
mPendingOscCommits[routeKey] = std::move(commit);
}
return true;
} }
void RuntimeServices::ClearOscState() void RuntimeServices::ClearOscState()
{ {
{ if (mControlServices)
std::lock_guard<std::mutex> lock(mPendingOscMutex); mControlServices->ClearOscState();
mPendingOscUpdates.clear();
}
{
std::lock_guard<std::mutex> lock(mPendingOscCommitMutex);
mPendingOscCommits.clear();
}
{
std::lock_guard<std::mutex> lock(mCompletedOscCommitMutex);
mCompletedOscCommits.clear();
}
} }
void RuntimeServices::ConsumeCompletedOscCommits(std::vector<CompletedOscCommit>& completedCommits) void RuntimeServices::ConsumeCompletedOscCommits(std::vector<CompletedOscCommit>& completedCommits)
{ {
completedCommits.clear(); if (!mControlServices)
{
std::lock_guard<std::mutex> lock(mCompletedOscCommitMutex); completedCommits.clear();
if (mCompletedOscCommits.empty())
return; return;
}
completedCommits.swap(mCompletedOscCommits); mControlServices->ConsumeCompletedOscCommits(completedCommits);
} }
RuntimePollEvents RuntimeServices::ConsumePollEvents() RuntimePollEvents RuntimeServices::ConsumePollEvents()
{ {
RuntimePollEvents events; return mControlServices ? mControlServices->ConsumePollEvents() : RuntimePollEvents{};
events.registryChanged = mRegistryChanged.exchange(false);
events.reloadRequested = mReloadRequested.exchange(false);
events.failed = mPollFailed.exchange(false);
if (events.failed)
{
std::lock_guard<std::mutex> lock(mPollErrorMutex);
events.error = mPollError;
}
return events;
}
void RuntimeServices::StartPolling(RuntimeHost& runtimeHost)
{
if (mPollRunning.exchange(true))
return;
mPollThread = std::thread([this, &runtimeHost]() { PollLoop(runtimeHost); });
}
void RuntimeServices::StopPolling()
{
if (!mPollRunning.exchange(false))
return;
if (mPollThread.joinable())
mPollThread.join();
}
void RuntimeServices::PollLoop(RuntimeHost& runtimeHost)
{
while (mPollRunning)
{
std::map<std::string, PendingOscCommit> pendingCommits;
{
std::lock_guard<std::mutex> lock(mPendingOscCommitMutex);
pendingCommits.swap(mPendingOscCommits);
}
for (const auto& entry : pendingCommits)
{
std::string commitError;
if (runtimeHost.UpdateLayerParameterByControlKey(
entry.second.layerKey,
entry.second.parameterKey,
entry.second.value,
false,
commitError))
{
CompletedOscCommit completedCommit;
completedCommit.routeKey = entry.second.routeKey;
completedCommit.generation = entry.second.generation;
std::lock_guard<std::mutex> lock(mCompletedOscCommitMutex);
mCompletedOscCommits.push_back(std::move(completedCommit));
}
else if (!commitError.empty())
{
OutputDebugStringA(("OSC commit failed: " + commitError + "\n").c_str());
}
}
bool registryChanged = false;
bool reloadRequested = false;
std::string runtimeError;
if (!runtimeHost.PollFileChanges(registryChanged, reloadRequested, runtimeError))
{
{
std::lock_guard<std::mutex> lock(mPollErrorMutex);
mPollError = runtimeError;
}
mPollFailed = true;
}
else
{
if (registryChanged)
mRegistryChanged = true;
if (reloadRequested)
mReloadRequested = true;
}
for (int i = 0; i < 25 && mPollRunning; ++i)
Sleep(10);
}
} }

View File

@@ -1,44 +1,17 @@
#pragma once #pragma once
#include "RuntimeJson.h" #include "ControlServices.h"
#include "ShaderTypes.h"
#include <atomic>
#include <map>
#include <memory> #include <memory>
#include <mutex>
#include <string> #include <string>
#include <thread>
class ControlServer;
class OpenGLComposite; class OpenGLComposite;
class OscServer;
class RuntimeHost; class RuntimeHost;
struct RuntimePollEvents
{
bool registryChanged = false;
bool reloadRequested = false;
bool failed = false;
std::string error;
};
class RuntimeServices class RuntimeServices
{ {
public: public:
struct AppliedOscUpdate using AppliedOscUpdate = ControlServices::AppliedOscUpdate;
{ using CompletedOscCommit = ControlServices::CompletedOscCommit;
std::string routeKey;
std::string layerKey;
std::string parameterKey;
JsonValue targetValue;
};
struct CompletedOscCommit
{
std::string routeKey;
uint64_t generation = 0;
};
RuntimeServices(); RuntimeServices();
~RuntimeServices(); ~RuntimeServices();
@@ -56,39 +29,5 @@ public:
RuntimePollEvents ConsumePollEvents(); RuntimePollEvents ConsumePollEvents();
private: private:
struct PendingOscUpdate std::unique_ptr<ControlServices> mControlServices;
{
std::string layerKey;
std::string parameterKey;
std::string valueJson;
};
struct PendingOscCommit
{
std::string routeKey;
std::string layerKey;
std::string parameterKey;
JsonValue value;
uint64_t generation = 0;
};
void StartPolling(RuntimeHost& runtimeHost);
void StopPolling();
void PollLoop(RuntimeHost& runtimeHost);
std::unique_ptr<ControlServer> mControlServer;
std::unique_ptr<OscServer> mOscServer;
std::thread mPollThread;
std::atomic<bool> mPollRunning;
std::atomic<bool> mRegistryChanged;
std::atomic<bool> mReloadRequested;
std::atomic<bool> mPollFailed;
std::mutex mPollErrorMutex;
std::string mPollError;
std::mutex mPendingOscMutex;
std::map<std::string, PendingOscUpdate> mPendingOscUpdates;
std::mutex mPendingOscCommitMutex;
std::map<std::string, PendingOscCommit> mPendingOscCommits;
std::mutex mCompletedOscCommitMutex;
std::vector<CompletedOscCommit> mCompletedOscCommits;
}; };

View File

@@ -148,10 +148,10 @@ bool OpenGLComposite::InitVideoIO()
VideoFormatSelection videoModes; VideoFormatSelection videoModes;
std::string initFailureReason; std::string initFailureReason;
if (mRuntimeStore && mRuntimeStore->GetRepoRoot().empty()) if (mRuntimeStore && mRuntimeStore->GetRuntimeRepositoryRoot().empty())
{ {
std::string runtimeError; std::string runtimeError;
if (!mRuntimeStore->Initialize(runtimeError)) if (!mRuntimeStore->InitializeStore(runtimeError))
{ {
MessageBoxA(NULL, runtimeError.c_str(), "Runtime host failed to initialize", MB_OK); MessageBoxA(NULL, runtimeError.c_str(), "Runtime host failed to initialize", MB_OK);
return false; return false;
@@ -161,10 +161,10 @@ bool OpenGLComposite::InitVideoIO()
if (mRuntimeStore) if (mRuntimeStore)
{ {
if (!ResolveConfiguredVideoFormats( if (!ResolveConfiguredVideoFormats(
mRuntimeStore->GetInputVideoFormat(), mRuntimeStore->GetConfiguredInputVideoFormat(),
mRuntimeStore->GetInputFrameRate(), mRuntimeStore->GetConfiguredInputFrameRate(),
mRuntimeStore->GetOutputVideoFormat(), mRuntimeStore->GetConfiguredOutputVideoFormat(),
mRuntimeStore->GetOutputFrameRate(), mRuntimeStore->GetConfiguredOutputFrameRate(),
videoModes, videoModes,
initFailureReason)) initFailureReason))
{ {
@@ -181,7 +181,7 @@ bool OpenGLComposite::InitVideoIO()
MessageBoxA(NULL, initFailureReason.c_str(), title, MB_OK | MB_ICONERROR); MessageBoxA(NULL, initFailureReason.c_str(), title, MB_OK | MB_ICONERROR);
return false; return false;
} }
const bool outputAlphaRequired = mRuntimeStore && mRuntimeStore->ExternalKeyingEnabled(); const bool outputAlphaRequired = mRuntimeStore && mRuntimeStore->IsExternalKeyingConfigured();
if (!mVideoIO->SelectPreferredFormats(videoModes, outputAlphaRequired, initFailureReason)) if (!mVideoIO->SelectPreferredFormats(videoModes, outputAlphaRequired, initFailureReason))
goto error; goto error;
@@ -216,7 +216,7 @@ bool OpenGLComposite::InitVideoIO()
mRuntimeHost->SetSignalStatus(false, mVideoIO->InputFrameWidth(), mVideoIO->InputFrameHeight(), mVideoIO->InputDisplayModeName()); mRuntimeHost->SetSignalStatus(false, mVideoIO->InputFrameWidth(), mVideoIO->InputFrameHeight(), mVideoIO->InputDisplayModeName());
} }
if (!mVideoIO->ConfigureOutput([this](const VideoIOCompletion& completion) { mVideoIOBridge->PlayoutFrameCompleted(completion); }, videoModes.output, mRuntimeStore && mRuntimeStore->ExternalKeyingEnabled(), initFailureReason)) if (!mVideoIO->ConfigureOutput([this](const VideoIOCompletion& completion) { mVideoIOBridge->PlayoutFrameCompleted(completion); }, videoModes.output, mRuntimeStore && mRuntimeStore->IsExternalKeyingConfigured(), initFailureReason))
{ {
goto error; goto error;
} }
@@ -239,7 +239,7 @@ void OpenGLComposite::paintGL(bool force)
if (IsIconic(hGLWnd)) if (IsIconic(hGLWnd))
return; return;
const unsigned previewFps = mRuntimeStore ? mRuntimeStore->GetPreviewFps() : 30u; const unsigned previewFps = mRuntimeStore ? mRuntimeStore->GetConfiguredPreviewFps() : 30u;
if (previewFps == 0) if (previewFps == 0)
return; return;
@@ -294,7 +294,7 @@ void OpenGLComposite::PublishVideoIOStatus(const std::string& statusMessage)
mVideoIO->SupportsInternalKeying(), mVideoIO->SupportsInternalKeying(),
mVideoIO->SupportsExternalKeying(), mVideoIO->SupportsExternalKeying(),
mVideoIO->KeyerInterfaceAvailable(), mVideoIO->KeyerInterfaceAvailable(),
mRuntimeStore ? mRuntimeStore->ExternalKeyingEnabled() : false, mRuntimeStore ? mRuntimeStore->IsExternalKeyingConfigured() : false,
mVideoIO->ExternalKeyingActive(), mVideoIO->ExternalKeyingActive(),
mVideoIO->StatusMessage()); mVideoIO->StatusMessage());
} }
@@ -305,7 +305,7 @@ bool OpenGLComposite::InitOpenGLState()
return false; return false;
std::string runtimeError; std::string runtimeError;
if (mRuntimeStore->GetRepoRoot().empty() && !mRuntimeStore->Initialize(runtimeError)) if (mRuntimeStore->GetRuntimeRepositoryRoot().empty() && !mRuntimeStore->InitializeStore(runtimeError))
{ {
MessageBoxA(NULL, runtimeError.c_str(), "Runtime host failed to initialize", MB_OK); MessageBoxA(NULL, runtimeError.c_str(), "Runtime host failed to initialize", MB_OK);
return false; return false;
@@ -458,7 +458,7 @@ void OpenGLComposite::renderEffect()
if (states.empty() || mOscOverlayStates.empty() || !mRuntimeHost) if (states.empty() || mOscOverlayStates.empty() || !mRuntimeHost)
return; return;
const double smoothing = ClampOscAlpha(mRuntimeStore ? mRuntimeStore->GetOscSmoothing() : 0.0); const double smoothing = ClampOscAlpha(mRuntimeStore ? mRuntimeStore->GetConfiguredOscSmoothing() : 0.0);
std::vector<std::string> overlayKeysToRemove; std::vector<std::string> overlayKeysToRemove;
for (auto& item : mOscOverlayStates) for (auto& item : mOscOverlayStates)
{ {
@@ -600,35 +600,44 @@ void OpenGLComposite::renderEffect()
{ {
const unsigned renderWidth = mVideoIO->InputFrameWidth(); const unsigned renderWidth = mVideoIO->InputFrameWidth();
const unsigned renderHeight = mVideoIO->InputFrameHeight(); const unsigned renderHeight = mVideoIO->InputFrameHeight();
const uint64_t renderStateVersion = mRuntimeSnapshotProvider->GetRenderStateVersion(); const RuntimeSnapshotVersions versions = mRuntimeSnapshotProvider->GetVersions();
const uint64_t parameterStateVersion = mRuntimeSnapshotProvider->GetParameterStateVersion();
const bool renderStateCacheValid = const bool renderStateCacheValid =
!mCachedLayerRenderStates.empty() && !mCachedLayerRenderStates.empty() &&
mCachedRenderStateVersion == renderStateVersion && mCachedRenderStateVersion == versions.renderStateVersion &&
mCachedRenderStateWidth == renderWidth && mCachedRenderStateWidth == renderWidth &&
mCachedRenderStateHeight == renderHeight; mCachedRenderStateHeight == renderHeight;
if (renderStateCacheValid) if (renderStateCacheValid)
{ {
applyOscOverlays(mCachedLayerRenderStates, true); RuntimeRenderStateSnapshot renderSnapshot;
if (mCachedParameterStateVersion != parameterStateVersion && renderSnapshot.outputWidth = renderWidth;
mRuntimeSnapshotProvider->TryRefreshCachedLayerStates(mCachedLayerRenderStates)) renderSnapshot.outputHeight = renderHeight;
renderSnapshot.versions.renderStateVersion = mCachedRenderStateVersion;
renderSnapshot.versions.parameterStateVersion = mCachedParameterStateVersion;
renderSnapshot.states = mCachedLayerRenderStates;
applyOscOverlays(renderSnapshot.states, true);
if (mCachedParameterStateVersion != versions.parameterStateVersion &&
mRuntimeSnapshotProvider->TryRefreshSnapshotParameters(renderSnapshot))
{ {
mCachedParameterStateVersion = parameterStateVersion; mCachedParameterStateVersion = renderSnapshot.versions.parameterStateVersion;
applyOscOverlays(mCachedLayerRenderStates, true); applyOscOverlays(renderSnapshot.states, true);
} }
layerStates = mCachedLayerRenderStates;
mCachedLayerRenderStates = renderSnapshot.states;
layerStates = renderSnapshot.states;
mRuntimeSnapshotProvider->RefreshDynamicRenderStateFields(layerStates); mRuntimeSnapshotProvider->RefreshDynamicRenderStateFields(layerStates);
} }
else else
{ {
if (mRuntimeSnapshotProvider->TryGetLayerRenderStates(renderWidth, renderHeight, layerStates)) RuntimeRenderStateSnapshot renderSnapshot;
if (mRuntimeSnapshotProvider->TryGetRenderStateSnapshot(renderWidth, renderHeight, renderSnapshot))
{ {
mCachedLayerRenderStates = layerStates; mCachedLayerRenderStates = renderSnapshot.states;
mCachedRenderStateVersion = renderStateVersion; mCachedRenderStateVersion = renderSnapshot.versions.renderStateVersion;
mCachedParameterStateVersion = parameterStateVersion; mCachedParameterStateVersion = renderSnapshot.versions.parameterStateVersion;
mCachedRenderStateWidth = renderWidth; mCachedRenderStateWidth = renderSnapshot.outputWidth;
mCachedRenderStateHeight = renderHeight; mCachedRenderStateHeight = renderSnapshot.outputHeight;
applyOscOverlays(mCachedLayerRenderStates, true); applyOscOverlays(mCachedLayerRenderStates, true);
layerStates = mCachedLayerRenderStates; layerStates = mCachedLayerRenderStates;
} }
@@ -640,7 +649,7 @@ void OpenGLComposite::renderEffect()
} }
} }
} }
const unsigned historyCap = mRuntimeStore ? mRuntimeStore->GetMaxTemporalHistoryFrames() : 0; const unsigned historyCap = mRuntimeStore ? mRuntimeStore->GetConfiguredMaxTemporalHistoryFrames() : 0;
mRenderPass->Render( mRenderPass->Render(
hasInputSource, hasInputSource,
layerStates, layerStates,
@@ -701,8 +710,8 @@ void OpenGLComposite::ProcessScreenshotRequest()
std::filesystem::path OpenGLComposite::BuildScreenshotPath() const std::filesystem::path OpenGLComposite::BuildScreenshotPath() const
{ {
const std::filesystem::path root = mRuntimeStore && !mRuntimeStore->GetRuntimeRoot().empty() const std::filesystem::path root = mRuntimeStore && !mRuntimeStore->GetRuntimeDataRoot().empty()
? mRuntimeStore->GetRuntimeRoot() ? mRuntimeStore->GetRuntimeDataRoot()
: std::filesystem::current_path(); : std::filesystem::current_path();
const auto now = std::chrono::system_clock::now(); const auto now = std::chrono::system_clock::now();

View File

@@ -3,22 +3,22 @@
std::string OpenGLComposite::GetRuntimeStateJson() const std::string OpenGLComposite::GetRuntimeStateJson() const
{ {
return mRuntimeStore ? mRuntimeStore->BuildStateJson() : "{}"; return mRuntimeStore ? mRuntimeStore->BuildPersistentStateJson() : "{}";
} }
unsigned short OpenGLComposite::GetControlServerPort() const unsigned short OpenGLComposite::GetControlServerPort() const
{ {
return mRuntimeStore ? mRuntimeStore->GetServerPort() : 0; return mRuntimeStore ? mRuntimeStore->GetConfiguredControlServerPort() : 0;
} }
unsigned short OpenGLComposite::GetOscPort() const unsigned short OpenGLComposite::GetOscPort() const
{ {
return mRuntimeStore ? mRuntimeStore->GetOscPort() : 0; return mRuntimeStore ? mRuntimeStore->GetConfiguredOscPort() : 0;
} }
std::string OpenGLComposite::GetOscBindAddress() const std::string OpenGLComposite::GetOscBindAddress() const
{ {
return mRuntimeStore ? mRuntimeStore->GetOscBindAddress() : "127.0.0.1"; return mRuntimeStore ? mRuntimeStore->GetConfiguredOscBindAddress() : "127.0.0.1";
} }
std::string OpenGLComposite::GetControlUrl() const std::string OpenGLComposite::GetControlUrl() const
@@ -38,7 +38,7 @@ std::string OpenGLComposite::GetOscAddress() const
bool OpenGLComposite::AddLayer(const std::string& shaderId, std::string& error) bool OpenGLComposite::AddLayer(const std::string& shaderId, std::string& error)
{ {
if (!mRuntimeStore->AddLayer(shaderId, error)) if (!mRuntimeStore->CreateStoredLayer(shaderId, error))
return false; return false;
ReloadShader(true); ReloadShader(true);
@@ -48,7 +48,7 @@ bool OpenGLComposite::AddLayer(const std::string& shaderId, std::string& error)
bool OpenGLComposite::RemoveLayer(const std::string& layerId, std::string& error) bool OpenGLComposite::RemoveLayer(const std::string& layerId, std::string& error)
{ {
if (!mRuntimeStore->RemoveLayer(layerId, error)) if (!mRuntimeStore->DeleteStoredLayer(layerId, error))
return false; return false;
ReloadShader(true); ReloadShader(true);
@@ -58,7 +58,7 @@ bool OpenGLComposite::RemoveLayer(const std::string& layerId, std::string& error
bool OpenGLComposite::MoveLayer(const std::string& layerId, int direction, std::string& error) bool OpenGLComposite::MoveLayer(const std::string& layerId, int direction, std::string& error)
{ {
if (!mRuntimeStore->MoveLayer(layerId, direction, error)) if (!mRuntimeStore->MoveStoredLayer(layerId, direction, error))
return false; return false;
ReloadShader(true); ReloadShader(true);
@@ -68,7 +68,7 @@ bool OpenGLComposite::MoveLayer(const std::string& layerId, int direction, std::
bool OpenGLComposite::MoveLayerToIndex(const std::string& layerId, std::size_t targetIndex, std::string& error) bool OpenGLComposite::MoveLayerToIndex(const std::string& layerId, std::size_t targetIndex, std::string& error)
{ {
if (!mRuntimeStore->MoveLayerToIndex(layerId, targetIndex, error)) if (!mRuntimeStore->MoveStoredLayerToIndex(layerId, targetIndex, error))
return false; return false;
ReloadShader(true); ReloadShader(true);
@@ -78,7 +78,7 @@ bool OpenGLComposite::MoveLayerToIndex(const std::string& layerId, std::size_t t
bool OpenGLComposite::SetLayerBypass(const std::string& layerId, bool bypassed, std::string& error) bool OpenGLComposite::SetLayerBypass(const std::string& layerId, bool bypassed, std::string& error)
{ {
if (!mRuntimeStore->SetLayerBypass(layerId, bypassed, error)) if (!mRuntimeStore->SetStoredLayerBypassState(layerId, bypassed, error))
return false; return false;
ReloadShader(); ReloadShader();
@@ -88,7 +88,7 @@ bool OpenGLComposite::SetLayerBypass(const std::string& layerId, bool bypassed,
bool OpenGLComposite::SetLayerShader(const std::string& layerId, const std::string& shaderId, std::string& error) bool OpenGLComposite::SetLayerShader(const std::string& layerId, const std::string& shaderId, std::string& error)
{ {
if (!mRuntimeStore->SetLayerShader(layerId, shaderId, error)) if (!mRuntimeStore->SetStoredLayerShaderSelection(layerId, shaderId, error))
return false; return false;
ReloadShader(); ReloadShader();
@@ -102,7 +102,7 @@ bool OpenGLComposite::UpdateLayerParameterJson(const std::string& layerId, const
if (!ParseJson(valueJson, parsedValue, error)) if (!ParseJson(valueJson, parsedValue, error))
return false; return false;
if (!mRuntimeStore->UpdateLayerParameter(layerId, parameterId, parsedValue, error)) if (!mRuntimeStore->SetStoredParameterValue(layerId, parameterId, parsedValue, error))
return false; return false;
broadcastRuntimeState(); broadcastRuntimeState();
@@ -115,7 +115,7 @@ bool OpenGLComposite::UpdateLayerParameterByControlKeyJson(const std::string& la
if (!ParseJson(valueJson, parsedValue, error)) if (!ParseJson(valueJson, parsedValue, error))
return false; return false;
if (!mRuntimeStore->UpdateLayerParameterByControlKey(layerKey, parameterKey, parsedValue, error)) if (!mRuntimeStore->SetStoredParameterValueByControlKey(layerKey, parameterKey, parsedValue, error))
return false; return false;
broadcastRuntimeState(); broadcastRuntimeState();
@@ -124,7 +124,7 @@ bool OpenGLComposite::UpdateLayerParameterByControlKeyJson(const std::string& la
bool OpenGLComposite::ResetLayerParameters(const std::string& layerId, std::string& error) bool OpenGLComposite::ResetLayerParameters(const std::string& layerId, std::string& error)
{ {
if (!mRuntimeStore->ResetLayerParameters(layerId, error)) if (!mRuntimeStore->ResetStoredLayerParameterValues(layerId, error))
return false; return false;
mOscOverlayStates.clear(); mOscOverlayStates.clear();
@@ -138,7 +138,7 @@ bool OpenGLComposite::ResetLayerParameters(const std::string& layerId, std::stri
bool OpenGLComposite::SaveStackPreset(const std::string& presetName, std::string& error) bool OpenGLComposite::SaveStackPreset(const std::string& presetName, std::string& error)
{ {
if (!mRuntimeStore->SaveStackPreset(presetName, error)) if (!mRuntimeStore->SaveStackPresetSnapshot(presetName, error))
return false; return false;
broadcastRuntimeState(); broadcastRuntimeState();
@@ -147,7 +147,7 @@ bool OpenGLComposite::SaveStackPreset(const std::string& presetName, std::string
bool OpenGLComposite::LoadStackPreset(const std::string& presetName, std::string& error) bool OpenGLComposite::LoadStackPreset(const std::string& presetName, std::string& error)
{ {
if (!mRuntimeStore->LoadStackPreset(presetName, error)) if (!mRuntimeStore->LoadStackPresetSnapshot(presetName, error))
return false; return false;
ReloadShader(); ReloadShader();

View File

@@ -47,7 +47,7 @@ bool OpenGLRenderPipeline::RenderFrame(const RenderPipelineFrameContext& context
const auto renderEndTime = std::chrono::steady_clock::now(); const auto renderEndTime = std::chrono::steady_clock::now();
const double renderMilliseconds = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(renderEndTime - renderStartTime).count(); const double renderMilliseconds = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(renderEndTime - renderStartTime).count();
mRuntimeHost.TrySetPerformanceStats(state.frameBudgetMilliseconds, renderMilliseconds); mRuntimeHost.GetHealthTelemetry().TryRecordPerformanceStats(state.frameBudgetMilliseconds, renderMilliseconds);
mRuntimeHost.TryAdvanceFrame(); mRuntimeHost.TryAdvanceFrame();
ReadOutputFrame(state, outputFrame); ReadOutputFrame(state, outputFrame);

View File

@@ -46,7 +46,7 @@ void OpenGLVideoIOBridge::RecordFramePacing(VideoIOCompletionResult completionRe
else if (completionResult == VideoIOCompletionResult::Flushed) else if (completionResult == VideoIOCompletionResult::Flushed)
++mFlushedFrameCount; ++mFlushedFrameCount;
mRuntimeHost.TrySetFramePacingStats( mRuntimeHost.GetHealthTelemetry().TryRecordFramePacingStats(
mCompletionIntervalMilliseconds, mCompletionIntervalMilliseconds,
mSmoothedCompletionIntervalMilliseconds, mSmoothedCompletionIntervalMilliseconds,
mMaxCompletionIntervalMilliseconds, mMaxCompletionIntervalMilliseconds,
@@ -58,7 +58,7 @@ void OpenGLVideoIOBridge::RecordFramePacing(VideoIOCompletionResult completionRe
void OpenGLVideoIOBridge::VideoFrameArrived(const VideoIOFrame& inputFrame) void OpenGLVideoIOBridge::VideoFrameArrived(const VideoIOFrame& inputFrame)
{ {
const VideoIOState& state = mVideoIO.State(); const VideoIOState& state = mVideoIO.State();
mRuntimeHost.TrySetSignalStatus(!inputFrame.hasNoInputSource, state.inputFrameSize.width, state.inputFrameSize.height, state.inputDisplayModeName); mRuntimeHost.GetHealthTelemetry().TryReportSignalStatus(!inputFrame.hasNoInputSource, state.inputFrameSize.width, state.inputFrameSize.height, state.inputDisplayModeName);
if (inputFrame.hasNoInputSource || inputFrame.bytes == nullptr) if (inputFrame.hasNoInputSource || inputFrame.bytes == nullptr)
return; // don't transfer texture when there's no input return; // don't transfer texture when there's no input

View File

@@ -40,7 +40,9 @@ OpenGLShaderPrograms::OpenGLShaderPrograms(OpenGLRenderer& renderer, RuntimeHost
bool OpenGLShaderPrograms::CompileLayerPrograms(unsigned inputFrameWidth, unsigned inputFrameHeight, int errorMessageSize, char* errorMessage) bool OpenGLShaderPrograms::CompileLayerPrograms(unsigned inputFrameWidth, unsigned inputFrameHeight, int errorMessageSize, char* errorMessage)
{ {
const std::vector<RuntimeRenderState> layerStates = mRuntimeSnapshotProvider.GetLayerRenderStates(inputFrameWidth, inputFrameHeight); const RuntimeRenderStateSnapshot renderSnapshot =
mRuntimeSnapshotProvider.GetRenderStateSnapshot(inputFrameWidth, inputFrameHeight);
const std::vector<RuntimeRenderState>& layerStates = renderSnapshot.states;
std::string temporalError; std::string temporalError;
const unsigned historyCap = mRuntimeHost.GetMaxTemporalHistoryFrames(); const unsigned historyCap = mRuntimeHost.GetMaxTemporalHistoryFrames();
if (!mRenderer.TemporalHistory().ValidateTextureUnitBudget(layerStates, historyCap, temporalError)) if (!mRenderer.TemporalHistory().ValidateTextureUnitBudget(layerStates, historyCap, temporalError))
@@ -88,7 +90,7 @@ bool OpenGLShaderPrograms::CompileLayerPrograms(unsigned inputFrameWidth, unsign
DestroyLayerPrograms(); DestroyLayerPrograms();
mRenderer.ReplaceLayerPrograms(newPrograms); mRenderer.ReplaceLayerPrograms(newPrograms);
mCommittedLayerStates = layerStates; mCommittedLayerStates = renderSnapshot.states;
mRuntimeHost.SetCompileStatus(true, "Shader layers compiled successfully."); mRuntimeHost.SetCompileStatus(true, "Shader layers compiled successfully.");
mRuntimeHost.ClearReloadRequest(); mRuntimeHost.ClearReloadRequest();
@@ -106,18 +108,18 @@ bool OpenGLShaderPrograms::CommitPreparedLayerPrograms(const PreparedShaderBuild
std::string temporalError; std::string temporalError;
const unsigned historyCap = mRuntimeHost.GetMaxTemporalHistoryFrames(); const unsigned historyCap = mRuntimeHost.GetMaxTemporalHistoryFrames();
if (!mRenderer.TemporalHistory().ValidateTextureUnitBudget(preparedBuild.layerStates, historyCap, temporalError)) if (!mRenderer.TemporalHistory().ValidateTextureUnitBudget(preparedBuild.renderSnapshot.states, historyCap, temporalError))
{ {
CopyErrorMessage(temporalError, errorMessageSize, errorMessage); CopyErrorMessage(temporalError, errorMessageSize, errorMessage);
return false; return false;
} }
if (!mRenderer.TemporalHistory().EnsureResources(preparedBuild.layerStates, historyCap, inputFrameWidth, inputFrameHeight, temporalError)) if (!mRenderer.TemporalHistory().EnsureResources(preparedBuild.renderSnapshot.states, historyCap, inputFrameWidth, inputFrameHeight, temporalError))
{ {
CopyErrorMessage(temporalError, errorMessageSize, errorMessage); CopyErrorMessage(temporalError, errorMessageSize, errorMessage);
return false; return false;
} }
if (mRenderer.ResourcesInitialized() && if (mRenderer.ResourcesInitialized() &&
!mRenderer.FeedbackBuffers().EnsureResources(preparedBuild.layerStates, inputFrameWidth, inputFrameHeight, temporalError)) !mRenderer.FeedbackBuffers().EnsureResources(preparedBuild.renderSnapshot.states, inputFrameWidth, inputFrameHeight, temporalError))
{ {
CopyErrorMessage(temporalError, errorMessageSize, errorMessage); CopyErrorMessage(temporalError, errorMessageSize, errorMessage);
return false; return false;
@@ -151,7 +153,7 @@ bool OpenGLShaderPrograms::CommitPreparedLayerPrograms(const PreparedShaderBuild
DestroyLayerPrograms(); DestroyLayerPrograms();
mRenderer.ReplaceLayerPrograms(newPrograms); mRenderer.ReplaceLayerPrograms(newPrograms);
mCommittedLayerStates = preparedBuild.layerStates; mCommittedLayerStates = preparedBuild.renderSnapshot.states;
mRuntimeHost.SetCompileStatus(true, "Shader layers compiled successfully."); mRuntimeHost.SetCompileStatus(true, "Shader layers compiled successfully.");
mRuntimeHost.ClearReloadRequest(); mRuntimeHost.ClearReloadRequest();

View File

@@ -111,10 +111,10 @@ PreparedShaderBuild ShaderBuildQueue::Build(uint64_t generation, unsigned output
{ {
PreparedShaderBuild build; PreparedShaderBuild build;
build.generation = generation; build.generation = generation;
build.layerStates = mRuntimeSnapshotProvider.GetLayerRenderStates(outputWidth, outputHeight); build.renderSnapshot = mRuntimeSnapshotProvider.GetRenderStateSnapshot(outputWidth, outputHeight);
build.layers.reserve(build.layerStates.size()); build.layers.reserve(build.renderSnapshot.states.size());
for (const RuntimeRenderState& state : build.layerStates) for (const RuntimeRenderState& state : build.renderSnapshot.states)
{ {
PreparedLayerShader layer; PreparedLayerShader layer;
layer.state = state; layer.state = state;

View File

@@ -21,7 +21,7 @@ struct PreparedShaderBuild
uint64_t generation = 0; uint64_t generation = 0;
bool succeeded = false; bool succeeded = false;
std::string message; std::string message;
std::vector<RuntimeRenderState> layerStates; RuntimeRenderStateSnapshot renderSnapshot;
std::vector<PreparedLayerShader> layers; std::vector<PreparedLayerShader> layers;
}; };

View File

@@ -0,0 +1,43 @@
#include "stdafx.h"
#include "HealthTelemetry.h"
#include "RuntimeHost.h"
HealthTelemetry::HealthTelemetry(RuntimeHost& runtimeHost) :
mRuntimeHost(runtimeHost)
{
}
void HealthTelemetry::ReportSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName)
{
mRuntimeHost.WriteSignalStatus(hasSignal, width, height, modeName);
}
bool HealthTelemetry::TryReportSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName)
{
return mRuntimeHost.TryWriteSignalStatus(hasSignal, width, height, modeName);
}
void HealthTelemetry::RecordPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds)
{
mRuntimeHost.WritePerformanceStats(frameBudgetMilliseconds, renderMilliseconds);
}
bool HealthTelemetry::TryRecordPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds)
{
return mRuntimeHost.TryWritePerformanceStats(frameBudgetMilliseconds, renderMilliseconds);
}
void HealthTelemetry::RecordFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount)
{
mRuntimeHost.WriteFramePacingStats(completionIntervalMilliseconds, smoothedCompletionIntervalMilliseconds,
maxCompletionIntervalMilliseconds, lateFrameCount, droppedFrameCount, flushedFrameCount);
}
bool HealthTelemetry::TryRecordFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount)
{
return mRuntimeHost.TryWriteFramePacingStats(completionIntervalMilliseconds, smoothedCompletionIntervalMilliseconds,
maxCompletionIntervalMilliseconds, lateFrameCount, droppedFrameCount, flushedFrameCount);
}

View File

@@ -0,0 +1,29 @@
#pragma once
#include <cstdint>
#include <string>
class RuntimeHost;
// Phase 1 compatibility seam for status and timing reporting. The current
// implementation still writes through RuntimeHost, but callers can now target
// HealthTelemetry as the home for operational visibility work.
class HealthTelemetry
{
public:
explicit HealthTelemetry(RuntimeHost& runtimeHost);
void ReportSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName);
bool TryReportSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName);
void RecordPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds);
bool TryRecordPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds);
void RecordFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount);
bool TryRecordFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount);
private:
RuntimeHost& mRuntimeHost;
};

View File

@@ -699,7 +699,8 @@ bool ParseParameterDefinitions(const JsonValue& manifestJson, ShaderPackage& sha
} }
RuntimeHost::RuntimeHost() RuntimeHost::RuntimeHost()
: mReloadRequested(false), : mHealthTelemetry(*this),
mReloadRequested(false),
mCompileSucceeded(false), mCompileSucceeded(false),
mHasSignal(false), mHasSignal(false),
mSignalWidth(0), mSignalWidth(0),
@@ -1351,12 +1352,22 @@ void RuntimeHost::SetCompileStatus(bool succeeded, const std::string& message)
} }
void RuntimeHost::SetSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName) void RuntimeHost::SetSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName)
{
mHealthTelemetry.ReportSignalStatus(hasSignal, width, height, modeName);
}
bool RuntimeHost::TrySetSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName)
{
return mHealthTelemetry.TryReportSignalStatus(hasSignal, width, height, modeName);
}
void RuntimeHost::WriteSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName)
{ {
std::lock_guard<std::mutex> lock(mMutex); std::lock_guard<std::mutex> lock(mMutex);
SetSignalStatusLocked(hasSignal, width, height, modeName); SetSignalStatusLocked(hasSignal, width, height, modeName);
} }
bool RuntimeHost::TrySetSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName) bool RuntimeHost::TryWriteSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName)
{ {
std::unique_lock<std::mutex> lock(mMutex, std::try_to_lock); std::unique_lock<std::mutex> lock(mMutex, std::try_to_lock);
if (!lock.owns_lock()) if (!lock.owns_lock())
@@ -1413,12 +1424,22 @@ void RuntimeHost::SetVideoIOStatus(const std::string& backendName, const std::st
} }
void RuntimeHost::SetPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds) void RuntimeHost::SetPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds)
{
mHealthTelemetry.RecordPerformanceStats(frameBudgetMilliseconds, renderMilliseconds);
}
bool RuntimeHost::TrySetPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds)
{
return mHealthTelemetry.TryRecordPerformanceStats(frameBudgetMilliseconds, renderMilliseconds);
}
void RuntimeHost::WritePerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds)
{ {
std::lock_guard<std::mutex> lock(mMutex); std::lock_guard<std::mutex> lock(mMutex);
SetPerformanceStatsLocked(frameBudgetMilliseconds, renderMilliseconds); SetPerformanceStatsLocked(frameBudgetMilliseconds, renderMilliseconds);
} }
bool RuntimeHost::TrySetPerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds) bool RuntimeHost::TryWritePerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds)
{ {
std::unique_lock<std::mutex> lock(mMutex, std::try_to_lock); std::unique_lock<std::mutex> lock(mMutex, std::try_to_lock);
if (!lock.owns_lock()) if (!lock.owns_lock())
@@ -1440,13 +1461,27 @@ void RuntimeHost::SetPerformanceStatsLocked(double frameBudgetMilliseconds, doub
void RuntimeHost::SetFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds, void RuntimeHost::SetFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount) double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount)
{
mHealthTelemetry.RecordFramePacingStats(completionIntervalMilliseconds, smoothedCompletionIntervalMilliseconds,
maxCompletionIntervalMilliseconds, lateFrameCount, droppedFrameCount, flushedFrameCount);
}
bool RuntimeHost::TrySetFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount)
{
return mHealthTelemetry.TryRecordFramePacingStats(completionIntervalMilliseconds, smoothedCompletionIntervalMilliseconds,
maxCompletionIntervalMilliseconds, lateFrameCount, droppedFrameCount, flushedFrameCount);
}
void RuntimeHost::WriteFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount)
{ {
std::lock_guard<std::mutex> lock(mMutex); std::lock_guard<std::mutex> lock(mMutex);
SetFramePacingStatsLocked(completionIntervalMilliseconds, smoothedCompletionIntervalMilliseconds, SetFramePacingStatsLocked(completionIntervalMilliseconds, smoothedCompletionIntervalMilliseconds,
maxCompletionIntervalMilliseconds, lateFrameCount, droppedFrameCount, flushedFrameCount); maxCompletionIntervalMilliseconds, lateFrameCount, droppedFrameCount, flushedFrameCount);
} }
bool RuntimeHost::TrySetFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds, bool RuntimeHost::TryWriteFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount) double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount)
{ {
std::unique_lock<std::mutex> lock(mMutex, std::try_to_lock); std::unique_lock<std::mutex> lock(mMutex, std::try_to_lock);

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "HealthTelemetry.h"
#include "RuntimeJson.h" #include "RuntimeJson.h"
#include "ShaderTypes.h" #include "ShaderTypes.h"
@@ -52,6 +53,8 @@ public:
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount); double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount);
void AdvanceFrame(); void AdvanceFrame();
bool TryAdvanceFrame(); bool TryAdvanceFrame();
HealthTelemetry& GetHealthTelemetry() { return mHealthTelemetry; }
const HealthTelemetry& GetHealthTelemetry() const { return mHealthTelemetry; }
bool BuildLayerPassFragmentShaderSources(const std::string& layerId, std::vector<ShaderPassBuildSource>& passSources, std::string& error); bool BuildLayerPassFragmentShaderSources(const std::string& layerId, std::vector<ShaderPassBuildSource>& passSources, std::string& error);
std::vector<RuntimeRenderState> GetLayerRenderStates(unsigned outputWidth, unsigned outputHeight) const; std::vector<RuntimeRenderState> GetLayerRenderStates(unsigned outputWidth, unsigned outputHeight) const;
@@ -145,14 +148,24 @@ private:
LayerPersistentState* FindLayerById(const std::string& layerId); LayerPersistentState* FindLayerById(const std::string& layerId);
const LayerPersistentState* FindLayerById(const std::string& layerId) const; const LayerPersistentState* FindLayerById(const std::string& layerId) const;
std::string GenerateLayerId(); std::string GenerateLayerId();
void WriteSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName);
bool TryWriteSignalStatus(bool hasSignal, unsigned width, unsigned height, const std::string& modeName);
void SetSignalStatusLocked(bool hasSignal, unsigned width, unsigned height, const std::string& modeName); void SetSignalStatusLocked(bool hasSignal, unsigned width, unsigned height, const std::string& modeName);
void MarkRenderStateDirtyLocked(); void MarkRenderStateDirtyLocked();
void MarkParameterStateDirtyLocked(); void MarkParameterStateDirtyLocked();
void WritePerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds);
bool TryWritePerformanceStats(double frameBudgetMilliseconds, double renderMilliseconds);
void SetPerformanceStatsLocked(double frameBudgetMilliseconds, double renderMilliseconds); void SetPerformanceStatsLocked(double frameBudgetMilliseconds, double renderMilliseconds);
void WriteFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount);
bool TryWriteFramePacingStats(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount);
void SetFramePacingStatsLocked(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds, void SetFramePacingStatsLocked(double completionIntervalMilliseconds, double smoothedCompletionIntervalMilliseconds,
double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount); double maxCompletionIntervalMilliseconds, uint64_t lateFrameCount, uint64_t droppedFrameCount, uint64_t flushedFrameCount);
private: private:
friend class HealthTelemetry;
HealthTelemetry mHealthTelemetry;
mutable std::mutex mMutex; mutable std::mutex mMutex;
AppConfig mConfig; AppConfig mConfig;
PersistentState mPersistentState; PersistentState mPersistentState;

View File

@@ -1,5 +1,7 @@
#include "RuntimeSnapshotProvider.h" #include "RuntimeSnapshotProvider.h"
#include <utility>
RuntimeSnapshotProvider::RuntimeSnapshotProvider(RuntimeHost& runtimeHost) : RuntimeSnapshotProvider::RuntimeSnapshotProvider(RuntimeHost& runtimeHost) :
mRuntimeHost(runtimeHost) mRuntimeHost(runtimeHost)
{ {
@@ -10,32 +12,142 @@ bool RuntimeSnapshotProvider::BuildLayerPassFragmentShaderSources(const std::str
return mRuntimeHost.BuildLayerPassFragmentShaderSources(layerId, passSources, error); return mRuntimeHost.BuildLayerPassFragmentShaderSources(layerId, passSources, error);
} }
RuntimeSnapshotVersions RuntimeSnapshotProvider::GetVersions() const
{
RuntimeSnapshotVersions versions;
versions.renderStateVersion = mRuntimeHost.GetRenderStateVersion();
versions.parameterStateVersion = mRuntimeHost.GetParameterStateVersion();
return versions;
}
RuntimeRenderFrameContext RuntimeSnapshotProvider::GetFrameContext() const
{
std::vector<RuntimeRenderState> stateScratch(1);
mRuntimeHost.RefreshDynamicRenderStateFields(stateScratch);
RuntimeRenderFrameContext frameContext;
const RuntimeRenderState& state = stateScratch.front();
frameContext.timeSeconds = state.timeSeconds;
frameContext.utcTimeSeconds = state.utcTimeSeconds;
frameContext.utcOffsetSeconds = state.utcOffsetSeconds;
frameContext.startupRandom = state.startupRandom;
frameContext.frameCount = state.frameCount;
return frameContext;
}
RuntimeRenderStateSnapshot RuntimeSnapshotProvider::GetRenderStateSnapshot(unsigned outputWidth, unsigned outputHeight) const
{
for (;;)
{
const RuntimeSnapshotVersions versionsBefore = GetVersions();
RuntimeRenderStateSnapshot snapshot;
snapshot.outputWidth = outputWidth;
snapshot.outputHeight = outputHeight;
snapshot.states = mRuntimeHost.GetLayerRenderStates(outputWidth, outputHeight);
const RuntimeSnapshotVersions versionsAfter = GetVersions();
if (versionsBefore.renderStateVersion == versionsAfter.renderStateVersion &&
versionsBefore.parameterStateVersion == versionsAfter.parameterStateVersion)
{
snapshot.versions = versionsAfter;
return snapshot;
}
}
}
bool RuntimeSnapshotProvider::TryGetRenderStateSnapshot(unsigned outputWidth, unsigned outputHeight, RuntimeRenderStateSnapshot& snapshot) const
{
const RuntimeSnapshotVersions versionsBefore = GetVersions();
std::vector<RuntimeRenderState> states;
if (!mRuntimeHost.TryGetLayerRenderStates(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);
return true;
}
bool RuntimeSnapshotProvider::TryRefreshSnapshotParameters(RuntimeRenderStateSnapshot& snapshot) const
{
const uint64_t expectedRenderStateVersion = snapshot.versions.renderStateVersion;
if (!mRuntimeHost.TryRefreshCachedLayerStates(snapshot.states))
return false;
const RuntimeSnapshotVersions versions = GetVersions();
if (versions.renderStateVersion != expectedRenderStateVersion)
return false;
snapshot.versions = versions;
return true;
}
void RuntimeSnapshotProvider::ApplyFrameContext(std::vector<RuntimeRenderState>& states, const RuntimeRenderFrameContext& frameContext) const
{
for (RuntimeRenderState& state : states)
{
state.timeSeconds = frameContext.timeSeconds;
state.utcTimeSeconds = frameContext.utcTimeSeconds;
state.utcOffsetSeconds = frameContext.utcOffsetSeconds;
state.startupRandom = frameContext.startupRandom;
state.frameCount = frameContext.frameCount;
}
}
void RuntimeSnapshotProvider::ApplyFrameContext(RuntimeRenderStateSnapshot& snapshot, const RuntimeRenderFrameContext& frameContext) const
{
ApplyFrameContext(snapshot.states, frameContext);
}
std::vector<RuntimeRenderState> RuntimeSnapshotProvider::GetLayerRenderStates(unsigned outputWidth, unsigned outputHeight) const std::vector<RuntimeRenderState> RuntimeSnapshotProvider::GetLayerRenderStates(unsigned outputWidth, unsigned outputHeight) const
{ {
return mRuntimeHost.GetLayerRenderStates(outputWidth, outputHeight); return GetRenderStateSnapshot(outputWidth, outputHeight).states;
} }
bool RuntimeSnapshotProvider::TryGetLayerRenderStates(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const bool RuntimeSnapshotProvider::TryGetLayerRenderStates(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const
{ {
return mRuntimeHost.TryGetLayerRenderStates(outputWidth, outputHeight, states); RuntimeRenderStateSnapshot snapshot;
if (!TryGetRenderStateSnapshot(outputWidth, outputHeight, snapshot))
return false;
states = std::move(snapshot.states);
return true;
} }
bool RuntimeSnapshotProvider::TryRefreshCachedLayerStates(std::vector<RuntimeRenderState>& states) const bool RuntimeSnapshotProvider::TryRefreshCachedLayerStates(std::vector<RuntimeRenderState>& states) const
{ {
return mRuntimeHost.TryRefreshCachedLayerStates(states); RuntimeRenderStateSnapshot snapshot;
snapshot.versions.renderStateVersion = mRuntimeHost.GetRenderStateVersion();
snapshot.versions.parameterStateVersion = mRuntimeHost.GetParameterStateVersion();
snapshot.states = states;
if (!TryRefreshSnapshotParameters(snapshot))
return false;
states = std::move(snapshot.states);
return true;
} }
void RuntimeSnapshotProvider::RefreshDynamicRenderStateFields(std::vector<RuntimeRenderState>& states) const void RuntimeSnapshotProvider::RefreshDynamicRenderStateFields(std::vector<RuntimeRenderState>& states) const
{ {
mRuntimeHost.RefreshDynamicRenderStateFields(states); ApplyFrameContext(states, GetFrameContext());
} }
uint64_t RuntimeSnapshotProvider::GetRenderStateVersion() const uint64_t RuntimeSnapshotProvider::GetRenderStateVersion() const
{ {
return mRuntimeHost.GetRenderStateVersion(); return GetVersions().renderStateVersion;
} }
uint64_t RuntimeSnapshotProvider::GetParameterStateVersion() const uint64_t RuntimeSnapshotProvider::GetParameterStateVersion() const
{ {
return mRuntimeHost.GetParameterStateVersion(); return GetVersions().parameterStateVersion;
} }

View File

@@ -6,12 +6,43 @@
#include <string> #include <string>
#include <vector> #include <vector>
struct RuntimeSnapshotVersions
{
uint64_t renderStateVersion = 0;
uint64_t parameterStateVersion = 0;
};
struct RuntimeRenderFrameContext
{
double timeSeconds = 0.0;
double utcTimeSeconds = 0.0;
double utcOffsetSeconds = 0.0;
double startupRandom = 0.0;
double frameCount = 0.0;
};
struct RuntimeRenderStateSnapshot
{
RuntimeSnapshotVersions versions;
unsigned outputWidth = 0;
unsigned outputHeight = 0;
std::vector<RuntimeRenderState> states;
};
class RuntimeSnapshotProvider class RuntimeSnapshotProvider
{ {
public: public:
explicit RuntimeSnapshotProvider(RuntimeHost& runtimeHost); explicit RuntimeSnapshotProvider(RuntimeHost& runtimeHost);
bool BuildLayerPassFragmentShaderSources(const std::string& layerId, std::vector<ShaderPassBuildSource>& passSources, std::string& error) const; bool BuildLayerPassFragmentShaderSources(const std::string& layerId, std::vector<ShaderPassBuildSource>& passSources, std::string& error) const;
RuntimeSnapshotVersions GetVersions() const;
RuntimeRenderFrameContext GetFrameContext() const;
RuntimeRenderStateSnapshot GetRenderStateSnapshot(unsigned outputWidth, unsigned outputHeight) const;
bool TryGetRenderStateSnapshot(unsigned outputWidth, unsigned outputHeight, RuntimeRenderStateSnapshot& snapshot) const;
bool TryRefreshSnapshotParameters(RuntimeRenderStateSnapshot& snapshot) const;
void ApplyFrameContext(std::vector<RuntimeRenderState>& states, const RuntimeRenderFrameContext& frameContext) const;
void ApplyFrameContext(RuntimeRenderStateSnapshot& snapshot, const RuntimeRenderFrameContext& frameContext) const;
std::vector<RuntimeRenderState> GetLayerRenderStates(unsigned outputWidth, unsigned outputHeight) const; std::vector<RuntimeRenderState> GetLayerRenderStates(unsigned outputWidth, unsigned outputHeight) const;
bool TryGetLayerRenderStates(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const; bool TryGetLayerRenderStates(unsigned outputWidth, unsigned outputHeight, std::vector<RuntimeRenderState>& states) const;
bool TryRefreshCachedLayerStates(std::vector<RuntimeRenderState>& states) const; bool TryRefreshCachedLayerStates(std::vector<RuntimeRenderState>& states) const;

View File

@@ -5,147 +5,147 @@ RuntimeStore::RuntimeStore(RuntimeHost& runtimeHost) :
{ {
} }
bool RuntimeStore::Initialize(std::string& error) bool RuntimeStore::InitializeStore(std::string& error)
{ {
return mRuntimeHost.Initialize(error); return mRuntimeHost.Initialize(error);
} }
bool RuntimeStore::AddLayer(const std::string& shaderId, std::string& error) std::string RuntimeStore::BuildPersistentStateJson() const
{
return mRuntimeHost.AddLayer(shaderId, error);
}
bool RuntimeStore::RemoveLayer(const std::string& layerId, std::string& error)
{
return mRuntimeHost.RemoveLayer(layerId, error);
}
bool RuntimeStore::MoveLayer(const std::string& layerId, int direction, std::string& error)
{
return mRuntimeHost.MoveLayer(layerId, direction, error);
}
bool RuntimeStore::MoveLayerToIndex(const std::string& layerId, std::size_t targetIndex, std::string& error)
{
return mRuntimeHost.MoveLayerToIndex(layerId, targetIndex, error);
}
bool RuntimeStore::SetLayerBypass(const std::string& layerId, bool bypassed, std::string& error)
{
return mRuntimeHost.SetLayerBypass(layerId, bypassed, error);
}
bool RuntimeStore::SetLayerShader(const std::string& layerId, const std::string& shaderId, std::string& error)
{
return mRuntimeHost.SetLayerShader(layerId, shaderId, error);
}
bool RuntimeStore::UpdateLayerParameter(const std::string& layerId, const std::string& parameterId, const JsonValue& newValue, std::string& error)
{
return mRuntimeHost.UpdateLayerParameter(layerId, parameterId, newValue, error);
}
bool RuntimeStore::UpdateLayerParameterByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue, std::string& error)
{
return mRuntimeHost.UpdateLayerParameterByControlKey(layerKey, parameterKey, newValue, error);
}
bool RuntimeStore::UpdateLayerParameterByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue, bool persistState, std::string& error)
{
return mRuntimeHost.UpdateLayerParameterByControlKey(layerKey, parameterKey, newValue, persistState, error);
}
bool RuntimeStore::ResetLayerParameters(const std::string& layerId, std::string& error)
{
return mRuntimeHost.ResetLayerParameters(layerId, error);
}
bool RuntimeStore::SaveStackPreset(const std::string& presetName, std::string& error) const
{
return mRuntimeHost.SaveStackPreset(presetName, error);
}
bool RuntimeStore::LoadStackPreset(const std::string& presetName, std::string& error)
{
return mRuntimeHost.LoadStackPreset(presetName, error);
}
std::string RuntimeStore::BuildStateJson() const
{ {
return mRuntimeHost.BuildStateJson(); return mRuntimeHost.BuildStateJson();
} }
const std::filesystem::path& RuntimeStore::GetRepoRoot() const bool RuntimeStore::CreateStoredLayer(const std::string& shaderId, std::string& error)
{
return mRuntimeHost.AddLayer(shaderId, error);
}
bool RuntimeStore::DeleteStoredLayer(const std::string& layerId, std::string& error)
{
return mRuntimeHost.RemoveLayer(layerId, error);
}
bool RuntimeStore::MoveStoredLayer(const std::string& layerId, int direction, std::string& error)
{
return mRuntimeHost.MoveLayer(layerId, direction, error);
}
bool RuntimeStore::MoveStoredLayerToIndex(const std::string& layerId, std::size_t targetIndex, std::string& error)
{
return mRuntimeHost.MoveLayerToIndex(layerId, targetIndex, error);
}
bool RuntimeStore::SetStoredLayerBypassState(const std::string& layerId, bool bypassed, std::string& error)
{
return mRuntimeHost.SetLayerBypass(layerId, bypassed, error);
}
bool RuntimeStore::SetStoredLayerShaderSelection(const std::string& layerId, const std::string& shaderId, std::string& error)
{
return mRuntimeHost.SetLayerShader(layerId, shaderId, error);
}
bool RuntimeStore::SetStoredParameterValue(const std::string& layerId, const std::string& parameterId, const JsonValue& newValue, std::string& error)
{
return mRuntimeHost.UpdateLayerParameter(layerId, parameterId, newValue, error);
}
bool RuntimeStore::SetStoredParameterValueByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue, std::string& error)
{
return mRuntimeHost.UpdateLayerParameterByControlKey(layerKey, parameterKey, newValue, error);
}
bool RuntimeStore::SetStoredParameterValueByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue, bool persistState, std::string& error)
{
return mRuntimeHost.UpdateLayerParameterByControlKey(layerKey, parameterKey, newValue, persistState, error);
}
bool RuntimeStore::ResetStoredLayerParameterValues(const std::string& layerId, std::string& error)
{
return mRuntimeHost.ResetLayerParameters(layerId, error);
}
bool RuntimeStore::SaveStackPresetSnapshot(const std::string& presetName, std::string& error) const
{
return mRuntimeHost.SaveStackPreset(presetName, error);
}
bool RuntimeStore::LoadStackPresetSnapshot(const std::string& presetName, std::string& error)
{
return mRuntimeHost.LoadStackPreset(presetName, error);
}
const std::filesystem::path& RuntimeStore::GetRuntimeRepositoryRoot() const
{ {
return mRuntimeHost.GetRepoRoot(); return mRuntimeHost.GetRepoRoot();
} }
const std::filesystem::path& RuntimeStore::GetUiRoot() const const std::filesystem::path& RuntimeStore::GetRuntimeUiRoot() const
{ {
return mRuntimeHost.GetUiRoot(); return mRuntimeHost.GetUiRoot();
} }
const std::filesystem::path& RuntimeStore::GetDocsRoot() const const std::filesystem::path& RuntimeStore::GetRuntimeDocsRoot() const
{ {
return mRuntimeHost.GetDocsRoot(); return mRuntimeHost.GetDocsRoot();
} }
const std::filesystem::path& RuntimeStore::GetRuntimeRoot() const const std::filesystem::path& RuntimeStore::GetRuntimeDataRoot() const
{ {
return mRuntimeHost.GetRuntimeRoot(); return mRuntimeHost.GetRuntimeRoot();
} }
unsigned short RuntimeStore::GetServerPort() const unsigned short RuntimeStore::GetConfiguredControlServerPort() const
{ {
return mRuntimeHost.GetServerPort(); return mRuntimeHost.GetServerPort();
} }
unsigned short RuntimeStore::GetOscPort() const unsigned short RuntimeStore::GetConfiguredOscPort() const
{ {
return mRuntimeHost.GetOscPort(); return mRuntimeHost.GetOscPort();
} }
const std::string& RuntimeStore::GetOscBindAddress() const const std::string& RuntimeStore::GetConfiguredOscBindAddress() const
{ {
return mRuntimeHost.GetOscBindAddress(); return mRuntimeHost.GetOscBindAddress();
} }
double RuntimeStore::GetOscSmoothing() const double RuntimeStore::GetConfiguredOscSmoothing() const
{ {
return mRuntimeHost.GetOscSmoothing(); return mRuntimeHost.GetOscSmoothing();
} }
unsigned RuntimeStore::GetMaxTemporalHistoryFrames() const unsigned RuntimeStore::GetConfiguredMaxTemporalHistoryFrames() const
{ {
return mRuntimeHost.GetMaxTemporalHistoryFrames(); return mRuntimeHost.GetMaxTemporalHistoryFrames();
} }
unsigned RuntimeStore::GetPreviewFps() const unsigned RuntimeStore::GetConfiguredPreviewFps() const
{ {
return mRuntimeHost.GetPreviewFps(); return mRuntimeHost.GetPreviewFps();
} }
bool RuntimeStore::ExternalKeyingEnabled() const bool RuntimeStore::IsExternalKeyingConfigured() const
{ {
return mRuntimeHost.ExternalKeyingEnabled(); return mRuntimeHost.ExternalKeyingEnabled();
} }
const std::string& RuntimeStore::GetInputVideoFormat() const const std::string& RuntimeStore::GetConfiguredInputVideoFormat() const
{ {
return mRuntimeHost.GetInputVideoFormat(); return mRuntimeHost.GetInputVideoFormat();
} }
const std::string& RuntimeStore::GetInputFrameRate() const const std::string& RuntimeStore::GetConfiguredInputFrameRate() const
{ {
return mRuntimeHost.GetInputFrameRate(); return mRuntimeHost.GetInputFrameRate();
} }
const std::string& RuntimeStore::GetOutputVideoFormat() const const std::string& RuntimeStore::GetConfiguredOutputVideoFormat() const
{ {
return mRuntimeHost.GetOutputVideoFormat(); return mRuntimeHost.GetOutputVideoFormat();
} }
const std::string& RuntimeStore::GetOutputFrameRate() const const std::string& RuntimeStore::GetConfiguredOutputFrameRate() const
{ {
return mRuntimeHost.GetOutputFrameRate(); return mRuntimeHost.GetOutputFrameRate();
} }

View File

@@ -10,38 +10,37 @@ class RuntimeStore
public: public:
explicit RuntimeStore(RuntimeHost& runtimeHost); explicit RuntimeStore(RuntimeHost& runtimeHost);
bool Initialize(std::string& error); bool InitializeStore(std::string& error);
std::string BuildPersistentStateJson() const;
bool AddLayer(const std::string& shaderId, std::string& error); bool CreateStoredLayer(const std::string& shaderId, std::string& error);
bool RemoveLayer(const std::string& layerId, std::string& error); bool DeleteStoredLayer(const std::string& layerId, std::string& error);
bool MoveLayer(const std::string& layerId, int direction, std::string& error); bool MoveStoredLayer(const std::string& layerId, int direction, std::string& error);
bool MoveLayerToIndex(const std::string& layerId, std::size_t targetIndex, std::string& error); bool MoveStoredLayerToIndex(const std::string& layerId, std::size_t targetIndex, std::string& error);
bool SetLayerBypass(const std::string& layerId, bool bypassed, std::string& error); bool SetStoredLayerBypassState(const std::string& layerId, bool bypassed, std::string& error);
bool SetLayerShader(const std::string& layerId, const std::string& shaderId, std::string& error); bool SetStoredLayerShaderSelection(const std::string& layerId, const std::string& shaderId, std::string& error);
bool UpdateLayerParameter(const std::string& layerId, const std::string& parameterId, const JsonValue& newValue, std::string& error); bool SetStoredParameterValue(const std::string& layerId, const std::string& parameterId, const JsonValue& newValue, std::string& error);
bool UpdateLayerParameterByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue, std::string& error); bool SetStoredParameterValueByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue, std::string& error);
bool UpdateLayerParameterByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue, bool persistState, std::string& error); bool SetStoredParameterValueByControlKey(const std::string& layerKey, const std::string& parameterKey, const JsonValue& newValue, bool persistState, std::string& error);
bool ResetLayerParameters(const std::string& layerId, std::string& error); bool ResetStoredLayerParameterValues(const std::string& layerId, std::string& error);
bool SaveStackPreset(const std::string& presetName, std::string& error) const; bool SaveStackPresetSnapshot(const std::string& presetName, std::string& error) const;
bool LoadStackPreset(const std::string& presetName, std::string& error); bool LoadStackPresetSnapshot(const std::string& presetName, std::string& error);
std::string BuildStateJson() const; const std::filesystem::path& GetRuntimeRepositoryRoot() const;
const std::filesystem::path& GetRuntimeUiRoot() const;
const std::filesystem::path& GetRepoRoot() const; const std::filesystem::path& GetRuntimeDocsRoot() const;
const std::filesystem::path& GetUiRoot() const; const std::filesystem::path& GetRuntimeDataRoot() const;
const std::filesystem::path& GetDocsRoot() const; unsigned short GetConfiguredControlServerPort() const;
const std::filesystem::path& GetRuntimeRoot() const; unsigned short GetConfiguredOscPort() const;
unsigned short GetServerPort() const; const std::string& GetConfiguredOscBindAddress() const;
unsigned short GetOscPort() const; double GetConfiguredOscSmoothing() const;
const std::string& GetOscBindAddress() const; unsigned GetConfiguredMaxTemporalHistoryFrames() const;
double GetOscSmoothing() const; unsigned GetConfiguredPreviewFps() const;
unsigned GetMaxTemporalHistoryFrames() const; bool IsExternalKeyingConfigured() const;
unsigned GetPreviewFps() const; const std::string& GetConfiguredInputVideoFormat() const;
bool ExternalKeyingEnabled() const; const std::string& GetConfiguredInputFrameRate() const;
const std::string& GetInputVideoFormat() const; const std::string& GetConfiguredOutputVideoFormat() const;
const std::string& GetInputFrameRate() const; const std::string& GetConfiguredOutputFrameRate() const;
const std::string& GetOutputVideoFormat() const;
const std::string& GetOutputFrameRate() const;
void SetCompileStatus(bool succeeded, const std::string& message); void SetCompileStatus(bool succeeded, const std::string& message);
void ClearReloadRequest(); void ClearReloadRequest();