From fb1fb8447e44e796a123b634a9c525cb6fc84131 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Thu, 6 Aug 2026 17:00:31 +1000 Subject: [PATCH] [idd] scheduler: unblock ownership transitions Permit retained-buffer reuse when both private queues are occupied by a previous timing owner, even if the new owner has no pending deliveries. Use the shared fallback when possible. Otherwise retain the fresh frame locally and republish it instead of waiting for stale private deliveries. --- idd/LGIdd/CIndirectDeviceContext.cpp | 33 ++++++++++++++++++---------- 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/idd/LGIdd/CIndirectDeviceContext.cpp b/idd/LGIdd/CIndirectDeviceContext.cpp index 7d41aa8d..a1fced17 100644 --- a/idd/LGIdd/CIndirectDeviceContext.cpp +++ b/idd/LGIdd/CIndirectDeviceContext.cpp @@ -1745,25 +1745,27 @@ bool CIndirectDeviceContext::FrameBufferAvailable( return false; AcquireSRWLockShared(&m_framePublishLock); - bool deliveryAvailable; - bool ownerBlocked = false; + bool allowReady = false; // Pipeline one frame through each independent owner lane. Count the shared // fallback against the same limit so it cannot become a third delivery for // the same owner. Once both are occupied, a fully unreferenced buffer can // still retain a newer frame for secondary delivery and later republish. if (schedule.clientID) { - ownerBlocked = + const bool ownerBlocked = CountOwnerDeliveries(schedule.clientID) >= LGMP_Q_FRAME_LEN; - deliveryAvailable = ownerBlocked || - FindAvailableOwnerQueue(0) >= 0 || - lgmpHostQueuePending(m_frameQueue) < LGMP_Q_FRAME_LEN; + const bool ownerQueuesBlocked = FindAvailableOwnerQueue(0) < 0; + allowReady = ownerBlocked || ownerQueuesBlocked; + } + else if (lgmpHostQueuePending(m_frameQueue) != 0) + { + ReleaseSRWLockShared(&m_framePublishLock); + return false; } - else - deliveryAvailable = lgmpHostQueuePending(m_frameQueue) == 0; - const bool available = deliveryAvailable && - FindAvailableFrameBuffer(ownerBlocked) >= 0; + // With no owner delivery lane available, a copy can still replace an + // unreferenced retained frame and be republished when a lane clears. + const bool available = FindAvailableFrameBuffer(allowReady) >= 0; ReleaseSRWLockShared(&m_framePublishLock); return available; } @@ -1859,8 +1861,10 @@ CIndirectDeviceContext::PreparedFrameBuffer CIndirectDeviceContext::PrepareFrame AcquireSRWLockExclusive(&m_framePublishLock); const bool ownerBlocked = schedule.clientID && CountOwnerDeliveries(schedule.clientID) >= LGMP_Q_FRAME_LEN; + const bool allowReady = ownerBlocked || + (schedule.clientID && FindAvailableOwnerQueue(0) < 0); const int availableFrameIndex = - FindAvailableFrameBuffer(ownerBlocked); + FindAvailableFrameBuffer(allowReady); bool expected = false; const bool acquired = availableFrameIndex >= 0 && m_frameInFlight[availableFrameIndex].compare_exchange_strong( @@ -2062,8 +2066,13 @@ bool CIndirectDeviceContext::PublishFrameBuffer(unsigned frameIndex, const int ownerQueueIndex = FindAvailableOwnerQueue(frameIndex); if (ownerQueueIndex < 0) { - published = PostSharedOwnerFrame(frameIndex, schedule); + published = PostSharedOwnerFrame(frameIndex, schedule); deliveredToOwner = published; + if (!published) + { + PostSharedFrame(frameIndex, schedule.clientID, now); + published = true; + } } else {