diff --git a/CMakeLists.txt b/CMakeLists.txt
index 535d39e..75118ba 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -43,6 +43,8 @@ set(APP_SOURCES
"${APP_DIR}/control/OscServer.h"
"${APP_DIR}/control/RuntimeControlBridge.cpp"
"${APP_DIR}/control/RuntimeControlBridge.h"
+ "${APP_DIR}/control/RuntimeServices.cpp"
+ "${APP_DIR}/control/RuntimeServices.h"
"${APP_DIR}/decklink/DeckLinkDisplayMode.cpp"
"${APP_DIR}/decklink/DeckLinkDisplayMode.h"
"${APP_DIR}/decklink/DeckLinkFrameTransfer.cpp"
diff --git a/apps/LoopThroughWithOpenGLCompositing/LoopThroughWithOpenGLCompositing.vcxproj b/apps/LoopThroughWithOpenGLCompositing/LoopThroughWithOpenGLCompositing.vcxproj
index 205008f..ab541a0 100644
--- a/apps/LoopThroughWithOpenGLCompositing/LoopThroughWithOpenGLCompositing.vcxproj
+++ b/apps/LoopThroughWithOpenGLCompositing/LoopThroughWithOpenGLCompositing.vcxproj
@@ -207,6 +207,7 @@
+
@@ -221,6 +222,7 @@
+
diff --git a/apps/LoopThroughWithOpenGLCompositing/LoopThroughWithOpenGLCompositing.vcxproj.filters b/apps/LoopThroughWithOpenGLCompositing/LoopThroughWithOpenGLCompositing.vcxproj.filters
index c6841d4..7d368eb 100644
--- a/apps/LoopThroughWithOpenGLCompositing/LoopThroughWithOpenGLCompositing.vcxproj.filters
+++ b/apps/LoopThroughWithOpenGLCompositing/LoopThroughWithOpenGLCompositing.vcxproj.filters
@@ -48,6 +48,9 @@
DeckLink API
+
+ Source Files
+
Source Files
@@ -86,6 +89,9 @@
Header Files
+
+ Header Files
+
Header Files
diff --git a/apps/LoopThroughWithOpenGLCompositing/control/RuntimeServices.cpp b/apps/LoopThroughWithOpenGLCompositing/control/RuntimeServices.cpp
new file mode 100644
index 0000000..ff398a3
--- /dev/null
+++ b/apps/LoopThroughWithOpenGLCompositing/control/RuntimeServices.cpp
@@ -0,0 +1,119 @@
+#include "RuntimeServices.h"
+
+#include "ControlServer.h"
+#include "OscServer.h"
+#include "RuntimeControlBridge.h"
+#include "RuntimeHost.h"
+
+#include
+
+RuntimeServices::RuntimeServices() :
+ mControlServer(std::make_unique()),
+ mOscServer(std::make_unique()),
+ mPollRunning(false),
+ mRegistryChanged(false),
+ mReloadRequested(false),
+ mPollFailed(false)
+{
+}
+
+RuntimeServices::~RuntimeServices()
+{
+ Stop();
+}
+
+bool RuntimeServices::Start(OpenGLComposite& composite, RuntimeHost& runtimeHost, std::string& error)
+{
+ Stop();
+
+ if (!StartRuntimeControlServices(composite, runtimeHost, *mControlServer, *mOscServer, error))
+ {
+ Stop();
+ return false;
+ }
+
+ return true;
+}
+
+void RuntimeServices::BeginPolling(RuntimeHost& runtimeHost)
+{
+ StartPolling(runtimeHost);
+}
+
+void RuntimeServices::Stop()
+{
+ StopPolling();
+
+ if (mOscServer)
+ mOscServer->Stop();
+
+ if (mControlServer)
+ mControlServer->Stop();
+}
+
+void RuntimeServices::BroadcastState()
+{
+ if (mControlServer)
+ mControlServer->BroadcastState();
+}
+
+RuntimePollEvents RuntimeServices::ConsumePollEvents()
+{
+ RuntimePollEvents events;
+ events.registryChanged = mRegistryChanged.exchange(false);
+ events.reloadRequested = mReloadRequested.exchange(false);
+ events.failed = mPollFailed.exchange(false);
+
+ if (events.failed)
+ {
+ std::lock_guard 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)
+ {
+ bool registryChanged = false;
+ bool reloadRequested = false;
+ std::string runtimeError;
+ if (!runtimeHost.PollFileChanges(registryChanged, reloadRequested, runtimeError))
+ {
+ {
+ std::lock_guard 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);
+ }
+}
diff --git a/apps/LoopThroughWithOpenGLCompositing/control/RuntimeServices.h b/apps/LoopThroughWithOpenGLCompositing/control/RuntimeServices.h
new file mode 100644
index 0000000..29ba710
--- /dev/null
+++ b/apps/LoopThroughWithOpenGLCompositing/control/RuntimeServices.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+
+class ControlServer;
+class OpenGLComposite;
+class OscServer;
+class RuntimeHost;
+
+struct RuntimePollEvents
+{
+ bool registryChanged = false;
+ bool reloadRequested = false;
+ bool failed = false;
+ std::string error;
+};
+
+class RuntimeServices
+{
+public:
+ RuntimeServices();
+ ~RuntimeServices();
+
+ bool Start(OpenGLComposite& composite, RuntimeHost& runtimeHost, std::string& error);
+ void BeginPolling(RuntimeHost& runtimeHost);
+ void Stop();
+ void BroadcastState();
+ RuntimePollEvents ConsumePollEvents();
+
+private:
+ void StartPolling(RuntimeHost& runtimeHost);
+ void StopPolling();
+ void PollLoop(RuntimeHost& runtimeHost);
+
+ std::unique_ptr mControlServer;
+ std::unique_ptr mOscServer;
+ std::thread mPollThread;
+ std::atomic mPollRunning;
+ std::atomic mRegistryChanged;
+ std::atomic mReloadRequested;
+ std::atomic mPollFailed;
+ std::mutex mPollErrorMutex;
+ std::string mPollError;
+};
diff --git a/apps/LoopThroughWithOpenGLCompositing/gl/OpenGLComposite.cpp b/apps/LoopThroughWithOpenGLCompositing/gl/OpenGLComposite.cpp
index bc6b05c..2d10b12 100644
--- a/apps/LoopThroughWithOpenGLCompositing/gl/OpenGLComposite.cpp
+++ b/apps/LoopThroughWithOpenGLCompositing/gl/OpenGLComposite.cpp
@@ -1,44 +1,3 @@
-/* -LICENSE-START-
- ** Copyright (c) 2012 Blackmagic Design
- **
- ** Permission is hereby granted, free of charge, to any person or organization
- ** obtaining a copy of the software and accompanying documentation (the
- ** "Software") to use, reproduce, display, distribute, sub-license, execute,
- ** and transmit the Software, and to prepare derivative works of the Software,
- ** and to permit third-parties to whom the Software is furnished to do so, in
- ** accordance with:
- **
- ** (1) if the Software is obtained from Blackmagic Design, the End User License
- ** Agreement for the Software Development Kit ("EULA") available at
- ** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or
- **
- ** (2) if the Software is obtained from any third party, such licensing terms
- ** as notified by that third party,
- **
- ** and all subject to the following:
- **
- ** (3) the copyright notices in the Software and this entire statement,
- ** including the above license grant, this restriction and the following
- ** disclaimer, must be included in all copies of the Software, in whole or in
- ** part, and all derivative works of the Software, unless such copies or
- ** derivative works are solely in the form of machine-executable object code
- ** generated by a source language processor.
- **
- ** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
- ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
- ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
- ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- ** DEALINGS IN THE SOFTWARE.
- **
- ** A copy of the Software is available free of charge at
- ** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA.
- **
- ** -LICENSE-END-
- */
-
-#include "ControlServer.h"
#include "DeckLinkDisplayMode.h"
#include "DeckLinkFrameTransfer.h"
#include "DeckLinkSession.h"
@@ -48,22 +7,16 @@
#include "OpenGLDeckLinkBridge.h"
#include "OpenGLRenderPass.h"
#include "OpenGLShaderPrograms.h"
-#include "OscServer.h"
-#include "RuntimeControlBridge.h"
+#include "RuntimeServices.h"
#include
#include
-#include
#include
OpenGLComposite::OpenGLComposite(HWND hWnd, HDC hDC, HGLRC hRC) :
hGLWnd(hWnd), hGLDC(hDC), hGLRC(hRC),
mDeckLink(std::make_unique()),
- mRenderer(std::make_unique()),
- mRuntimePollRunning(false),
- mRuntimeRegistryChanged(false),
- mRuntimeReloadRequested(false),
- mRuntimePollFailed(false)
+ mRenderer(std::make_unique())
{
InitializeCriticalSection(&pMutex);
mRuntimeHost = std::make_unique();
@@ -78,19 +31,15 @@ OpenGLComposite::OpenGLComposite(HWND hWnd, HDC hDC, HGLRC hRC) :
[this]() { paintGL(); });
mRenderPass = std::make_unique(*mRenderer);
mShaderPrograms = std::make_unique(*mRenderer, *mRuntimeHost);
- mControlServer = std::make_unique();
- mOscServer = std::make_unique();
+ mRuntimeServices = std::make_unique();
}
OpenGLComposite::~OpenGLComposite()
{
- StopRuntimePolling();
+ if (mRuntimeServices)
+ mRuntimeServices->Stop();
mDeckLink->ReleaseResources();
mRenderer->DestroyResources();
- if (mOscServer)
- mOscServer->Stop();
- if (mControlServer)
- mControlServer->Stop();
DeleteCriticalSection(&pMutex);
}
@@ -255,7 +204,7 @@ bool OpenGLComposite::InitOpenGLState()
return false;
}
- if (!StartRuntimeControlServices(*this, *mRuntimeHost, *mControlServer, *mOscServer, runtimeError))
+ if (!mRuntimeServices->Start(*this, *mRuntimeHost, runtimeError))
{
MessageBoxA(NULL, runtimeError.c_str(), "Runtime control services failed to start", MB_OK);
return false;
@@ -284,7 +233,7 @@ bool OpenGLComposite::InitOpenGLState()
}
broadcastRuntimeState();
- StartRuntimePolling();
+ mRuntimeServices->BeginPolling(*mRuntimeHost);
return true;
}
@@ -306,13 +255,8 @@ bool OpenGLComposite::Start()
bool OpenGLComposite::Stop()
{
- StopRuntimePolling();
-
- if (mOscServer)
- mOscServer->Stop();
-
- if (mControlServer)
- mControlServer->Stop();
+ if (mRuntimeServices)
+ mRuntimeServices->Stop();
const bool wasExternalKeyingActive = mDeckLink->ExternalKeyingActive();
mDeckLink->Stop();
@@ -380,72 +324,23 @@ void OpenGLComposite::renderEffect()
});
}
-void OpenGLComposite::StartRuntimePolling()
-{
- if (!mRuntimeHost || mRuntimePollRunning.exchange(true))
- return;
-
- mRuntimePollThread = std::thread([this]() { RuntimePollLoop(); });
-}
-
-void OpenGLComposite::StopRuntimePolling()
-{
- if (!mRuntimePollRunning.exchange(false))
- return;
-
- if (mRuntimePollThread.joinable())
- mRuntimePollThread.join();
-}
-
-void OpenGLComposite::RuntimePollLoop()
-{
- while (mRuntimePollRunning)
- {
- bool registryChanged = false;
- bool reloadRequested = false;
- std::string runtimeError;
- if (!mRuntimeHost->PollFileChanges(registryChanged, reloadRequested, runtimeError))
- {
- {
- std::lock_guard lock(mRuntimePollErrorMutex);
- mRuntimePollError = runtimeError;
- }
- mRuntimePollFailed = true;
- }
- else
- {
- if (registryChanged)
- mRuntimeRegistryChanged = true;
- if (reloadRequested)
- mRuntimeReloadRequested = true;
- }
-
- for (int i = 0; i < 25 && mRuntimePollRunning; ++i)
- Sleep(10);
- }
-}
-
bool OpenGLComposite::ProcessRuntimePollResults()
{
- if (!mRuntimeHost)
+ if (!mRuntimeHost || !mRuntimeServices)
return true;
- if (mRuntimePollFailed.exchange(false))
+ const RuntimePollEvents events = mRuntimeServices->ConsumePollEvents();
+ if (events.failed)
{
- std::string runtimeError;
- {
- std::lock_guard lock(mRuntimePollErrorMutex);
- runtimeError = mRuntimePollError;
- }
- mRuntimeHost->SetCompileStatus(false, runtimeError);
+ mRuntimeHost->SetCompileStatus(false, events.error);
broadcastRuntimeState();
return false;
}
- if (mRuntimeRegistryChanged.exchange(false))
+ if (events.registryChanged)
broadcastRuntimeState();
- if (!mRuntimeReloadRequested.exchange(false))
+ if (!events.reloadRequested)
return true;
char compilerErrorMessage[1024] = {};
@@ -464,8 +359,8 @@ bool OpenGLComposite::ProcessRuntimePollResults()
void OpenGLComposite::broadcastRuntimeState()
{
- if (mControlServer)
- mControlServer->BroadcastState();
+ if (mRuntimeServices)
+ mRuntimeServices->BroadcastState();
}
void OpenGLComposite::resetTemporalHistoryState()
diff --git a/apps/LoopThroughWithOpenGLCompositing/gl/OpenGLComposite.h b/apps/LoopThroughWithOpenGLCompositing/gl/OpenGLComposite.h
index 5586758..1fc5005 100644
--- a/apps/LoopThroughWithOpenGLCompositing/gl/OpenGLComposite.h
+++ b/apps/LoopThroughWithOpenGLCompositing/gl/OpenGLComposite.h
@@ -1,43 +1,3 @@
-/* -LICENSE-START-
- ** Copyright (c) 2012 Blackmagic Design
- **
- ** Permission is hereby granted, free of charge, to any person or organization
- ** obtaining a copy of the software and accompanying documentation (the
- ** "Software") to use, reproduce, display, distribute, sub-license, execute,
- ** and transmit the Software, and to prepare derivative works of the Software,
- ** and to permit third-parties to whom the Software is furnished to do so, in
- ** accordance with:
- **
- ** (1) if the Software is obtained from Blackmagic Design, the End User License
- ** Agreement for the Software Development Kit ("EULA") available at
- ** https://www.blackmagicdesign.com/EULA/DeckLinkSDK; or
- **
- ** (2) if the Software is obtained from any third party, such licensing terms
- ** as notified by that third party,
- **
- ** and all subject to the following:
- **
- ** (3) the copyright notices in the Software and this entire statement,
- ** including the above license grant, this restriction and the following
- ** disclaimer, must be included in all copies of the Software, in whole or in
- ** part, and all derivative works of the Software, unless such copies or
- ** derivative works are solely in the form of machine-executable object code
- ** generated by a source language processor.
- **
- ** (4) THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- ** FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
- ** SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
- ** FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
- ** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- ** DEALINGS IN THE SOFTWARE.
- **
- ** A copy of the Software is available free of charge at
- ** https://www.blackmagicdesign.com/desktopvideo_sdk under the EULA.
- **
- ** -LICENSE-END-
- */
-
#ifndef __OPENGL_COMPOSITE_H__
#define __OPENGL_COMPOSITE_H__
@@ -56,22 +16,18 @@
#include "OpenGLRenderer.h"
#include "RuntimeHost.h"
-#include
#include
#include