diff --git a/idd/LGIdd/Device.cpp b/idd/LGIdd/Device.cpp
index 0fe9b230..e5d6ee4a 100644
--- a/idd/LGIdd/Device.cpp
+++ b/idd/LGIdd/Device.cpp
@@ -34,10 +34,10 @@
#include "CDebug.h"
#include "display/CDisplayConfiguration.h"
#include "display/IddCxCompat.h"
-#include "display/device/CDeviceContext.h"
-#include "display/monitor/Context.h"
+#include "display/CDeviceContext.h"
+#include "display/CMonitorContext.h"
#include "transport/IControlTransport.h"
-#include "transport/CPipeServer.h"
+#include "ipc/CPipeServer.h"
#include "config/CSettings.h"
WDFDEVICE l_wdfDevice = nullptr;
diff --git a/idd/LGIdd/Driver.cpp b/idd/LGIdd/Driver.cpp
index 47ea777d..c6dc8e9d 100644
--- a/idd/LGIdd/Driver.cpp
+++ b/idd/LGIdd/Driver.cpp
@@ -24,7 +24,7 @@
#include "CDebug.h"
#include "platform/CPlatformInfo.h"
#include "VersionInfo.h"
-#include "transport/CPipeServer.h"
+#include "ipc/CPipeServer.h"
NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
diff --git a/idd/LGIdd/LGIdd.vcxproj b/idd/LGIdd/LGIdd.vcxproj
index dbec06b7..eb0c3bc5 100644
--- a/idd/LGIdd/LGIdd.vcxproj
+++ b/idd/LGIdd/LGIdd.vcxproj
@@ -27,20 +27,20 @@
+
-
-
+
+
+
-
-
@@ -52,8 +52,6 @@
-
-
@@ -69,16 +67,19 @@
+
-
-
+
+
+
+
@@ -94,15 +95,13 @@
-
-
-
+
+
-
diff --git a/idd/LGIdd/LGIdd.vcxproj.filters b/idd/LGIdd/LGIdd.vcxproj.filters
index e9fe9002..8c7e3b6f 100644
--- a/idd/LGIdd/LGIdd.vcxproj.filters
+++ b/idd/LGIdd/LGIdd.vcxproj.filters
@@ -5,15 +5,12 @@
{4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+
+ {6A9D97A5-1A6C-4A95-A2D0-A7C2D6BE459D}
+
{D2C16E51-6087-4E08-8DA4-5AD1A60EF58E}
-
- {83AAC4D0-9E4C-4B25-BD54-9186713B2010}
-
-
- {3AF4227D-EBC0-45FB-9670-192E371313D5}
-
{202B79B2-5CCF-4AD4-B4C5-F5602419683D}
@@ -70,6 +67,9 @@
Driver
+
+ IPC
+
Display
@@ -82,11 +82,11 @@
Display
-
- Display\Device
+
+ Display
-
- Display\Monitor
+
+ Display
Capture
@@ -100,6 +100,12 @@
Capture
+
+ Capture
+
+
+ Capture
+
Capture
@@ -145,13 +151,7 @@
Post-processing\Effects
-
- Transport
-
-
- Transport
-
-
+
Transport
@@ -166,10 +166,10 @@
Transport
-
+
Transport
-
+
Transport
@@ -207,6 +207,9 @@
Driver
+
+ IPC
+
Display
@@ -216,11 +219,11 @@
Display
-
- Display\Device
+
+ Display
-
- Display\Monitor
+
+ Display
Capture
@@ -234,21 +237,18 @@
Capture
+
+ Capture
+
Capture
Capture
-
- Capture
-
Capture
-
- Capture
-
D3D
@@ -282,12 +282,6 @@
Post-processing\Effects
-
- Transport
-
-
- Transport
-
Transport
diff --git a/idd/LGIdd/capture/CFrameBufferPool.h b/idd/LGIdd/capture/CFrameBufferPool.h
index c34a333c..dc7bc7fb 100644
--- a/idd/LGIdd/capture/CFrameBufferPool.h
+++ b/idd/LGIdd/capture/CFrameBufferPool.h
@@ -21,8 +21,8 @@
#pragma once
#include "capture/CFrameBufferResource.h"
-#include "transport/FrameBufferTypes.h"
-#include "transport/TransportTypes.h"
+#include "capture/FramePipeline.h"
+#include "transport/PreparedFrameBuffer.h"
struct CD3D12Device;
class IFrameTransport;
@@ -33,7 +33,7 @@ private:
IFrameTransport * m_transport = nullptr;
CD3D12Device * m_dx12 = nullptr;
- CFrameBufferResource m_buffers[TRANSPORT_FRAME_BUFFER_COUNT];
+ CFrameBufferResource m_buffers[CAPTURE_FRAME_BUFFERS];
public:
void Init(IFrameTransport * transport, CD3D12Device * dx12);
diff --git a/idd/LGIdd/capture/CFrameBufferResource.h b/idd/LGIdd/capture/CFrameBufferResource.h
index 1cf27bb3..8863cad1 100644
--- a/idd/LGIdd/capture/CFrameBufferResource.h
+++ b/idd/LGIdd/capture/CFrameBufferResource.h
@@ -27,7 +27,7 @@
#include
#include
-#include "transport/CFrameScheduler.h"
+#include "capture/CFrameScheduler.h"
#include "d3d/CInteropResource.h"
struct CD3D12Device;
diff --git a/idd/LGIdd/capture/CFrameProcessor.cpp b/idd/LGIdd/capture/CFrameProcessor.cpp
index ac4a34b4..bbce75f5 100644
--- a/idd/LGIdd/capture/CFrameProcessor.cpp
+++ b/idd/LGIdd/capture/CFrameProcessor.cpp
@@ -29,7 +29,7 @@
CFrameProcessor::CFrameProcessor(IFrameTransport * transport,
std::shared_ptr dx12,
- CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
+ CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
SRWLOCK * pipelineLock, HANDLE terminateEvent) :
m_transport(transport),
m_dx12(std::move(dx12)),
@@ -156,7 +156,7 @@ void CFrameProcessor::GetPreviousDamage(
std::unique_ptr CreateFrameProcessor(
bool software, IFrameTransport * transport,
std::shared_ptr dx12,
- CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
+ CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
SRWLOCK * pipelineLock, HANDLE terminateEvent)
{
std::unique_ptr processor;
diff --git a/idd/LGIdd/capture/CFrameProcessor.h b/idd/LGIdd/capture/CFrameProcessor.h
index 46e92960..eb8afd40 100644
--- a/idd/LGIdd/capture/CFrameProcessor.h
+++ b/idd/LGIdd/capture/CFrameProcessor.h
@@ -24,8 +24,8 @@
#include "capture/CFrameBufferPool.h"
#include "d3d/CInteropResource.h"
#include "postprocess/CPostProcessor.h"
-#include "transport/CFrameScheduler.h"
-#include "transport/TransportTypes.h"
+#include "capture/CFrameScheduler.h"
+#include "capture/FramePipeline.h"
#include
#include
@@ -76,7 +76,7 @@ protected:
public:
CFrameProcessor(IFrameTransport * transport,
std::shared_ptr dx12,
- CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
+ CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
SRWLOCK * pipelineLock, HANDLE terminateEvent);
virtual ~CFrameProcessor() = default;
@@ -98,5 +98,5 @@ public:
std::unique_ptr CreateFrameProcessor(
bool software, IFrameTransport * transport,
std::shared_ptr dx12,
- CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
+ CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
SRWLOCK * pipelineLock, HANDLE terminateEvent);
diff --git a/idd/LGIdd/transport/CFrameScheduler.cpp b/idd/LGIdd/capture/CFrameScheduler.cpp
similarity index 99%
rename from idd/LGIdd/transport/CFrameScheduler.cpp
rename to idd/LGIdd/capture/CFrameScheduler.cpp
index c13aa54c..b3c409fb 100644
--- a/idd/LGIdd/transport/CFrameScheduler.cpp
+++ b/idd/LGIdd/capture/CFrameScheduler.cpp
@@ -18,7 +18,7 @@
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "transport/CFrameScheduler.h"
+#include "capture/CFrameScheduler.h"
#include "CDebug.h"
@@ -288,10 +288,10 @@ void CFrameScheduler::UpdateSubscribers(const uint32_t * clientIDs,
{
AcquireSRWLockExclusive(&m_lock);
- uint32_t oldClientIDs [TRANSPORT_MAX_CLIENTS] = {};
- bool wasSubscribed [TRANSPORT_MAX_CLIENTS] = {};
- bool wasOwnerCapable[TRANSPORT_MAX_CLIENTS] = {};
- unsigned clientIndex = 0;
+ uint32_t oldClientIDs [MAX_CLIENTS] = {};
+ bool wasSubscribed [MAX_CLIENTS] = {};
+ bool wasOwnerCapable[MAX_CLIENTS] = {};
+ unsigned clientIndex = 0;
for (const Client& client : m_clients)
{
oldClientIDs[clientIndex] = client.clientID;
diff --git a/idd/LGIdd/transport/CFrameScheduler.h b/idd/LGIdd/capture/CFrameScheduler.h
similarity index 87%
rename from idd/LGIdd/transport/CFrameScheduler.h
rename to idd/LGIdd/capture/CFrameScheduler.h
index ef90392b..cd3dce4d 100644
--- a/idd/LGIdd/transport/CFrameScheduler.h
+++ b/idd/LGIdd/capture/CFrameScheduler.h
@@ -23,11 +23,33 @@
#include
#include
-#include "transport/TransportTypes.h"
+enum : uint32_t
+{
+ FRAME_SCHEDULE_ACTIVE = 0x1,
+ FRAME_SCHEDULE_RELEASE = 0x2,
+ FRAME_SCHEDULE_RESET = 0x4,
+ FRAME_SCHEDULE_IMMEDIATE = 0x8,
+};
+
+struct FrameScheduleUpdate
+{
+ uint32_t clientID;
+ uint32_t generation;
+ uint32_t flags;
+ uint64_t period;
+ uint64_t targetSlack;
+ int64_t phaseError;
+ uint32_t feedbackFrameSerial;
+ uint32_t feedbackScheduleEpoch;
+ uint32_t feedbackDeadlineSerial;
+ uint32_t lease;
+};
class CFrameScheduler
{
public:
+ static const unsigned MAX_CLIENTS = 8;
+
struct Schedule
{
uint32_t clientID;
@@ -78,12 +100,12 @@ private:
static const unsigned PUBLICATION_HISTORY_SIZE = 128;
static const unsigned WORK_TIMING_HISTORY_SIZE = 32;
- mutable SRWLOCK m_lock = SRWLOCK_INIT;
- HANDLE m_wakeEvent = nullptr;
- Client m_clients[TRANSPORT_MAX_CLIENTS] = {};
- Schedule m_schedule = {};
- bool m_scheduling = false;
- uint32_t m_epoch = 0;
+ mutable SRWLOCK m_lock = SRWLOCK_INIT;
+ HANDLE m_wakeEvent = nullptr;
+ Client m_clients[MAX_CLIENTS] = {};
+ Schedule m_schedule = {};
+ bool m_scheduling = false;
+ uint32_t m_epoch = 0;
// A result acknowledges only the request tickets captured by its attempt.
uint64_t m_forceRequestTicket = 0;
diff --git a/idd/LGIdd/capture/CHardwareFrameProcessor.cpp b/idd/LGIdd/capture/CHardwareFrameProcessor.cpp
index a94512ad..bcad171e 100644
--- a/idd/LGIdd/capture/CHardwareFrameProcessor.cpp
+++ b/idd/LGIdd/capture/CHardwareFrameProcessor.cpp
@@ -29,7 +29,7 @@
using namespace Microsoft::WRL;
-static_assert(TRANSPORT_FRAME_QUEUE_LENGTH == 2,
+static_assert(CAPTURE_PIPELINE_SLOTS == 2,
"IDD candidate pipeline assumes two slots");
class CPublishPending
@@ -72,7 +72,7 @@ public:
CHardwareFrameProcessor::CHardwareFrameProcessor(
IFrameTransport * transport, std::shared_ptr dx12,
- CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
+ CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
SRWLOCK * pipelineLock, HANDLE terminateEvent) :
CFrameProcessor(transport, std::move(dx12), postProcessors,
pipelineLock, terminateEvent)
diff --git a/idd/LGIdd/capture/CHardwareFrameProcessor.h b/idd/LGIdd/capture/CHardwareFrameProcessor.h
index 6136f828..025a2b28 100644
--- a/idd/LGIdd/capture/CHardwareFrameProcessor.h
+++ b/idd/LGIdd/capture/CHardwareFrameProcessor.h
@@ -65,8 +65,8 @@ private:
bool active = false;
};
- FrameCandidate m_candidates[TRANSPORT_FRAME_QUEUE_LENGTH];
- CandidateDamageTail m_candidateDamageTail[TRANSPORT_FRAME_QUEUE_LENGTH];
+ FrameCandidate m_candidates[CAPTURE_PIPELINE_SLOTS];
+ CandidateDamageTail m_candidateDamageTail[CAPTURE_PIPELINE_SLOTS];
mutable SRWLOCK m_candidateLock = SRWLOCK_INIT;
SRWLOCK m_copySubmitLock = SRWLOCK_INIT;
uint64_t m_candidateSequence = 0;
@@ -91,7 +91,7 @@ private:
public:
CHardwareFrameProcessor(IFrameTransport * transport,
std::shared_ptr dx12,
- CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
+ CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
SRWLOCK * pipelineLock, HANDLE terminateEvent);
bool IsValid() const override;
diff --git a/idd/LGIdd/capture/CSoftwareFrameProcessor.cpp b/idd/LGIdd/capture/CSoftwareFrameProcessor.cpp
index fba9b60d..1153a644 100644
--- a/idd/LGIdd/capture/CSoftwareFrameProcessor.cpp
+++ b/idd/LGIdd/capture/CSoftwareFrameProcessor.cpp
@@ -20,7 +20,7 @@
#include "capture/CSoftwareFrameProcessor.h"
#include "capture/CFrameProcessorUtil.h"
-#include "transport/TransportTypes.h"
+#include "capture/FramePipeline.h"
#include "transport/IFrameTransport.h"
#include "util/CSRWLock.h"
#include "CDebug.h"
@@ -29,7 +29,7 @@
CSoftwareFrameProcessor::CSoftwareFrameProcessor(
IFrameTransport * transport, std::shared_ptr dx12,
- CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
+ CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
SRWLOCK * pipelineLock, HANDLE terminateEvent) :
CFrameProcessor(transport, std::move(dx12), postProcessors,
pipelineLock, terminateEvent),
diff --git a/idd/LGIdd/capture/CSoftwareFrameProcessor.h b/idd/LGIdd/capture/CSoftwareFrameProcessor.h
index 59d53e76..85aa48fb 100644
--- a/idd/LGIdd/capture/CSoftwareFrameProcessor.h
+++ b/idd/LGIdd/capture/CSoftwareFrameProcessor.h
@@ -33,7 +33,7 @@ private:
public:
CSoftwareFrameProcessor(IFrameTransport * transport,
std::shared_ptr dx12,
- CPostProcessor postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH],
+ CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
SRWLOCK * pipelineLock, HANDLE terminateEvent);
bool Submit(const FrameSubmission& submission) override;
diff --git a/idd/LGIdd/capture/CSwapChainCursor.cpp b/idd/LGIdd/capture/CSwapChainCursor.cpp
deleted file mode 100644
index 67194e49..00000000
--- a/idd/LGIdd/capture/CSwapChainCursor.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * Looking Glass
- * Copyright © 2017-2026 The Looking Glass Authors
- * https://looking-glass.io
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "capture/CSwapChainProcessor.h"
-
-#include "display/IddCxCompat.h"
-#include "display/device/CDeviceContext.h"
-#include "transport/IControlTransport.h"
-
-#include "CDebug.h"
-
-DWORD CALLBACK CSwapChainProcessor::_CursorThread(LPVOID arg)
-{
- reinterpret_cast(arg)->CursorThread();
- return 0;
-}
-
-bool CSwapChainProcessor::QueryHWCursor()
-{
- IDARG_IN_QUERY_HWCURSOR in = {};
- in.LastShapeId = m_lastShapeId;
- in.pShapeBuffer = m_shapeBuffer;
- in.ShapeBufferSizeInBytes = 512 * 512 * 4;
-
- IDARG_OUT_QUERY_HWCURSOR out = {};
- UINT cursorWhiteLevel = m_sdrWhiteLevel.load(std::memory_order_relaxed);
- NTSTATUS status;
-#ifdef HAS_IDDCX_110
- if (m_devContext->HasIddCx110DDIs())
- {
- IDARG_OUT_QUERY_HWCURSOR3 out3 = {};
- status = IddCxMonitorQueryHardwareCursor3(m_monitor, &in, &out3);
- out.IsCursorVisible = out3.IsCursorVisible;
- out.X = out3.X;
- out.Y = out3.Y;
- out.IsCursorShapeUpdated = out3.IsCursorShapeUpdated;
- out.CursorShapeInfo = out3.CursorShapeInfo;
- if (out3.SdrWhiteLevel)
- cursorWhiteLevel = out3.SdrWhiteLevel;
- }
- else
-#endif
- {
- status = IddCxMonitorQueryHardwareCursor(m_monitor, &in, &out);
- }
-
- if (FAILED(status))
- {
- // this occurs if the display went away (ie, screen blanking or disabled)
- if (status == STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY)
- {
- SetEvent(m_terminateEvent.Get());
- return false;
- }
-
- DEBUG_ERROR("IddCxMonitorQueryHardwareCursor failed (0x%08x)", status);
- return false;
- }
-
- if (out.IsCursorShapeUpdated)
- m_lastShapeId = out.CursorShapeInfo.ShapeId;
-
- m_control.SendCursor(out, m_shapeBuffer, cursorWhiteLevel);
- return true;
-}
-
-void CSwapChainProcessor::CursorThread()
-{
- HRESULT hr = 0;
- bool running = true;
-
- while (running)
- {
- HANDLE waitHandles[] =
- {
- m_cursorDataEvent.Get(),
- m_terminateEvent.Get()
- };
-
- DWORD waitResult = WaitForMultipleObjects(
- ARRAYSIZE(waitHandles), waitHandles, FALSE, 100);
-
- switch (waitResult)
- {
- case WAIT_TIMEOUT:
- continue;
-
- // cursorDataEvent
- case WAIT_OBJECT_0:
- if (!QueryHWCursor())
- return;
- continue;
-
- // terminateEvent
- case WAIT_OBJECT_0 + 1:
- running = false;
- continue;
-
- default:
- hr = HRESULT_FROM_WIN32(waitResult);
- DEBUG_ERROR_HR(hr, "WaitForMultipleObjects");
- return;
- }
- }
-}
diff --git a/idd/LGIdd/capture/CSwapChainProcessor.cpp b/idd/LGIdd/capture/CSwapChainProcessor.cpp
index e559fd10..2d6010b2 100644
--- a/idd/LGIdd/capture/CSwapChainProcessor.cpp
+++ b/idd/LGIdd/capture/CSwapChainProcessor.cpp
@@ -21,8 +21,8 @@
#include "capture/CSwapChainProcessor.h"
#include "capture/CFrameProcessorUtil.h"
#include "display/IddCxCompat.h"
-#include "display/device/CDeviceContext.h"
-#include "display/monitor/Context.h"
+#include "display/CDeviceContext.h"
+#include "display/CMonitorContext.h"
#include "platform/CPlatformInfo.h"
#include "transport/IFrameTransport.h"
#include "transport/IControlTransport.h"
@@ -31,7 +31,7 @@
#include
#include
#include "CDebug.h"
-#include "transport/CPipeServer.h"
+#include "ipc/CPipeServer.h"
#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION
#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002
@@ -737,3 +737,340 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr acquiredBuffer
};
return m_frameProcessor->Submit(submission);
}
+
+static const uint64_t PUBLISH_RETRY_NS = 1000000ULL;
+
+static bool ArmPublishTimer(HANDLE timer, uint64_t delay)
+{
+ if (!timer)
+ return false;
+
+ LARGE_INTEGER due = {};
+ due.QuadPart = -static_cast((delay + 99) / 100);
+ if (!due.QuadPart)
+ due.QuadPart = -1;
+ return SetWaitableTimer(timer, &due, 0, nullptr, nullptr, FALSE) != FALSE;
+}
+
+DWORD CALLBACK CSwapChainProcessor::_PublisherThread(LPVOID arg)
+{
+ reinterpret_cast(arg)->PublisherThread();
+ return 0;
+}
+
+void CSwapChainProcessor::PublisherThread()
+{
+ DWORD avTask = 0;
+ HANDLE avTaskHandle = AvSetMmThreadCharacteristicsW(L"Distribution", &avTask);
+ if (avTaskHandle &&
+ !AvSetMmThreadPriority(avTaskHandle, AVRT_PRIORITY_HIGH))
+ DEBUG_WARN("Failed to raise publisher MMCSS priority: %lu",
+ GetLastError());
+
+ const HANDLE scheduleEvent = m_transport.GetFrameScheduleEvent();
+ HANDLE idleHandles[] =
+ {
+ m_terminateEvent.Get(),
+ m_frameProcessor->GetReadyEvent(),
+ scheduleEvent,
+ };
+ HANDLE timerHandles[] =
+ {
+ m_terminateEvent.Get(),
+ m_frameProcessor->GetReadyEvent(),
+ scheduleEvent,
+ m_publishTimer.Get(),
+ };
+ const bool cadenceEnabled = m_frameProcessor->UsesCadence();
+
+ for (;;)
+ {
+ const uint64_t now = CFrameScheduler::Nanotime();
+ uint64_t target;
+ CFrameScheduler::Schedule schedule;
+ bool periodic;
+ bool republish;
+ m_transport.GetPublishTarget(
+ now, target, schedule, periodic, republish);
+
+ const bool ready = m_frameProcessor->HasReadyFrame();
+ if (!ready)
+ {
+ m_transport.ProcessDeliveries();
+ if (m_frameProcessor->HasReadyFrame())
+ continue;
+
+ uint64_t current = CFrameScheduler::Nanotime();
+ uint64_t cadenceTarget = 0;
+ if (cadenceEnabled && schedule.deliveryDeadlineSerial && periodic)
+ {
+ if (schedule.deadline <= current)
+ {
+ m_transport.FrameMissed(schedule, current, periodic);
+ continue;
+ }
+ cadenceTarget = schedule.deadline;
+ }
+
+ if (republish && m_transport.HasPublishedFrame())
+ {
+ if (m_transport.RepublishFrameBuffer(schedule))
+ continue;
+
+ current = CFrameScheduler::Nanotime();
+ if (cadenceTarget && cadenceTarget <= current)
+ {
+ m_transport.FrameMissed(schedule, current, periodic);
+ continue;
+ }
+
+ uint64_t retryTarget = current + PUBLISH_RETRY_NS;
+ if (cadenceTarget)
+ retryTarget = min(retryTarget, cadenceTarget);
+ ArmPublishTimer(m_publishTimer.Get(), retryTarget - current);
+ if (WaitForMultipleObjects(
+ ARRAYSIZE(timerHandles), timerHandles, FALSE, INFINITE) ==
+ WAIT_OBJECT_0)
+ break;
+ continue;
+ }
+
+ uint64_t replayTarget;
+ if (m_transport.GetPendingDeliveryTarget(current, replayTarget))
+ {
+ bool retry = false;
+ if (replayTarget <= current)
+ {
+ if (m_transport.RetryPendingDelivery(current, retry))
+ continue;
+
+ current = CFrameScheduler::Nanotime();
+ if (cadenceTarget && cadenceTarget <= current)
+ {
+ m_transport.FrameMissed(schedule, current, periodic);
+ continue;
+ }
+
+ if (retry)
+ replayTarget = current + PUBLISH_RETRY_NS;
+ else
+ {
+ if (cadenceTarget)
+ replayTarget = cadenceTarget;
+ else
+ {
+ if (m_publishTimer.Get())
+ CancelWaitableTimer(m_publishTimer.Get());
+ if (WaitForMultipleObjects(
+ ARRAYSIZE(idleHandles), idleHandles, FALSE, INFINITE) ==
+ WAIT_OBJECT_0)
+ break;
+ continue;
+ }
+ }
+ }
+
+ if (cadenceTarget)
+ replayTarget = min(replayTarget, cadenceTarget);
+
+ current = CFrameScheduler::Nanotime();
+ if (cadenceTarget && cadenceTarget <= current)
+ {
+ m_transport.FrameMissed(schedule, current, periodic);
+ continue;
+ }
+ if (replayTarget <= current)
+ continue;
+
+ ArmPublishTimer(m_publishTimer.Get(), replayTarget - current);
+ if (WaitForMultipleObjects(
+ ARRAYSIZE(timerHandles), timerHandles, FALSE, INFINITE) ==
+ WAIT_OBJECT_0)
+ break;
+ continue;
+ }
+
+ if (cadenceTarget)
+ {
+ current = CFrameScheduler::Nanotime();
+ if (cadenceTarget <= current)
+ {
+ m_transport.FrameMissed(schedule, current, periodic);
+ continue;
+ }
+
+ ArmPublishTimer(m_publishTimer.Get(), cadenceTarget - current);
+ if (WaitForMultipleObjects(
+ ARRAYSIZE(timerHandles), timerHandles, FALSE, INFINITE) ==
+ WAIT_OBJECT_0)
+ break;
+ continue;
+ }
+
+ if (m_publishTimer.Get())
+ CancelWaitableTimer(m_publishTimer.Get());
+ if (WaitForMultipleObjects(
+ ARRAYSIZE(idleHandles), idleHandles, FALSE, INFINITE) ==
+ WAIT_OBJECT_0)
+ break;
+ continue;
+ }
+
+ uint64_t current = CFrameScheduler::Nanotime();
+ uint64_t replayTarget;
+ if (m_transport.GetPendingDeliveryTarget(current, replayTarget) &&
+ replayTarget < target)
+ {
+ if (replayTarget <= current)
+ {
+ m_transport.ProcessDeliveries();
+ current = CFrameScheduler::Nanotime();
+ bool retry = false;
+ if (m_transport.RetryPendingDelivery(current, retry))
+ continue;
+
+ current = CFrameScheduler::Nanotime();
+ if (retry)
+ replayTarget = current + PUBLISH_RETRY_NS;
+ else
+ replayTarget = target;
+ }
+
+ replayTarget = min(replayTarget, target);
+ current = CFrameScheduler::Nanotime();
+ if (target > current)
+ {
+ if (replayTarget <= current)
+ continue;
+
+ ArmPublishTimer(m_publishTimer.Get(), replayTarget - current);
+ if (WaitForMultipleObjects(
+ ARRAYSIZE(timerHandles), timerHandles, FALSE, INFINITE) ==
+ WAIT_OBJECT_0)
+ break;
+ continue;
+ }
+ }
+
+ current = CFrameScheduler::Nanotime();
+ if (target > current)
+ {
+ ArmPublishTimer(m_publishTimer.Get(), target - current);
+ if (WaitForMultipleObjects(
+ ARRAYSIZE(timerHandles), timerHandles, FALSE, INFINITE) ==
+ WAIT_OBJECT_0)
+ break;
+ continue;
+ }
+
+ const uint64_t publishStart = CFrameScheduler::Nanotime();
+ m_transport.ProcessDeliveries();
+ if (!m_transport.FrameBufferAvailable(schedule) ||
+ !m_frameProcessor->Publish(schedule, periodic, publishStart))
+ {
+ ArmPublishTimer(m_publishTimer.Get(), PUBLISH_RETRY_NS);
+ if (WaitForMultipleObjects(
+ ARRAYSIZE(timerHandles), timerHandles, FALSE, INFINITE) ==
+ WAIT_OBJECT_0)
+ break;
+ }
+ }
+
+ if (avTaskHandle)
+ AvRevertMmThreadCharacteristics(avTaskHandle);
+}
+
+DWORD CALLBACK CSwapChainProcessor::_CursorThread(LPVOID arg)
+{
+ reinterpret_cast(arg)->CursorThread();
+ return 0;
+}
+
+bool CSwapChainProcessor::QueryHWCursor()
+{
+ IDARG_IN_QUERY_HWCURSOR in = {};
+ in.LastShapeId = m_lastShapeId;
+ in.pShapeBuffer = m_shapeBuffer;
+ in.ShapeBufferSizeInBytes = 512 * 512 * 4;
+
+ IDARG_OUT_QUERY_HWCURSOR out = {};
+ UINT cursorWhiteLevel = m_sdrWhiteLevel.load(std::memory_order_relaxed);
+ NTSTATUS status;
+#ifdef HAS_IDDCX_110
+ if (m_devContext->HasIddCx110DDIs())
+ {
+ IDARG_OUT_QUERY_HWCURSOR3 out3 = {};
+ status = IddCxMonitorQueryHardwareCursor3(m_monitor, &in, &out3);
+ out.IsCursorVisible = out3.IsCursorVisible;
+ out.X = out3.X;
+ out.Y = out3.Y;
+ out.IsCursorShapeUpdated = out3.IsCursorShapeUpdated;
+ out.CursorShapeInfo = out3.CursorShapeInfo;
+ if (out3.SdrWhiteLevel)
+ cursorWhiteLevel = out3.SdrWhiteLevel;
+ }
+ else
+#endif
+ {
+ status = IddCxMonitorQueryHardwareCursor(m_monitor, &in, &out);
+ }
+
+ if (FAILED(status))
+ {
+ // this occurs if the display went away (ie, screen blanking or disabled)
+ if (status == STATUS_GRAPHICS_PATH_NOT_IN_TOPOLOGY)
+ {
+ SetEvent(m_terminateEvent.Get());
+ return false;
+ }
+
+ DEBUG_ERROR("IddCxMonitorQueryHardwareCursor failed (0x%08x)", status);
+ return false;
+ }
+
+ if (out.IsCursorShapeUpdated)
+ m_lastShapeId = out.CursorShapeInfo.ShapeId;
+
+ m_control.SendCursor(out, m_shapeBuffer, cursorWhiteLevel);
+ return true;
+}
+
+void CSwapChainProcessor::CursorThread()
+{
+ HRESULT hr = 0;
+ bool running = true;
+
+ while (running)
+ {
+ HANDLE waitHandles[] =
+ {
+ m_cursorDataEvent.Get(),
+ m_terminateEvent.Get()
+ };
+
+ DWORD waitResult = WaitForMultipleObjects(
+ ARRAYSIZE(waitHandles), waitHandles, FALSE, 100);
+
+ switch (waitResult)
+ {
+ case WAIT_TIMEOUT:
+ continue;
+
+ // cursorDataEvent
+ case WAIT_OBJECT_0:
+ if (!QueryHWCursor())
+ return;
+ continue;
+
+ // terminateEvent
+ case WAIT_OBJECT_0 + 1:
+ running = false;
+ continue;
+
+ default:
+ hr = HRESULT_FROM_WIN32(waitResult);
+ DEBUG_ERROR_HR(hr, "WaitForMultipleObjects");
+ return;
+ }
+ }
+}
diff --git a/idd/LGIdd/capture/CSwapChainProcessor.h b/idd/LGIdd/capture/CSwapChainProcessor.h
index 75d52400..e736e5bc 100644
--- a/idd/LGIdd/capture/CSwapChainProcessor.h
+++ b/idd/LGIdd/capture/CSwapChainProcessor.h
@@ -56,7 +56,7 @@ private:
HANDLE m_newFrameEvent;
CInteropResourcePool m_resPool;
- CPostProcessor m_postProcessors[TRANSPORT_FRAME_QUEUE_LENGTH];
+ CPostProcessor m_postProcessors[CAPTURE_PIPELINE_SLOTS];
std::unique_ptr m_frameProcessor;
// Reconfiguration is exclusive while per-candidate recording is shared.
SRWLOCK m_pipelineLock = SRWLOCK_INIT;
diff --git a/idd/LGIdd/capture/CSwapChainPublisher.cpp b/idd/LGIdd/capture/CSwapChainPublisher.cpp
deleted file mode 100644
index 66739fd6..00000000
--- a/idd/LGIdd/capture/CSwapChainPublisher.cpp
+++ /dev/null
@@ -1,268 +0,0 @@
-/**
- * Looking Glass
- * Copyright © 2017-2026 The Looking Glass Authors
- * https://looking-glass.io
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the Free
- * Software Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc., 59
- * Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#include "capture/CSwapChainProcessor.h"
-
-#include "transport/IFrameTransport.h"
-
-#include
-#include "CDebug.h"
-
-static const uint64_t PUBLISH_RETRY_NS = 1000000ULL;
-
-static bool ArmPublishTimer(HANDLE timer, uint64_t delay)
-{
- if (!timer)
- return false;
-
- LARGE_INTEGER due = {};
- due.QuadPart = -static_cast((delay + 99) / 100);
- if (!due.QuadPart)
- due.QuadPart = -1;
- return SetWaitableTimer(timer, &due, 0, nullptr, nullptr, FALSE) != FALSE;
-}
-
-DWORD CALLBACK CSwapChainProcessor::_PublisherThread(LPVOID arg)
-{
- reinterpret_cast(arg)->PublisherThread();
- return 0;
-}
-
-void CSwapChainProcessor::PublisherThread()
-{
- DWORD avTask = 0;
- HANDLE avTaskHandle = AvSetMmThreadCharacteristicsW(L"Distribution", &avTask);
- if (avTaskHandle &&
- !AvSetMmThreadPriority(avTaskHandle, AVRT_PRIORITY_HIGH))
- DEBUG_WARN("Failed to raise publisher MMCSS priority: %lu",
- GetLastError());
-
- const HANDLE scheduleEvent = m_transport.GetFrameScheduleEvent();
- HANDLE idleHandles[] =
- {
- m_terminateEvent.Get(),
- m_frameProcessor->GetReadyEvent(),
- scheduleEvent,
- };
- HANDLE timerHandles[] =
- {
- m_terminateEvent.Get(),
- m_frameProcessor->GetReadyEvent(),
- scheduleEvent,
- m_publishTimer.Get(),
- };
- const bool cadenceEnabled = m_frameProcessor->UsesCadence();
-
- for (;;)
- {
- const uint64_t now = CFrameScheduler::Nanotime();
- uint64_t target;
- CFrameScheduler::Schedule schedule;
- bool periodic;
- bool republish;
- m_transport.GetPublishTarget(
- now, target, schedule, periodic, republish);
-
- const bool ready = m_frameProcessor->HasReadyFrame();
- if (!ready)
- {
- m_transport.ProcessDeliveries();
- if (m_frameProcessor->HasReadyFrame())
- continue;
-
- uint64_t current = CFrameScheduler::Nanotime();
- uint64_t cadenceTarget = 0;
- if (cadenceEnabled && schedule.deliveryDeadlineSerial && periodic)
- {
- if (schedule.deadline <= current)
- {
- m_transport.FrameMissed(schedule, current, periodic);
- continue;
- }
- cadenceTarget = schedule.deadline;
- }
-
- if (republish && m_transport.HasPublishedFrame())
- {
- if (m_transport.RepublishFrameBuffer(schedule))
- continue;
-
- current = CFrameScheduler::Nanotime();
- if (cadenceTarget && cadenceTarget <= current)
- {
- m_transport.FrameMissed(schedule, current, periodic);
- continue;
- }
-
- uint64_t retryTarget = current + PUBLISH_RETRY_NS;
- if (cadenceTarget)
- retryTarget = min(retryTarget, cadenceTarget);
- ArmPublishTimer(m_publishTimer.Get(), retryTarget - current);
- if (WaitForMultipleObjects(
- ARRAYSIZE(timerHandles), timerHandles, FALSE, INFINITE) ==
- WAIT_OBJECT_0)
- break;
- continue;
- }
-
- uint64_t replayTarget;
- if (m_transport.GetPendingDeliveryTarget(current, replayTarget))
- {
- bool retry = false;
- if (replayTarget <= current)
- {
- if (m_transport.RetryPendingDelivery(current, retry))
- continue;
-
- current = CFrameScheduler::Nanotime();
- if (cadenceTarget && cadenceTarget <= current)
- {
- m_transport.FrameMissed(schedule, current, periodic);
- continue;
- }
-
- if (retry)
- replayTarget = current + PUBLISH_RETRY_NS;
- else
- {
- if (cadenceTarget)
- replayTarget = cadenceTarget;
- else
- {
- if (m_publishTimer.Get())
- CancelWaitableTimer(m_publishTimer.Get());
- if (WaitForMultipleObjects(
- ARRAYSIZE(idleHandles), idleHandles, FALSE, INFINITE) ==
- WAIT_OBJECT_0)
- break;
- continue;
- }
- }
- }
-
- if (cadenceTarget)
- replayTarget = min(replayTarget, cadenceTarget);
-
- current = CFrameScheduler::Nanotime();
- if (cadenceTarget && cadenceTarget <= current)
- {
- m_transport.FrameMissed(schedule, current, periodic);
- continue;
- }
- if (replayTarget <= current)
- continue;
-
- ArmPublishTimer(m_publishTimer.Get(), replayTarget - current);
- if (WaitForMultipleObjects(
- ARRAYSIZE(timerHandles), timerHandles, FALSE, INFINITE) ==
- WAIT_OBJECT_0)
- break;
- continue;
- }
-
- if (cadenceTarget)
- {
- current = CFrameScheduler::Nanotime();
- if (cadenceTarget <= current)
- {
- m_transport.FrameMissed(schedule, current, periodic);
- continue;
- }
-
- ArmPublishTimer(m_publishTimer.Get(), cadenceTarget - current);
- if (WaitForMultipleObjects(
- ARRAYSIZE(timerHandles), timerHandles, FALSE, INFINITE) ==
- WAIT_OBJECT_0)
- break;
- continue;
- }
-
- if (m_publishTimer.Get())
- CancelWaitableTimer(m_publishTimer.Get());
- if (WaitForMultipleObjects(
- ARRAYSIZE(idleHandles), idleHandles, FALSE, INFINITE) ==
- WAIT_OBJECT_0)
- break;
- continue;
- }
-
- uint64_t current = CFrameScheduler::Nanotime();
- uint64_t replayTarget;
- if (m_transport.GetPendingDeliveryTarget(current, replayTarget) &&
- replayTarget < target)
- {
- if (replayTarget <= current)
- {
- m_transport.ProcessDeliveries();
- current = CFrameScheduler::Nanotime();
- bool retry = false;
- if (m_transport.RetryPendingDelivery(current, retry))
- continue;
-
- current = CFrameScheduler::Nanotime();
- if (retry)
- replayTarget = current + PUBLISH_RETRY_NS;
- else
- replayTarget = target;
- }
-
- replayTarget = min(replayTarget, target);
- current = CFrameScheduler::Nanotime();
- if (target > current)
- {
- if (replayTarget <= current)
- continue;
-
- ArmPublishTimer(m_publishTimer.Get(), replayTarget - current);
- if (WaitForMultipleObjects(
- ARRAYSIZE(timerHandles), timerHandles, FALSE, INFINITE) ==
- WAIT_OBJECT_0)
- break;
- continue;
- }
- }
-
- current = CFrameScheduler::Nanotime();
- if (target > current)
- {
- ArmPublishTimer(m_publishTimer.Get(), target - current);
- if (WaitForMultipleObjects(
- ARRAYSIZE(timerHandles), timerHandles, FALSE, INFINITE) ==
- WAIT_OBJECT_0)
- break;
- continue;
- }
-
- const uint64_t publishStart = CFrameScheduler::Nanotime();
- m_transport.ProcessDeliveries();
- if (!m_transport.FrameBufferAvailable(schedule) ||
- !m_frameProcessor->Publish(schedule, periodic, publishStart))
- {
- ArmPublishTimer(m_publishTimer.Get(), PUBLISH_RETRY_NS);
- if (WaitForMultipleObjects(
- ARRAYSIZE(timerHandles), timerHandles, FALSE, INFINITE) ==
- WAIT_OBJECT_0)
- break;
- }
- }
-
- if (avTaskHandle)
- AvRevertMmThreadCharacteristics(avTaskHandle);
-}
diff --git a/idd/LGIdd/capture/FramePipeline.h b/idd/LGIdd/capture/FramePipeline.h
new file mode 100644
index 00000000..ceccb8fe
--- /dev/null
+++ b/idd/LGIdd/capture/FramePipeline.h
@@ -0,0 +1,27 @@
+/**
+ * Looking Glass
+ * Copyright © 2017-2026 The Looking Glass Authors
+ * https://looking-glass.io
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc., 59
+ * Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#pragma once
+
+enum : unsigned
+{
+ CAPTURE_PIPELINE_SLOTS = 2,
+ CAPTURE_FRAME_BUFFERS = 3,
+};
diff --git a/idd/LGIdd/d3d/CD3D12Device.h b/idd/LGIdd/d3d/CD3D12Device.h
index 0cc635d6..816ec876 100644
--- a/idd/LGIdd/d3d/CD3D12Device.h
+++ b/idd/LGIdd/d3d/CD3D12Device.h
@@ -27,7 +27,7 @@
#include
#include "d3d/CD3D12CommandQueue.h"
-#include "transport/TransportTypes.h"
+#include "transport/DirectFrameBufferMemory.h"
using namespace Microsoft::WRL;
diff --git a/idd/LGIdd/display/device/CDeviceContext.cpp b/idd/LGIdd/display/CDeviceContext.cpp
similarity index 99%
rename from idd/LGIdd/display/device/CDeviceContext.cpp
rename to idd/LGIdd/display/CDeviceContext.cpp
index 8192d46f..9152fab6 100644
--- a/idd/LGIdd/display/device/CDeviceContext.cpp
+++ b/idd/LGIdd/display/CDeviceContext.cpp
@@ -18,10 +18,10 @@
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "display/device/CDeviceContext.h"
+#include "display/CDeviceContext.h"
#include "display/IddCxCompat.h"
-#include "transport/CPipeServer.h"
+#include "ipc/CPipeServer.h"
#include "transport/IFrameTransport.h"
#include "transport/TransportFactory.h"
#include "CDebug.h"
diff --git a/idd/LGIdd/display/device/CDeviceContext.h b/idd/LGIdd/display/CDeviceContext.h
similarity index 100%
rename from idd/LGIdd/display/device/CDeviceContext.h
rename to idd/LGIdd/display/CDeviceContext.h
diff --git a/idd/LGIdd/display/monitor/Context.cpp b/idd/LGIdd/display/CMonitorContext.cpp
similarity index 98%
rename from idd/LGIdd/display/monitor/Context.cpp
rename to idd/LGIdd/display/CMonitorContext.cpp
index 416b2fe2..aebe98fb 100644
--- a/idd/LGIdd/display/monitor/Context.cpp
+++ b/idd/LGIdd/display/CMonitorContext.cpp
@@ -18,8 +18,8 @@
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "display/monitor/Context.h"
-#include "display/device/CDeviceContext.h"
+#include "display/CMonitorContext.h"
+#include "display/CDeviceContext.h"
#include "capture/CSwapChainProcessor.h"
#include "d3d/CD3D11Device.h"
#include "CDebug.h"
diff --git a/idd/LGIdd/display/monitor/Context.h b/idd/LGIdd/display/CMonitorContext.h
similarity index 100%
rename from idd/LGIdd/display/monitor/Context.h
rename to idd/LGIdd/display/CMonitorContext.h
diff --git a/idd/LGIdd/display/CMonitorManager.cpp b/idd/LGIdd/display/CMonitorManager.cpp
index e8e2b655..08407f7a 100644
--- a/idd/LGIdd/display/CMonitorManager.cpp
+++ b/idd/LGIdd/display/CMonitorManager.cpp
@@ -20,7 +20,7 @@
#include "display/CMonitorManager.h"
-#include "display/monitor/Context.h"
+#include "display/CMonitorContext.h"
#include "CDebug.h"
void CMonitorManager::Create(UINT connectorIndex, IDDCX_ADAPTER adapter,
diff --git a/idd/LGIdd/transport/CPipeServer.cpp b/idd/LGIdd/ipc/CPipeServer.cpp
similarity index 99%
rename from idd/LGIdd/transport/CPipeServer.cpp
rename to idd/LGIdd/ipc/CPipeServer.cpp
index 9a2d0db7..d98b904b 100644
--- a/idd/LGIdd/transport/CPipeServer.cpp
+++ b/idd/LGIdd/ipc/CPipeServer.cpp
@@ -18,9 +18,9 @@
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "transport/CPipeServer.h"
+#include "ipc/CPipeServer.h"
#include "CDebug.h"
-#include "display/device/CDeviceContext.h"
+#include "display/CDeviceContext.h"
CPipeServer g_pipe;
diff --git a/idd/LGIdd/transport/CPipeServer.h b/idd/LGIdd/ipc/CPipeServer.h
similarity index 100%
rename from idd/LGIdd/transport/CPipeServer.h
rename to idd/LGIdd/ipc/CPipeServer.h
diff --git a/idd/LGIdd/postprocess/effect/CRGB24Effect.cpp b/idd/LGIdd/postprocess/effect/CRGB24Effect.cpp
index 6c5bff94..134121f6 100644
--- a/idd/LGIdd/postprocess/effect/CRGB24Effect.cpp
+++ b/idd/LGIdd/postprocess/effect/CRGB24Effect.cpp
@@ -22,7 +22,7 @@
#include "CDebug.h"
#include "config/CSettings.h"
-#include "transport/TransportTypes.h"
+#include "capture/FramePipeline.h"
#include
#include
@@ -61,7 +61,7 @@ struct CRGB24Effect::State
std::shared_ptr colorTransform;
};
- static const unsigned WarmupCount = TRANSPORT_FRAME_QUEUE_LENGTH;
+ static const unsigned WarmupCount = CAPTURE_PIPELINE_SLOTS;
static const unsigned SampleCount = 64;
static const unsigned TrimCount = SampleCount / 8;
diff --git a/idd/LGIdd/transport/TransportTypes.h b/idd/LGIdd/transport/DirectFrameBufferMemory.h
similarity index 63%
rename from idd/LGIdd/transport/TransportTypes.h
rename to idd/LGIdd/transport/DirectFrameBufferMemory.h
index 4a535af5..58e8d96c 100644
--- a/idd/LGIdd/transport/TransportTypes.h
+++ b/idd/LGIdd/transport/DirectFrameBufferMemory.h
@@ -21,36 +21,6 @@
#pragma once
#include
-#include
-
-enum : unsigned
-{
- TRANSPORT_FRAME_QUEUE_LENGTH = 2,
- TRANSPORT_FRAME_BUFFER_COUNT = 3,
- TRANSPORT_MAX_CLIENTS = 8,
-};
-
-enum : uint32_t
-{
- FRAME_SCHEDULE_ACTIVE = 0x1,
- FRAME_SCHEDULE_RELEASE = 0x2,
- FRAME_SCHEDULE_RESET = 0x4,
- FRAME_SCHEDULE_IMMEDIATE = 0x8,
-};
-
-struct FrameScheduleUpdate
-{
- uint32_t clientID;
- uint32_t generation;
- uint32_t flags;
- uint64_t period;
- uint64_t targetSlack;
- int64_t phaseError;
- uint32_t feedbackFrameSerial;
- uint32_t feedbackScheduleEpoch;
- uint32_t feedbackDeadlineSerial;
- uint32_t lease;
-};
struct DirectFrameBufferMemory
{
diff --git a/idd/LGIdd/transport/IFrameTransport.h b/idd/LGIdd/transport/IFrameTransport.h
index 982e555b..dc016c7a 100644
--- a/idd/LGIdd/transport/IFrameTransport.h
+++ b/idd/LGIdd/transport/IFrameTransport.h
@@ -21,9 +21,8 @@
#pragma once
#include "postprocess/D12FrameFormat.h"
-#include "transport/CFrameScheduler.h"
-#include "transport/FrameBufferTypes.h"
-#include "transport/TransportTypes.h"
+#include "capture/CFrameScheduler.h"
+#include "transport/PreparedFrameBuffer.h"
#include
#include
diff --git a/idd/LGIdd/transport/ITransport.h b/idd/LGIdd/transport/ITransport.h
index 7f2a7138..4cdd567e 100644
--- a/idd/LGIdd/transport/ITransport.h
+++ b/idd/LGIdd/transport/ITransport.h
@@ -20,8 +20,8 @@
#pragma once
+#include "transport/DirectFrameBufferMemory.h"
#include "transport/FrameMemoryLimits.h"
-#include "transport/TransportTypes.h"
#include
#include
diff --git a/idd/LGIdd/transport/FrameBufferTypes.h b/idd/LGIdd/transport/PreparedFrameBuffer.h
similarity index 100%
rename from idd/LGIdd/transport/FrameBufferTypes.h
rename to idd/LGIdd/transport/PreparedFrameBuffer.h
diff --git a/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.cpp b/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.cpp
index e20103f9..ebb199f8 100644
--- a/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.cpp
+++ b/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.cpp
@@ -35,11 +35,11 @@ struct LGMPBuffer
};
#pragma warning(pop)
-static_assert(TRANSPORT_FRAME_QUEUE_LENGTH == LGMP_Q_FRAME_LEN,
+static_assert(CAPTURE_PIPELINE_SLOTS == LGMP_Q_FRAME_LEN,
"The capture pipeline must match the LGMP frame queue");
-static_assert(TRANSPORT_FRAME_BUFFER_COUNT == LGMP_Q_FRAME_BUFFER_LEN,
+static_assert(CAPTURE_FRAME_BUFFERS == LGMP_Q_FRAME_BUFFER_LEN,
"The capture buffer pool must match the LGMP frame buffers");
-static_assert(TRANSPORT_MAX_CLIENTS == LGMP_MAX_CLIENTS,
+static_assert(CFrameScheduler::MAX_CLIENTS == LGMP_MAX_CLIENTS,
"The scheduler must support every LGMP client");
static const struct LGMPQueueConfig FRAME_QUEUE_CONFIG =
diff --git a/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.h b/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.h
index 45c77d19..22948649 100644
--- a/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.h
+++ b/idd/LGIdd/transport/lgmp/CLGMPFrameTransport.h
@@ -29,7 +29,8 @@ extern "C" {
}
#include "common/KVMFR.h"
-#include "transport/CFrameScheduler.h"
+#include "capture/CFrameScheduler.h"
+#include "capture/FramePipeline.h"
#include "transport/FrameMemoryLimits.h"
#include "transport/IFrameTransport.h"