further phase 1
Some checks failed
CI / React UI Build (push) Successful in 11s
CI / Native Windows Build And Tests (push) Successful in 2m39s
CI / Windows Release Package (push) Has been cancelled

This commit is contained in:
Aiden
2026-05-11 00:38:49 +10:00
parent 27dbb55f7b
commit ba4643dfa3
17 changed files with 359 additions and 332 deletions

View File

@@ -28,7 +28,6 @@ namespace
OpenGLComposite::OpenGLComposite(HWND hWnd, HDC hDC, HGLRC hRC) :
hGLWnd(hWnd), hGLDC(hDC), hGLRC(hRC),
mUseCommittedLayerStates(false),
mScreenshotRequested(false)
{
InitializeCriticalSection(&pMutex);
@@ -121,9 +120,11 @@ bool OpenGLComposite::InitVideoIO()
goto error;
}
PublishVideoIOStatus(mVideoBackend->OutputModelName().empty()
? "DeckLink output device selected."
: ("Selected output device: " + mVideoBackend->OutputModelName()));
mVideoBackend->PublishStatus(
mRuntimeStore && mRuntimeStore->IsExternalKeyingConfigured(),
mVideoBackend->OutputModelName().empty()
? "DeckLink output device selected."
: ("Selected output device: " + mVideoBackend->OutputModelName()));
// Resize window to match output video frame, but scale large formats down by half for viewing.
if (mVideoBackend->OutputFrameWidth() < 1920)
@@ -135,21 +136,17 @@ bool OpenGLComposite::InitVideoIO()
{
goto error;
}
if (!mVideoBackend->HasInputDevice() && mRuntimeHost)
{
mRuntimeHost->GetHealthTelemetry().ReportSignalStatus(
false,
mVideoBackend->InputFrameWidth(),
mVideoBackend->InputFrameHeight(),
mVideoBackend->InputDisplayModeName());
}
if (!mVideoBackend->HasInputDevice())
mVideoBackend->ReportNoInputDeviceSignalStatus();
if (!mVideoBackend->ConfigureOutput(videoModes.output, mRuntimeStore && mRuntimeStore->IsExternalKeyingConfigured(), initFailureReason))
{
goto error;
}
PublishVideoIOStatus(mVideoBackend->StatusMessage());
mVideoBackend->PublishStatus(
mRuntimeStore && mRuntimeStore->IsExternalKeyingConfigured(),
mVideoBackend->StatusMessage());
return true;
@@ -194,25 +191,6 @@ void OpenGLComposite::resizeWindow(int width, int height)
}
}
void OpenGLComposite::PublishVideoIOStatus(const std::string& statusMessage)
{
if (!mRuntimeHost)
return;
if (!statusMessage.empty())
mVideoBackend->SetStatusMessage(statusMessage);
mRuntimeHost->GetHealthTelemetry().ReportVideoIOStatus(
"decklink",
mVideoBackend->OutputModelName(),
mVideoBackend->SupportsInternalKeying(),
mVideoBackend->SupportsExternalKeying(),
mVideoBackend->KeyerInterfaceAvailable(),
mRuntimeStore ? mRuntimeStore->IsExternalKeyingConfigured() : false,
mVideoBackend->ExternalKeyingActive(),
mVideoBackend->StatusMessage());
}
bool OpenGLComposite::InitOpenGLState()
{
if (! ResolveGLExtensions())
@@ -264,13 +242,12 @@ bool OpenGLComposite::InitOpenGLState()
return false;
}
mRuntimeStore->SetCompileStatus(true, "Shader layers compiled successfully.");
mUseCommittedLayerStates = false;
mRenderEngine->ResetTemporalHistoryState();
mRenderEngine->ResetShaderFeedbackState();
broadcastRuntimeState();
mRuntimeServices->BeginPolling(*mRuntimeHost, *mRuntimeStore);
mRuntimeServices->BeginPolling(*mRuntimeStore);
return true;
}
@@ -287,7 +264,9 @@ bool OpenGLComposite::Stop()
const bool wasExternalKeyingActive = mVideoBackend->ExternalKeyingActive();
mVideoBackend->Stop();
if (wasExternalKeyingActive)
PublishVideoIOStatus("External keying has been disabled.");
mVideoBackend->PublishStatus(
mRuntimeStore && mRuntimeStore->IsExternalKeyingConfigured(),
"External keying has been disabled.");
return true;
}
@@ -340,7 +319,7 @@ void OpenGLComposite::renderEffect()
std::vector<RenderEngine::OscOverlayCommitRequest> overlayCommitRequests;
const double smoothing = mRuntimeStore ? mRuntimeStore->GetConfiguredOscSmoothing() : 0.0;
mRenderEngine->ResolveRenderLayerStates(
mUseCommittedLayerStates.load(),
mRuntimeCoordinator && mRuntimeCoordinator->UseCommittedLayerStates(),
mVideoBackend->InputFrameWidth(),
mVideoBackend->InputFrameHeight(),
smoothing,
@@ -439,20 +418,20 @@ bool OpenGLComposite::ProcessRuntimePollResults()
if (!events.reloadRequested)
{
PreparedShaderBuild readyBuild;
if (!mShaderBuildQueue || !mShaderBuildQueue->TryConsumeReadyBuild(readyBuild))
if (!mShaderBuildQueue || !mRenderEngine)
return true;
char compilerErrorMessage[1024] = {};
if (!mRenderEngine->ApplyPreparedShaderBuild(
readyBuild,
const RenderEngine::PreparedShaderBuildApplyResult buildResult = mRenderEngine->TryApplyReadyShaderBuild(
*mShaderBuildQueue,
mVideoBackend->InputFrameWidth(),
mVideoBackend->InputFrameHeight(),
mRuntimeCoordinator && mRuntimeCoordinator->PreserveFeedbackOnNextShaderBuild(),
sizeof(compilerErrorMessage),
compilerErrorMessage))
mRuntimeCoordinator && mRuntimeCoordinator->PreserveFeedbackOnNextShaderBuild());
if (!buildResult.hadReadyBuild)
return true;
if (!buildResult.applied)
{
ApplyRuntimeCoordinatorResult(mRuntimeCoordinator->HandlePreparedShaderBuildFailure(compilerErrorMessage));
ApplyRuntimeCoordinatorResult(mRuntimeCoordinator->HandlePreparedShaderBuildFailure(buildResult.errorMessage));
return false;
}
@@ -487,18 +466,8 @@ bool OpenGLComposite::ApplyRuntimeCoordinatorResult(const RuntimeCoordinatorResu
if (result.clearReloadRequest && mRuntimeStore)
mRuntimeStore->ClearReloadRequest();
switch (result.committedStateMode)
{
case RuntimeCoordinatorCommittedStateMode::UseCommittedStates:
mUseCommittedLayerStates = true;
break;
case RuntimeCoordinatorCommittedStateMode::UseLiveSnapshots:
mUseCommittedLayerStates = false;
break;
case RuntimeCoordinatorCommittedStateMode::Unchanged:
default:
break;
}
if (mRuntimeCoordinator)
mRuntimeCoordinator->ApplyCommittedStateMode(result.committedStateMode);
if (result.clearTransientOscState)
{
@@ -508,7 +477,8 @@ bool OpenGLComposite::ApplyRuntimeCoordinatorResult(const RuntimeCoordinatorResu
mRuntimeServices->ClearOscState();
}
ApplyRuntimeCoordinatorRenderReset(result.renderResetScope);
if (mRenderEngine)
mRenderEngine->ApplyRuntimeCoordinatorRenderReset(result.renderResetScope);
if (result.shaderBuildRequested)
RequestShaderBuild();
@@ -519,26 +489,6 @@ bool OpenGLComposite::ApplyRuntimeCoordinatorResult(const RuntimeCoordinatorResu
return true;
}
void OpenGLComposite::ApplyRuntimeCoordinatorRenderReset(RuntimeCoordinatorRenderResetScope resetScope)
{
if (!mRenderEngine)
return;
switch (resetScope)
{
case RuntimeCoordinatorRenderResetScope::TemporalHistoryOnly:
mRenderEngine->ResetTemporalHistoryState();
break;
case RuntimeCoordinatorRenderResetScope::TemporalHistoryAndFeedback:
mRenderEngine->ResetTemporalHistoryState();
mRenderEngine->ResetShaderFeedbackState();
break;
case RuntimeCoordinatorRenderResetScope::None:
default:
break;
}
}
void OpenGLComposite::broadcastRuntimeState()
{
if (mRuntimeServices)

View File

@@ -67,7 +67,6 @@ public:
private:
void resizeWindow(int width, int height);
bool CheckOpenGLExtensions();
void PublishVideoIOStatus(const std::string& statusMessage);
HWND hGLWnd;
HDC hGLDC;
@@ -82,7 +81,6 @@ private:
std::unique_ptr<ShaderBuildQueue> mShaderBuildQueue;
std::unique_ptr<RuntimeServices> mRuntimeServices;
std::unique_ptr<VideoBackend> mVideoBackend;
std::atomic<bool> mUseCommittedLayerStates;
std::atomic<bool> mScreenshotRequested;
bool InitOpenGLState();
@@ -90,7 +88,6 @@ private:
bool ProcessRuntimePollResults();
void RequestShaderBuild();
bool ApplyRuntimeCoordinatorResult(const RuntimeCoordinatorResult& result, std::string* error = nullptr);
void ApplyRuntimeCoordinatorRenderReset(RuntimeCoordinatorRenderResetScope resetScope);
void ProcessScreenshotRequest();
std::filesystem::path BuildScreenshotPath() const;
void broadcastRuntimeState();

View File

@@ -1,6 +1,7 @@
#include "RenderEngine.h"
#include "RuntimeParameterUtils.h"
#include "ShaderBuildQueue.h"
#include <gl/gl.h>
@@ -165,6 +166,35 @@ bool RenderEngine::ApplyPreparedShaderBuild(
return true;
}
RenderEngine::PreparedShaderBuildApplyResult RenderEngine::TryApplyReadyShaderBuild(
ShaderBuildQueue& shaderBuildQueue,
unsigned inputFrameWidth,
unsigned inputFrameHeight,
bool preserveFeedbackState)
{
PreparedShaderBuildApplyResult result;
PreparedShaderBuild readyBuild;
if (!shaderBuildQueue.TryConsumeReadyBuild(readyBuild))
return result;
result.hadReadyBuild = true;
char compilerErrorMessage[1024] = {};
if (!ApplyPreparedShaderBuild(
readyBuild,
inputFrameWidth,
inputFrameHeight,
preserveFeedbackState,
sizeof(compilerErrorMessage),
compilerErrorMessage))
{
result.errorMessage = compilerErrorMessage;
return result;
}
result.applied = true;
return result;
}
const std::vector<RuntimeRenderState>& RenderEngine::CommittedLayerStates() const
{
return mShaderPrograms.CommittedLayerStates();
@@ -180,6 +210,23 @@ void RenderEngine::ResetShaderFeedbackState()
mShaderPrograms.ResetShaderFeedbackState();
}
void RenderEngine::ApplyRuntimeCoordinatorRenderReset(RuntimeCoordinatorRenderResetScope resetScope)
{
switch (resetScope)
{
case RuntimeCoordinatorRenderResetScope::TemporalHistoryOnly:
ResetTemporalHistoryState();
break;
case RuntimeCoordinatorRenderResetScope::TemporalHistoryAndFeedback:
ResetTemporalHistoryState();
ResetShaderFeedbackState();
break;
case RuntimeCoordinatorRenderResetScope::None:
default:
break;
}
}
void RenderEngine::ClearOscOverlayState()
{
mOscOverlayStates.clear();

View File

@@ -5,6 +5,7 @@
#include "OpenGLRenderer.h"
#include "OpenGLShaderPrograms.h"
#include "HealthTelemetry.h"
#include "RuntimeCoordinator.h"
#include "RuntimeSnapshotProvider.h"
#include <windows.h>
@@ -16,6 +17,8 @@
#include <string>
#include <vector>
class ShaderBuildQueue;
class RenderEngine
{
public:
@@ -46,6 +49,13 @@ public:
uint64_t generation = 0;
};
struct PreparedShaderBuildApplyResult
{
bool hadReadyBuild = false;
bool applied = false;
std::string errorMessage;
};
RenderEngine(
RuntimeSnapshotProvider& runtimeSnapshotProvider,
HealthTelemetry& healthTelemetry,
@@ -76,10 +86,16 @@ public:
bool preserveFeedbackState,
int errorMessageSize,
char* errorMessage);
PreparedShaderBuildApplyResult TryApplyReadyShaderBuild(
ShaderBuildQueue& shaderBuildQueue,
unsigned inputFrameWidth,
unsigned inputFrameHeight,
bool preserveFeedbackState);
const std::vector<RuntimeRenderState>& CommittedLayerStates() const;
void ResetTemporalHistoryState();
void ResetShaderFeedbackState();
void ApplyRuntimeCoordinatorRenderReset(RuntimeCoordinatorRenderResetScope resetScope);
void ClearOscOverlayState();
void UpdateOscOverlayState(
const std::vector<OscOverlayUpdate>& updates,