From 1de52f6e8a8b659c4491adae3a177831aea4ab56 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Fri, 7 Aug 2026 18:16:18 +1000 Subject: [PATCH] [idd] project: organize source layout Move cadence and pipeline declarations under capture, and move local named-pipe handling under ipc. Flatten display contexts and rename files after their contained classes. Keep transport headers limited to transport contracts and capabilities. Consolidate CSwapChainProcessor definitions so each source file matches the class it implements. --- idd/LGIdd/Device.cpp | 6 +- idd/LGIdd/Driver.cpp | 2 +- idd/LGIdd/LGIdd.vcxproj | 23 +- idd/LGIdd/LGIdd.vcxproj.filters | 64 ++-- idd/LGIdd/capture/CFrameBufferPool.h | 6 +- idd/LGIdd/capture/CFrameBufferResource.h | 2 +- idd/LGIdd/capture/CFrameProcessor.cpp | 4 +- idd/LGIdd/capture/CFrameProcessor.h | 8 +- .../CFrameScheduler.cpp | 10 +- .../{transport => capture}/CFrameScheduler.h | 36 +- idd/LGIdd/capture/CHardwareFrameProcessor.cpp | 4 +- idd/LGIdd/capture/CHardwareFrameProcessor.h | 6 +- idd/LGIdd/capture/CSoftwareFrameProcessor.cpp | 4 +- idd/LGIdd/capture/CSoftwareFrameProcessor.h | 2 +- idd/LGIdd/capture/CSwapChainCursor.cpp | 122 ------- idd/LGIdd/capture/CSwapChainProcessor.cpp | 343 +++++++++++++++++- idd/LGIdd/capture/CSwapChainProcessor.h | 2 +- idd/LGIdd/capture/CSwapChainPublisher.cpp | 268 -------------- idd/LGIdd/capture/FramePipeline.h | 27 ++ idd/LGIdd/d3d/CD3D12Device.h | 2 +- .../display/{device => }/CDeviceContext.cpp | 4 +- .../display/{device => }/CDeviceContext.h | 0 .../Context.cpp => CMonitorContext.cpp} | 4 +- .../{monitor/Context.h => CMonitorContext.h} | 0 idd/LGIdd/display/CMonitorManager.cpp | 2 +- idd/LGIdd/{transport => ipc}/CPipeServer.cpp | 4 +- idd/LGIdd/{transport => ipc}/CPipeServer.h | 0 idd/LGIdd/postprocess/effect/CRGB24Effect.cpp | 4 +- ...sportTypes.h => DirectFrameBufferMemory.h} | 30 -- idd/LGIdd/transport/IFrameTransport.h | 5 +- idd/LGIdd/transport/ITransport.h | 2 +- ...ameBufferTypes.h => PreparedFrameBuffer.h} | 0 .../transport/lgmp/CLGMPFrameTransport.cpp | 6 +- .../transport/lgmp/CLGMPFrameTransport.h | 3 +- 34 files changed, 482 insertions(+), 523 deletions(-) rename idd/LGIdd/{transport => capture}/CFrameScheduler.cpp (99%) rename idd/LGIdd/{transport => capture}/CFrameScheduler.h (87%) delete mode 100644 idd/LGIdd/capture/CSwapChainCursor.cpp delete mode 100644 idd/LGIdd/capture/CSwapChainPublisher.cpp create mode 100644 idd/LGIdd/capture/FramePipeline.h rename idd/LGIdd/display/{device => }/CDeviceContext.cpp (99%) rename idd/LGIdd/display/{device => }/CDeviceContext.h (100%) rename idd/LGIdd/display/{monitor/Context.cpp => CMonitorContext.cpp} (98%) rename idd/LGIdd/display/{monitor/Context.h => CMonitorContext.h} (100%) rename idd/LGIdd/{transport => ipc}/CPipeServer.cpp (99%) rename idd/LGIdd/{transport => ipc}/CPipeServer.h (100%) rename idd/LGIdd/transport/{TransportTypes.h => DirectFrameBufferMemory.h} (63%) rename idd/LGIdd/transport/{FrameBufferTypes.h => PreparedFrameBuffer.h} (100%) 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"