mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-22 07:01:30 +00:00
[idd] common: use CSRWLock throughout the drivers
Make CSRWLock own the native lock and provide scoped guards for shared, exclusive, early-unlock, and non-blocking use. Replace direct SRW lock management throughout the IDD, input driver, and helper while preserving the existing lock scopes.
This commit is contained in:
@@ -224,13 +224,14 @@ bool CPipeEndpoint::Start(
|
||||
DEBUG_ERROR_HR(GetLastError(), "Failed to create named pipe thread");
|
||||
m_running.store(false);
|
||||
|
||||
AcquireSRWLockExclusive(&m_pipeLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_pipeLock);
|
||||
if (m_pipe != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(m_pipe);
|
||||
m_pipe = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_pipeLock);
|
||||
}
|
||||
|
||||
CloseHandle(m_stopEvent);
|
||||
m_stopEvent = nullptr;
|
||||
@@ -249,10 +250,11 @@ void CPipeEndpoint::Stop()
|
||||
if (m_stopEvent)
|
||||
SetEvent(m_stopEvent);
|
||||
|
||||
AcquireSRWLockShared(&m_pipeLock);
|
||||
{
|
||||
CSRWSharedLock lock(m_pipeLock);
|
||||
if (m_pipe != INVALID_HANDLE_VALUE)
|
||||
CancelIoEx(m_pipe, nullptr);
|
||||
ReleaseSRWLockShared(&m_pipeLock);
|
||||
}
|
||||
|
||||
if (m_thread)
|
||||
{
|
||||
@@ -261,13 +263,14 @@ void CPipeEndpoint::Stop()
|
||||
m_thread = nullptr;
|
||||
}
|
||||
|
||||
AcquireSRWLockExclusive(&m_pipeLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_pipeLock);
|
||||
if (m_pipe != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CloseHandle(m_pipe);
|
||||
m_pipe = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_pipeLock);
|
||||
}
|
||||
|
||||
if (m_stopEvent)
|
||||
{
|
||||
@@ -290,7 +293,7 @@ bool CPipeEndpoint::Send(const void * message, size_t size)
|
||||
return false;
|
||||
|
||||
bool success = false;
|
||||
AcquireSRWLockExclusive(&m_pipeLock);
|
||||
CSRWExclusiveLock lock(m_pipeLock);
|
||||
if (m_pipe != INVALID_HANDLE_VALUE && IsConnected())
|
||||
{
|
||||
const PipeIoResult result = WriteMessage(
|
||||
@@ -304,7 +307,6 @@ bool CPipeEndpoint::Send(const void * message, size_t size)
|
||||
CancelIoEx(m_pipe, nullptr);
|
||||
}
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_pipeLock);
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -350,18 +352,21 @@ void CPipeEndpoint::RunServer()
|
||||
if (!ioEvent)
|
||||
{
|
||||
DEBUG_ERROR_HR(GetLastError(), "Failed to create named pipe I/O event");
|
||||
AcquireSRWLockShared(&m_pipeLock);
|
||||
const HANDLE pipe = m_pipe;
|
||||
ReleaseSRWLockShared(&m_pipeLock);
|
||||
HANDLE pipe;
|
||||
{
|
||||
CSRWSharedLock lock(m_pipeLock);
|
||||
pipe = m_pipe;
|
||||
}
|
||||
if (pipe != INVALID_HANDLE_VALUE)
|
||||
ClosePipe(pipe);
|
||||
return;
|
||||
}
|
||||
|
||||
HANDLE pipe = INVALID_HANDLE_VALUE;
|
||||
AcquireSRWLockShared(&m_pipeLock);
|
||||
{
|
||||
CSRWSharedLock lock(m_pipeLock);
|
||||
pipe = m_pipe;
|
||||
ReleaseSRWLockShared(&m_pipeLock);
|
||||
}
|
||||
|
||||
while (IsRunning())
|
||||
{
|
||||
@@ -581,16 +586,14 @@ bool CPipeEndpoint::WaitForRetry(DWORD delayMs)
|
||||
|
||||
void CPipeEndpoint::PublishPipe(HANDLE pipe)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_pipeLock);
|
||||
CSRWExclusiveLock lock(m_pipeLock);
|
||||
m_pipe = pipe;
|
||||
ReleaseSRWLockExclusive(&m_pipeLock);
|
||||
}
|
||||
|
||||
void CPipeEndpoint::ClosePipe(HANDLE pipe)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_pipeLock);
|
||||
CSRWExclusiveLock lock(m_pipeLock);
|
||||
if (m_pipe == pipe)
|
||||
m_pipe = INVALID_HANDLE_VALUE;
|
||||
CloseHandle(pipe);
|
||||
ReleaseSRWLockExclusive(&m_pipeLock);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CSRWLock.h"
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include <atomic>
|
||||
@@ -124,7 +126,7 @@ private:
|
||||
std::atomic<bool> m_running { false };
|
||||
std::atomic<bool> m_connected { false };
|
||||
|
||||
SRWLOCK m_pipeLock = SRWLOCK_INIT;
|
||||
CSRWLock m_pipeLock;
|
||||
HANDLE m_pipe = INVALID_HANDLE_VALUE;
|
||||
HANDLE m_thread = nullptr;
|
||||
HANDLE m_stopEvent = nullptr;
|
||||
|
||||
@@ -22,42 +22,110 @@
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
class CSRWSharedLock;
|
||||
class CSRWExclusiveLock;
|
||||
|
||||
class CSRWLock
|
||||
{
|
||||
private:
|
||||
friend class CSRWSharedLock;
|
||||
friend class CSRWExclusiveLock;
|
||||
|
||||
SRWLOCK m_lock = SRWLOCK_INIT;
|
||||
|
||||
public:
|
||||
CSRWLock() = default;
|
||||
|
||||
CSRWLock(const CSRWLock&) = delete;
|
||||
CSRWLock& operator=(const CSRWLock&) = delete;
|
||||
};
|
||||
|
||||
class CSRWSharedLock
|
||||
{
|
||||
private:
|
||||
SRWLOCK * m_lock;
|
||||
|
||||
public:
|
||||
explicit CSRWSharedLock(SRWLOCK * lock) : m_lock(lock)
|
||||
explicit CSRWSharedLock(CSRWLock& lock) : m_lock(&lock.m_lock)
|
||||
{
|
||||
AcquireSRWLockShared(m_lock);
|
||||
}
|
||||
|
||||
~CSRWSharedLock()
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
if (!m_lock)
|
||||
return;
|
||||
|
||||
ReleaseSRWLockShared(m_lock);
|
||||
m_lock = nullptr;
|
||||
}
|
||||
|
||||
CSRWSharedLock(const CSRWSharedLock&) = delete;
|
||||
CSRWSharedLock& operator=(const CSRWSharedLock&) = delete;
|
||||
|
||||
CSRWSharedLock(CSRWSharedLock&& other) noexcept : m_lock(other.m_lock)
|
||||
{
|
||||
other.m_lock = nullptr;
|
||||
}
|
||||
|
||||
CSRWSharedLock& operator=(CSRWSharedLock&&) = delete;
|
||||
};
|
||||
|
||||
class CSRWExclusiveLock
|
||||
{
|
||||
private:
|
||||
struct TryTag {};
|
||||
|
||||
SRWLOCK * m_lock;
|
||||
|
||||
CSRWExclusiveLock(CSRWLock& lock, TryTag) :
|
||||
m_lock(TryAcquireSRWLockExclusive(&lock.m_lock) ? &lock.m_lock : nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
explicit CSRWExclusiveLock(SRWLOCK * lock) : m_lock(lock)
|
||||
explicit CSRWExclusiveLock(CSRWLock& lock) : m_lock(&lock.m_lock)
|
||||
{
|
||||
AcquireSRWLockExclusive(m_lock);
|
||||
}
|
||||
|
||||
~CSRWExclusiveLock()
|
||||
{
|
||||
Unlock();
|
||||
}
|
||||
|
||||
static CSRWExclusiveLock Try(CSRWLock& lock)
|
||||
{
|
||||
return CSRWExclusiveLock(lock, TryTag {});
|
||||
}
|
||||
|
||||
explicit operator bool() const
|
||||
{
|
||||
return m_lock != nullptr;
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
if (!m_lock)
|
||||
return;
|
||||
|
||||
ReleaseSRWLockExclusive(m_lock);
|
||||
m_lock = nullptr;
|
||||
}
|
||||
|
||||
CSRWExclusiveLock(const CSRWExclusiveLock&) = delete;
|
||||
CSRWExclusiveLock& operator=(const CSRWExclusiveLock&) = delete;
|
||||
|
||||
CSRWExclusiveLock(CSRWExclusiveLock&& other) noexcept :
|
||||
m_lock(other.m_lock)
|
||||
{
|
||||
other.m_lock = nullptr;
|
||||
}
|
||||
|
||||
CSRWExclusiveLock& operator=(CSRWExclusiveLock&&) = delete;
|
||||
};
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
CFrameProcessor::CFrameProcessor(IFrameTransport * transport,
|
||||
std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent) :
|
||||
CSRWLock * pipelineLock, HANDLE terminateEvent) :
|
||||
m_transport(transport),
|
||||
m_dx12(std::move(dx12)),
|
||||
m_postProcessors(postProcessors),
|
||||
@@ -53,12 +53,11 @@ void CFrameProcessor::Reset()
|
||||
|
||||
void CFrameProcessor::Invalidate()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_damageLock);
|
||||
CSRWExclusiveLock lock(m_damageLock);
|
||||
m_previousDamageCount = 0;
|
||||
m_hasPendingDamage = true;
|
||||
m_pendingDamageCount = 0;
|
||||
SetFullDamageLocked();
|
||||
ReleaseSRWLockExclusive(&m_damageLock);
|
||||
}
|
||||
|
||||
void CFrameProcessor::ResetPipeline()
|
||||
@@ -69,21 +68,19 @@ void CFrameProcessor::ResetPipeline()
|
||||
void CFrameProcessor::AccumulateDamage(
|
||||
const RECT dirtyRects[], unsigned count)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_damageLock);
|
||||
CSRWExclusiveLock lock(m_damageLock);
|
||||
CFrameProcessorUtil::AccumulateDamage(
|
||||
m_pendingDamage, &m_pendingDamageCount, &m_hasPendingDamage,
|
||||
dirtyRects, count);
|
||||
AccumulateDamageLocked(dirtyRects, count);
|
||||
ReleaseSRWLockExclusive(&m_damageLock);
|
||||
}
|
||||
|
||||
void CFrameProcessor::SetFullDamage()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_damageLock);
|
||||
CSRWExclusiveLock lock(m_damageLock);
|
||||
m_hasPendingDamage = true;
|
||||
m_pendingDamageCount = 0;
|
||||
SetFullDamageLocked();
|
||||
ReleaseSRWLockExclusive(&m_damageLock);
|
||||
}
|
||||
|
||||
void CFrameProcessor::AccumulateDamageLocked(
|
||||
@@ -97,16 +94,15 @@ void CFrameProcessor::SetFullDamageLocked()
|
||||
|
||||
bool CFrameProcessor::HasPendingDamage() const
|
||||
{
|
||||
AcquireSRWLockShared(&m_damageLock);
|
||||
CSRWSharedLock lock(m_damageLock);
|
||||
const bool result = m_hasPendingDamage;
|
||||
ReleaseSRWLockShared(&m_damageLock);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CFrameProcessor::TakePendingDamage(
|
||||
RECT dirtyRects[], unsigned * count)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_damageLock);
|
||||
CSRWExclusiveLock lock(m_damageLock);
|
||||
const bool hasDamage = m_hasPendingDamage;
|
||||
*count = hasDamage ? m_pendingDamageCount : 0;
|
||||
if (*count)
|
||||
@@ -114,7 +110,6 @@ bool CFrameProcessor::TakePendingDamage(
|
||||
*count * sizeof(*dirtyRects));
|
||||
m_hasPendingDamage = false;
|
||||
m_pendingDamageCount = 0;
|
||||
ReleaseSRWLockExclusive(&m_damageLock);
|
||||
return hasDamage;
|
||||
}
|
||||
|
||||
@@ -124,40 +119,37 @@ void CFrameProcessor::RestorePendingDamage(
|
||||
if (!hasDamage)
|
||||
return;
|
||||
|
||||
AcquireSRWLockExclusive(&m_damageLock);
|
||||
CSRWExclusiveLock lock(m_damageLock);
|
||||
CFrameProcessorUtil::AccumulateDamage(
|
||||
m_pendingDamage, &m_pendingDamageCount, &m_hasPendingDamage,
|
||||
dirtyRects, count);
|
||||
ReleaseSRWLockExclusive(&m_damageLock);
|
||||
}
|
||||
|
||||
void CFrameProcessor::CommitDamage(
|
||||
const RECT dirtyRects[], unsigned count)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_damageLock);
|
||||
CSRWExclusiveLock lock(m_damageLock);
|
||||
m_previousDamageCount = count;
|
||||
if (count)
|
||||
memcpy(m_previousDamage, dirtyRects,
|
||||
count * sizeof(*m_previousDamage));
|
||||
ReleaseSRWLockExclusive(&m_damageLock);
|
||||
}
|
||||
|
||||
void CFrameProcessor::GetPreviousDamage(
|
||||
RECT dirtyRects[], unsigned * count) const
|
||||
{
|
||||
AcquireSRWLockShared(&m_damageLock);
|
||||
CSRWSharedLock lock(m_damageLock);
|
||||
*count = m_previousDamageCount;
|
||||
if (*count)
|
||||
memcpy(dirtyRects, m_previousDamage,
|
||||
*count * sizeof(*dirtyRects));
|
||||
ReleaseSRWLockShared(&m_damageLock);
|
||||
}
|
||||
|
||||
std::unique_ptr<CFrameProcessor> CreateFrameProcessor(
|
||||
bool software, IFrameTransport * transport,
|
||||
std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent)
|
||||
CSRWLock * pipelineLock, HANDLE terminateEvent)
|
||||
{
|
||||
std::unique_ptr<CFrameProcessor> processor;
|
||||
if (software)
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CSRWLock.h"
|
||||
#include "d3d/CD3D12Device.h"
|
||||
#include "capture/CFrameBufferPool.h"
|
||||
#include "d3d/CInteropResource.h"
|
||||
@@ -51,12 +52,12 @@ protected:
|
||||
IFrameTransport * m_transport;
|
||||
std::shared_ptr<CD3D12Device> m_dx12;
|
||||
CPostProcessor * m_postProcessors;
|
||||
SRWLOCK * m_pipelineLock;
|
||||
CSRWLock * m_pipelineLock;
|
||||
HANDLE m_terminateEvent;
|
||||
CFrameBufferPool m_frameBuffers;
|
||||
Wrappers::Event m_readyEvent;
|
||||
|
||||
mutable SRWLOCK m_damageLock = SRWLOCK_INIT;
|
||||
mutable CSRWLock m_damageLock;
|
||||
RECT m_previousDamage[LG_MAX_DIRTY_RECTS] = {};
|
||||
unsigned m_previousDamageCount = 0;
|
||||
RECT m_pendingDamage[LG_MAX_DIRTY_RECTS] = {};
|
||||
@@ -77,7 +78,7 @@ public:
|
||||
CFrameProcessor(IFrameTransport * transport,
|
||||
std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent);
|
||||
CSRWLock * pipelineLock, HANDLE terminateEvent);
|
||||
virtual ~CFrameProcessor() = default;
|
||||
|
||||
virtual bool IsValid() const;
|
||||
@@ -99,4 +100,4 @@ std::unique_ptr<CFrameProcessor> CreateFrameProcessor(
|
||||
bool software, IFrameTransport * transport,
|
||||
std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent);
|
||||
CSRWLock * pipelineLock, HANDLE terminateEvent);
|
||||
|
||||
@@ -247,7 +247,7 @@ bool CFrameScheduler::ElectOwner(uint64_t now, uint32_t resetClientID)
|
||||
|
||||
void CFrameScheduler::Reset()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
for (Client& client : m_clients)
|
||||
client = {};
|
||||
m_schedule = {};
|
||||
@@ -278,7 +278,7 @@ void CFrameScheduler::Reset()
|
||||
m_lastLogAcquired = 0;
|
||||
m_lastLogSkipped = 0;
|
||||
m_lastLogPublished = 0;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
lock.Unlock();
|
||||
WakePublisher();
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ void CFrameScheduler::UpdateSubscribers(const uint32_t * clientIDs,
|
||||
unsigned count, const uint32_t * ownerClientIDs, unsigned ownerCount,
|
||||
uint64_t now)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
|
||||
uint32_t oldClientIDs [MAX_CLIENTS] = {};
|
||||
bool wasSubscribed [MAX_CLIENTS] = {};
|
||||
@@ -343,7 +343,7 @@ void CFrameScheduler::UpdateSubscribers(const uint32_t * clientIDs,
|
||||
}
|
||||
|
||||
const bool changed = ElectOwner(now) || subscribersChanged;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
lock.Unlock();
|
||||
if (changed)
|
||||
WakePublisher();
|
||||
}
|
||||
@@ -363,7 +363,7 @@ bool CFrameScheduler::UpdateSchedule(uint32_t sourceClientID,
|
||||
|
||||
if (schedule.flags & FRAME_SCHEDULE_RELEASE)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
Client * client = FindClient(schedule.clientID);
|
||||
bool wake = false;
|
||||
if (client)
|
||||
@@ -375,7 +375,7 @@ bool CFrameScheduler::UpdateSchedule(uint32_t sourceClientID,
|
||||
wake = true;
|
||||
wake |= ElectOwner(now);
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
lock.Unlock();
|
||||
if (wake)
|
||||
WakePublisher();
|
||||
return true;
|
||||
@@ -390,14 +390,11 @@ bool CFrameScheduler::UpdateSchedule(uint32_t sourceClientID,
|
||||
schedule.lease < MIN_LEASE_MS || schedule.lease > MAX_LEASE_MS)
|
||||
return false;
|
||||
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
Client * client = FindOrAllocateClient(schedule.clientID);
|
||||
|
||||
if (!client)
|
||||
{
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
const bool explicitReset =
|
||||
(schedule.flags & FRAME_SCHEDULE_RESET) != 0;
|
||||
@@ -432,7 +429,7 @@ bool CFrameScheduler::UpdateSchedule(uint32_t sourceClientID,
|
||||
wake = true;
|
||||
}
|
||||
wake |= ApplyFeedback(*client, schedule);
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
lock.Unlock();
|
||||
if (wake)
|
||||
WakePublisher();
|
||||
return true;
|
||||
@@ -555,18 +552,17 @@ void CFrameScheduler::AdvanceDelivery(Client& client, uint64_t now)
|
||||
|
||||
bool CFrameScheduler::GetSchedule(Schedule& schedule) const
|
||||
{
|
||||
AcquireSRWLockShared(&m_lock);
|
||||
CSRWSharedLock lock(m_lock);
|
||||
const bool result = m_scheduling;
|
||||
if (result)
|
||||
schedule = m_schedule;
|
||||
ReleaseSRWLockShared(&m_lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
void CFrameScheduler::ObserveFrame(uint64_t now)
|
||||
{
|
||||
bool wake = false;
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
++m_acquiredFrames;
|
||||
if (m_lastArrival && now > m_lastArrival)
|
||||
{
|
||||
@@ -587,16 +583,17 @@ void CFrameScheduler::ObserveFrame(uint64_t now)
|
||||
}
|
||||
}
|
||||
m_lastArrival = now;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
lock.Unlock();
|
||||
if (wake)
|
||||
WakePublisher();
|
||||
}
|
||||
|
||||
void CFrameScheduler::ForceFrame()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
++m_forceRequestTicket;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
WakePublisher();
|
||||
}
|
||||
|
||||
@@ -607,12 +604,9 @@ bool CFrameScheduler::GetPublishTarget(uint64_t now, uint64_t& target,
|
||||
schedule = {};
|
||||
periodic = false;
|
||||
republish = false;
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
if (!m_scheduling)
|
||||
{
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
schedule = m_schedule;
|
||||
schedule.forceTicket = m_forceRequestTicket;
|
||||
@@ -634,7 +628,6 @@ bool CFrameScheduler::GetPublishTarget(uint64_t now, uint64_t& target,
|
||||
target = periodicTarget;
|
||||
schedule.deliveryDeadlineSerial = periodic ? m_deadlineSerial : 0;
|
||||
schedule.phaseEligible = periodic;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -642,7 +635,6 @@ bool CFrameScheduler::GetPublishTarget(uint64_t now, uint64_t& target,
|
||||
schedule.deliveryDeadlineSerial = m_deadlineSerial;
|
||||
schedule.phaseEligible = true;
|
||||
target = periodicTarget;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -652,7 +644,7 @@ void CFrameScheduler::FrameMissed(const Schedule& schedule, uint64_t now,
|
||||
if (!periodic)
|
||||
return;
|
||||
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
if (m_scheduling && schedule.clientID == m_schedule.clientID &&
|
||||
schedule.generation == m_schedule.generation &&
|
||||
schedule.epoch == m_schedule.epoch &&
|
||||
@@ -666,14 +658,12 @@ void CFrameScheduler::FrameMissed(const Schedule& schedule, uint64_t now,
|
||||
if (client)
|
||||
client->nextDelivery = m_nextDeadline;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
void CFrameScheduler::FrameSuperseded()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
++m_skippedFrames;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
bool CFrameScheduler::TryFrameSubmitted(const Schedule& schedule,
|
||||
@@ -683,7 +673,8 @@ bool CFrameScheduler::TryFrameSubmitted(const Schedule& schedule,
|
||||
schedule.deliveryDeadlineSerial != schedule.deadlineSerial)
|
||||
return false;
|
||||
|
||||
if (!TryAcquireSRWLockExclusive(&m_lock))
|
||||
auto lock = CSRWExclusiveLock::Try(m_lock);
|
||||
if (!lock)
|
||||
return false;
|
||||
|
||||
bool registered = false;
|
||||
@@ -704,14 +695,13 @@ bool CFrameScheduler::TryFrameSubmitted(const Schedule& schedule,
|
||||
publication.committed = true;
|
||||
registered = true;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
return registered;
|
||||
}
|
||||
|
||||
void CFrameScheduler::FramePublished(const Schedule& schedule,
|
||||
uint32_t frameSerial, uint64_t now, bool periodic)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
if (m_scheduling && schedule.clientID == m_schedule.clientID &&
|
||||
schedule.generation == m_schedule.generation &&
|
||||
schedule.epoch == m_schedule.epoch &&
|
||||
@@ -744,14 +734,13 @@ void CFrameScheduler::FramePublished(const Schedule& schedule,
|
||||
if (client)
|
||||
client->nextDelivery = m_nextDeadline;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
void CFrameScheduler::FrameRetained(const Schedule& schedule,
|
||||
uint64_t now, bool periodic)
|
||||
{
|
||||
bool wake = false;
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
if (m_scheduling && schedule.clientID == m_schedule.clientID &&
|
||||
schedule.generation == m_schedule.generation &&
|
||||
schedule.epoch == m_schedule.epoch &&
|
||||
@@ -779,7 +768,7 @@ void CFrameScheduler::FrameRetained(const Schedule& schedule,
|
||||
if (client)
|
||||
client->nextDelivery = m_nextDeadline;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
lock.Unlock();
|
||||
|
||||
if (wake)
|
||||
WakePublisher();
|
||||
@@ -793,7 +782,8 @@ bool CFrameScheduler::TryFrameCompleted(const Schedule& schedule,
|
||||
!schedule.deadline)
|
||||
return false;
|
||||
|
||||
if (!TryAcquireSRWLockExclusive(&m_lock))
|
||||
auto lock = CSRWExclusiveLock::Try(m_lock);
|
||||
if (!lock)
|
||||
return false;
|
||||
|
||||
bool phaseValid = false;
|
||||
@@ -809,14 +799,13 @@ bool CFrameScheduler::TryFrameCompleted(const Schedule& schedule,
|
||||
phaseValid = publication->phaseValid;
|
||||
}
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
return phaseValid;
|
||||
}
|
||||
|
||||
void CFrameScheduler::FrameRepublished(const Schedule& schedule,
|
||||
uint32_t frameSerial)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
if (m_scheduling && schedule.clientID == m_schedule.clientID &&
|
||||
schedule.generation == m_schedule.generation &&
|
||||
schedule.epoch == m_schedule.epoch)
|
||||
@@ -835,13 +824,12 @@ void CFrameScheduler::FrameRepublished(const Schedule& schedule,
|
||||
}
|
||||
++m_publishedFrames;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
void CFrameScheduler::RequestRepublish()
|
||||
{
|
||||
bool wake = false;
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
Client * client = FindClient(m_schedule.clientID);
|
||||
if (m_scheduling && client && !client->deliveredFrameValid &&
|
||||
m_republishRequestTicket == m_republishAckTicket)
|
||||
@@ -849,7 +837,7 @@ void CFrameScheduler::RequestRepublish()
|
||||
++m_republishRequestTicket;
|
||||
wake = true;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
lock.Unlock();
|
||||
|
||||
if (wake)
|
||||
WakePublisher();
|
||||
@@ -859,7 +847,7 @@ unsigned CFrameScheduler::GetSecondaryRecipients(
|
||||
const uint32_t * clientIDs, unsigned count, uint32_t frameSerial,
|
||||
uint64_t now, uint32_t * recipients) const
|
||||
{
|
||||
AcquireSRWLockShared(&m_lock);
|
||||
CSRWSharedLock lock(m_lock);
|
||||
unsigned recipientCount = 0;
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
{
|
||||
@@ -891,7 +879,6 @@ unsigned CFrameScheduler::GetSecondaryRecipients(
|
||||
if (due)
|
||||
recipients[recipientCount++] = clientIDs[i];
|
||||
}
|
||||
ReleaseSRWLockShared(&m_lock);
|
||||
return recipientCount;
|
||||
}
|
||||
|
||||
@@ -902,7 +889,7 @@ bool CFrameScheduler::GetSecondaryTarget(uint32_t frameSerial,
|
||||
bool found = false;
|
||||
target = now;
|
||||
|
||||
AcquireSRWLockShared(&m_lock);
|
||||
CSRWSharedLock lock(m_lock);
|
||||
for (const Client& client : m_clients)
|
||||
{
|
||||
if (!client.clientID || !client.subscribed ||
|
||||
@@ -935,14 +922,13 @@ bool CFrameScheduler::GetSecondaryTarget(uint32_t frameSerial,
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
ReleaseSRWLockShared(&m_lock);
|
||||
return found;
|
||||
}
|
||||
|
||||
void CFrameScheduler::FrameDelivered(const uint32_t * clientIDs,
|
||||
unsigned count, uint32_t frameSerial, uint64_t now)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
for (unsigned i = 0; i < count; ++i)
|
||||
{
|
||||
Client * client = FindClient(clientIDs[i]);
|
||||
@@ -972,17 +958,13 @@ void CFrameScheduler::FrameDelivered(const uint32_t * clientIDs,
|
||||
if (!immediate || periodic)
|
||||
AdvanceDelivery(*client, now);
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
void CFrameScheduler::LogStatistics(uint64_t now)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
if (!m_scheduling || now - m_lastLog < LOG_INTERVAL_NS)
|
||||
{
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t clientID = m_schedule.clientID;
|
||||
const uint64_t period = m_schedule.period;
|
||||
@@ -997,7 +979,7 @@ void CFrameScheduler::LogStatistics(uint64_t now)
|
||||
m_lastLogAcquired = m_acquiredFrames;
|
||||
m_lastLogSkipped = m_skippedFrames;
|
||||
m_lastLogPublished = m_publishedFrames;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
lock.Unlock();
|
||||
|
||||
const double acquiredRate =
|
||||
static_cast<double>(acquired) * 1000000000.0 / elapsed;
|
||||
@@ -1019,7 +1001,8 @@ void CFrameScheduler::TryRecordFrameTiming(uint64_t duration)
|
||||
if (!duration)
|
||||
return;
|
||||
|
||||
if (!TryAcquireSRWLockExclusive(&m_lock))
|
||||
auto lock = CSRWExclusiveLock::Try(m_lock);
|
||||
if (!lock)
|
||||
return;
|
||||
|
||||
m_workTiming[m_workTimingIndex] = duration;
|
||||
@@ -1052,5 +1035,4 @@ void CFrameScheduler::TryRecordFrameTiming(uint64_t duration)
|
||||
m_workEstimate = sorted[m_workTimingCount - discarded - 1];
|
||||
}
|
||||
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CSRWLock.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -100,7 +102,7 @@ private:
|
||||
static const unsigned PUBLICATION_HISTORY_SIZE = 128;
|
||||
static const unsigned WORK_TIMING_HISTORY_SIZE = 32;
|
||||
|
||||
mutable SRWLOCK m_lock = SRWLOCK_INIT;
|
||||
mutable CSRWLock m_lock;
|
||||
HANDLE m_wakeEvent = nullptr;
|
||||
Client m_clients[MAX_CLIENTS] = {};
|
||||
Schedule m_schedule = {};
|
||||
|
||||
@@ -35,21 +35,20 @@ static_assert(CAPTURE_PIPELINE_SLOTS == 2,
|
||||
class CPublishPending
|
||||
{
|
||||
private:
|
||||
SRWLOCK * m_lock;
|
||||
CSRWLock& m_lock;
|
||||
bool * m_pending;
|
||||
HANDLE m_event;
|
||||
bool m_active = true;
|
||||
|
||||
public:
|
||||
CPublishPending(SRWLOCK * lock, bool * pending, HANDLE event) :
|
||||
m_lock(lock),
|
||||
CPublishPending(CSRWLock& stateLock, bool * pending, HANDLE event) :
|
||||
m_lock(stateLock),
|
||||
m_pending(pending),
|
||||
m_event(event)
|
||||
{
|
||||
AcquireSRWLockExclusive(m_lock);
|
||||
CSRWExclusiveLock guard(m_lock);
|
||||
*m_pending = true;
|
||||
ResetEvent(m_event);
|
||||
ReleaseSRWLockExclusive(m_lock);
|
||||
}
|
||||
|
||||
~CPublishPending()
|
||||
@@ -62,10 +61,11 @@ public:
|
||||
if (!m_active)
|
||||
return;
|
||||
|
||||
AcquireSRWLockExclusive(m_lock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
*m_pending = false;
|
||||
SetEvent(m_event);
|
||||
ReleaseSRWLockExclusive(m_lock);
|
||||
}
|
||||
m_active = false;
|
||||
}
|
||||
};
|
||||
@@ -73,7 +73,7 @@ public:
|
||||
CHardwareFrameProcessor::CHardwareFrameProcessor(
|
||||
IFrameTransport * transport, std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent) :
|
||||
CSRWLock * pipelineLock, HANDLE terminateEvent) :
|
||||
CFrameProcessor(transport, std::move(dx12), postProcessors,
|
||||
pipelineLock, terminateEvent)
|
||||
{
|
||||
@@ -116,15 +116,17 @@ void CHardwareFrameProcessor::AccumulateDamageLocked(
|
||||
|
||||
void CHardwareFrameProcessor::ResetCandidates()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_candidateLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_candidateLock);
|
||||
for (FrameCandidate& candidate : m_candidates)
|
||||
candidate = {};
|
||||
ReleaseSRWLockExclusive(&m_candidateLock);
|
||||
}
|
||||
|
||||
AcquireSRWLockExclusive(&m_damageLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_damageLock);
|
||||
for (CandidateDamageTail& tail : m_candidateDamageTail)
|
||||
tail = {};
|
||||
ReleaseSRWLockExclusive(&m_damageLock);
|
||||
}
|
||||
SignalCandidateState();
|
||||
}
|
||||
|
||||
@@ -143,14 +145,13 @@ void CHardwareFrameProcessor::ResetPipeline()
|
||||
bool CHardwareFrameProcessor::HasReadyFrame() const
|
||||
{
|
||||
bool ready = false;
|
||||
AcquireSRWLockShared(&m_candidateLock);
|
||||
CSRWSharedLock lock(m_candidateLock);
|
||||
for (const FrameCandidate& candidate : m_candidates)
|
||||
if (candidate.state == CANDIDATE_READY)
|
||||
{
|
||||
ready = true;
|
||||
break;
|
||||
}
|
||||
ReleaseSRWLockShared(&m_candidateLock);
|
||||
return ready;
|
||||
}
|
||||
|
||||
@@ -163,7 +164,8 @@ int CHardwareFrameProcessor::AcquireCandidate(
|
||||
bool idle = true;
|
||||
bool publishing = false;
|
||||
|
||||
AcquireSRWLockExclusive(&m_candidateLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_candidateLock);
|
||||
for (unsigned i = 0; i < ARRAYSIZE(m_candidates); ++i)
|
||||
{
|
||||
if (m_candidates[i].state != CANDIDATE_FREE)
|
||||
@@ -202,7 +204,7 @@ int CHardwareFrameProcessor::AcquireCandidate(
|
||||
candidate.state = CANDIDATE_PREPARING;
|
||||
candidate.sequence = ++m_candidateSequence;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_candidateLock);
|
||||
}
|
||||
|
||||
if (superseded)
|
||||
m_transport->FrameSuperseded();
|
||||
@@ -214,9 +216,10 @@ void CHardwareFrameProcessor::ReleaseCandidate(unsigned candidateIndex)
|
||||
if (candidateIndex >= ARRAYSIZE(m_candidates))
|
||||
return;
|
||||
|
||||
AcquireSRWLockExclusive(&m_candidateLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_candidateLock);
|
||||
m_candidates[candidateIndex].state = CANDIDATE_FREE;
|
||||
ReleaseSRWLockExclusive(&m_candidateLock);
|
||||
}
|
||||
SignalCandidateState();
|
||||
}
|
||||
|
||||
@@ -280,14 +283,11 @@ bool CHardwareFrameProcessor::ExecuteCandidateCopy(
|
||||
|
||||
for (;;)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_copySubmitLock);
|
||||
if (!m_publishPending)
|
||||
{
|
||||
const bool result = copySlot->Execute();
|
||||
ReleaseSRWLockExclusive(&m_copySubmitLock);
|
||||
return result;
|
||||
CSRWExclusiveLock lock(m_copySubmitLock);
|
||||
if (!m_publishPending)
|
||||
return copySlot->Execute();
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_copySubmitLock);
|
||||
|
||||
const DWORD result = WaitForMultipleObjects(
|
||||
ARRAYSIZE(waitHandles), waitHandles, FALSE, INFINITE);
|
||||
@@ -313,7 +313,8 @@ void CHardwareFrameProcessor::CandidateCompletionFunction(
|
||||
const bool timingValid = result && slot->GetGPUTimes(gpuStart, gpuEnd);
|
||||
|
||||
bool forceFrame = false;
|
||||
AcquireSRWLockExclusive(&processor->m_candidateLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(processor->m_candidateLock);
|
||||
if (candidate->state == CANDIDATE_PREPARING)
|
||||
{
|
||||
candidate->prepareReady = CFrameScheduler::Nanotime();
|
||||
@@ -324,7 +325,7 @@ void CHardwareFrameProcessor::CandidateCompletionFunction(
|
||||
result ? CANDIDATE_READY : CANDIDATE_FREE;
|
||||
forceFrame = result && candidate->timingToken != 0;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&processor->m_candidateLock);
|
||||
}
|
||||
|
||||
if (!result)
|
||||
{
|
||||
@@ -358,7 +359,8 @@ void CHardwareFrameProcessor::CompletionFunction(
|
||||
uint64_t prepareGPUEnd;
|
||||
uint64_t timingStart;
|
||||
bool prepareTimingValid;
|
||||
AcquireSRWLockShared(&processor->m_candidateLock);
|
||||
{
|
||||
CSRWSharedLock lock(processor->m_candidateLock);
|
||||
const FrameCandidate& candidate =
|
||||
processor->m_candidates[candidateIndex];
|
||||
prepareCopyStart = candidate.prepareCopyStart;
|
||||
@@ -367,7 +369,7 @@ void CHardwareFrameProcessor::CompletionFunction(
|
||||
prepareGPUEnd = candidate.prepareGPUEnd;
|
||||
timingStart = candidate.timingStart;
|
||||
prepareTimingValid = candidate.prepareTimingValid;
|
||||
ReleaseSRWLockShared(&processor->m_candidateLock);
|
||||
}
|
||||
|
||||
const uint64_t publishStart = fbRes->GetCopyStart();
|
||||
uint64_t gpuCopyStart = 0;
|
||||
@@ -443,13 +445,14 @@ bool CHardwareFrameProcessor::Publish(
|
||||
uint64_t publishStart)
|
||||
{
|
||||
CPublishPending publishPending(
|
||||
&m_copySubmitLock, &m_publishPending, m_copySubmitEvent.Get());
|
||||
CSRWSharedLock pipelineLock(m_pipelineLock);
|
||||
m_copySubmitLock, &m_publishPending, m_copySubmitEvent.Get());
|
||||
CSRWSharedLock pipelineLock(*m_pipelineLock);
|
||||
|
||||
int selectedCandidate = -1;
|
||||
uint64_t newestSequence = 0;
|
||||
|
||||
AcquireSRWLockExclusive(&m_candidateLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_candidateLock);
|
||||
for (unsigned i = 0; i < ARRAYSIZE(m_candidates); ++i)
|
||||
if (m_candidates[i].state == CANDIDATE_READY &&
|
||||
(selectedCandidate < 0 ||
|
||||
@@ -462,7 +465,7 @@ bool CHardwareFrameProcessor::Publish(
|
||||
if (selectedCandidate >= 0)
|
||||
m_candidates[static_cast<unsigned>(selectedCandidate)].state =
|
||||
CANDIDATE_PUBLISHING;
|
||||
ReleaseSRWLockExclusive(&m_candidateLock);
|
||||
}
|
||||
|
||||
if (selectedCandidate < 0)
|
||||
return false;
|
||||
@@ -471,18 +474,21 @@ bool CHardwareFrameProcessor::Publish(
|
||||
|
||||
const auto restoreCandidate = [this, candidateIndex]()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_candidateLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_candidateLock);
|
||||
if (m_candidates[candidateIndex].state == CANDIDATE_PUBLISHING)
|
||||
m_candidates[candidateIndex].state = CANDIDATE_READY;
|
||||
ReleaseSRWLockExclusive(&m_candidateLock);
|
||||
}
|
||||
SignalCandidateState();
|
||||
};
|
||||
|
||||
AcquireSRWLockShared(&m_candidateLock);
|
||||
const bool candidateValid =
|
||||
bool candidateValid;
|
||||
{
|
||||
CSRWSharedLock lock(m_candidateLock);
|
||||
candidateValid =
|
||||
m_candidates[candidateIndex].state == CANDIDATE_PUBLISHING &&
|
||||
m_candidates[candidateIndex].resource.Get();
|
||||
ReleaseSRWLockShared(&m_candidateLock);
|
||||
}
|
||||
if (!candidateValid)
|
||||
{
|
||||
restoreCandidate();
|
||||
@@ -564,7 +570,8 @@ bool CHardwareFrameProcessor::Publish(
|
||||
frameSchedule.phaseEligible = false;
|
||||
fbRes->SetSchedule(frameSchedule);
|
||||
|
||||
AcquireSRWLockExclusive(&m_damageLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_damageLock);
|
||||
if (candidate.nbDirtyRects)
|
||||
memcpy(m_previousDamage, candidate.dirtyRects,
|
||||
candidate.nbDirtyRects * sizeof(*m_previousDamage));
|
||||
@@ -580,17 +587,18 @@ bool CHardwareFrameProcessor::Publish(
|
||||
tail.ownerSequence = 0;
|
||||
tail.active = false;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_damageLock);
|
||||
}
|
||||
|
||||
const bool submitted = copySlot->Execute();
|
||||
publishPending.Clear();
|
||||
if (!submitted)
|
||||
{
|
||||
SetFullDamage();
|
||||
AcquireSRWLockShared(&m_candidateLock);
|
||||
const bool callbackPending =
|
||||
candidate.state == CANDIDATE_PUBLISHING;
|
||||
ReleaseSRWLockShared(&m_candidateLock);
|
||||
bool callbackPending;
|
||||
{
|
||||
CSRWSharedLock lock(m_candidateLock);
|
||||
callbackPending = candidate.state == CANDIDATE_PUBLISHING;
|
||||
}
|
||||
if (callbackPending && !copySlot->HasSubmittedWork())
|
||||
{
|
||||
m_transport->FailFrameBuffer(buffer.frameIndex);
|
||||
@@ -605,7 +613,8 @@ bool CHardwareFrameProcessor::Publish(
|
||||
buffer.frameIndex, schedule, periodic, deliveredToOwner);
|
||||
|
||||
unsigned superseded = 0;
|
||||
AcquireSRWLockExclusive(&m_candidateLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_candidateLock);
|
||||
for (FrameCandidate& ready : m_candidates)
|
||||
if (ready.state == CANDIDATE_READY &&
|
||||
ready.sequence < candidateSequence)
|
||||
@@ -613,7 +622,7 @@ bool CHardwareFrameProcessor::Publish(
|
||||
ready.state = CANDIDATE_FREE;
|
||||
++superseded;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_candidateLock);
|
||||
}
|
||||
for (unsigned i = 0; i < superseded; ++i)
|
||||
m_transport->FrameSuperseded();
|
||||
SignalCandidateState();
|
||||
@@ -654,13 +663,14 @@ bool CHardwareFrameProcessor::Submit(const FrameSubmission& submission)
|
||||
static_cast<unsigned>(selectedCandidate);
|
||||
FrameCandidate& candidate = m_candidates[candidateIndex];
|
||||
|
||||
CSRWSharedLock pipelineLock(m_pipelineLock);
|
||||
CSRWSharedLock pipelineLock(*m_pipelineLock);
|
||||
CPostProcessor& postProcessor = m_postProcessors[candidateIndex];
|
||||
const D12FrameFormat& dstFormat = postProcessor.GetOutputFormat();
|
||||
|
||||
RECT currentDirtyRects[LG_MAX_DIRTY_RECTS] = {};
|
||||
unsigned nbDirtyRects = 0;
|
||||
AcquireSRWLockExclusive(&m_damageLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_damageLock);
|
||||
if (m_hasPendingDamage)
|
||||
{
|
||||
nbDirtyRects = m_pendingDamageCount;
|
||||
@@ -673,7 +683,7 @@ bool CHardwareFrameProcessor::Submit(const FrameSubmission& submission)
|
||||
tail.nbDirtyRects = 0;
|
||||
tail.hasDamage = false;
|
||||
tail.active = true;
|
||||
ReleaseSRWLockExclusive(&m_damageLock);
|
||||
}
|
||||
|
||||
CD3D12CommandSlot * copySlot = m_dx12->GetCopySlot(candidateIndex);
|
||||
if (!copySlot)
|
||||
|
||||
@@ -67,8 +67,8 @@ private:
|
||||
|
||||
FrameCandidate m_candidates[CAPTURE_PIPELINE_SLOTS];
|
||||
CandidateDamageTail m_candidateDamageTail[CAPTURE_PIPELINE_SLOTS];
|
||||
mutable SRWLOCK m_candidateLock = SRWLOCK_INIT;
|
||||
SRWLOCK m_copySubmitLock = SRWLOCK_INIT;
|
||||
mutable CSRWLock m_candidateLock;
|
||||
CSRWLock m_copySubmitLock;
|
||||
uint64_t m_candidateSequence = 0;
|
||||
bool m_publishPending = false;
|
||||
Wrappers::Event m_candidateAvailableEvent;
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
CHardwareFrameProcessor(IFrameTransport * transport,
|
||||
std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent);
|
||||
CSRWLock * pipelineLock, HANDLE terminateEvent);
|
||||
|
||||
bool IsValid() const override;
|
||||
bool Submit(const FrameSubmission& submission) override;
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
CSoftwareFrameProcessor::CSoftwareFrameProcessor(
|
||||
IFrameTransport * transport, std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent) :
|
||||
CSRWLock * pipelineLock, HANDLE terminateEvent) :
|
||||
CFrameProcessor(transport, std::move(dx12), postProcessors,
|
||||
pipelineLock, terminateEvent)
|
||||
{
|
||||
@@ -112,7 +112,7 @@ void CSoftwareFrameProcessor::CompletionFunction(
|
||||
|
||||
bool CSoftwareFrameProcessor::Submit(const FrameSubmission& submission)
|
||||
{
|
||||
CSRWSharedLock pipelineLock(m_pipelineLock);
|
||||
CSRWSharedLock pipelineLock(*m_pipelineLock);
|
||||
CPostProcessor& postProcessor = m_postProcessors[0];
|
||||
const D12FrameFormat& dstFormat = postProcessor.GetOutputFormat();
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ public:
|
||||
CSoftwareFrameProcessor(IFrameTransport * transport,
|
||||
std::shared_ptr<CD3D12Device> dx12,
|
||||
CPostProcessor postProcessors[CAPTURE_PIPELINE_SLOTS],
|
||||
SRWLOCK * pipelineLock, HANDLE terminateEvent);
|
||||
CSRWLock * pipelineLock, HANDLE terminateEvent);
|
||||
|
||||
bool Submit(const FrameSubmission& submission) override;
|
||||
bool HasReadyFrame() const override { return false; }
|
||||
|
||||
@@ -655,7 +655,7 @@ bool CSwapChainProcessor::SwapChainNewFrame(ComPtr<IDXGIResource> acquiredBuffer
|
||||
unsigned timingEffectIndex = 0;
|
||||
uint64_t timingToken = 0;
|
||||
{
|
||||
CSRWExclusiveLock pipelineLock(&m_pipelineLock);
|
||||
CSRWExclusiveLock pipelineLock(m_pipelineLock);
|
||||
m_postProcessors[0].Update(srcFormat);
|
||||
|
||||
frameMetadataChanged = noImageUpdate &&
|
||||
|
||||
@@ -59,7 +59,7 @@ private:
|
||||
CPostProcessor m_postProcessors[CAPTURE_PIPELINE_SLOTS];
|
||||
std::unique_ptr<CFrameProcessor> m_frameProcessor;
|
||||
// Reconfiguration is exclusive while per-candidate recording is shared.
|
||||
SRWLOCK m_pipelineLock = SRWLOCK_INIT;
|
||||
CSRWLock m_pipelineLock;
|
||||
|
||||
Wrappers::HandleT<Wrappers::HandleTraits::HANDLENullTraits> m_thread[3];
|
||||
Wrappers::Event m_terminateEvent;
|
||||
|
||||
@@ -575,7 +575,7 @@ void CD3D12CommandQueue::WaitForIdle()
|
||||
bool CD3D12CommandQueue::Submit(CD3D12CommandSlot& slot)
|
||||
{
|
||||
bool result = false;
|
||||
AcquireSRWLockExclusive(&m_submitLock);
|
||||
CSRWExclusiveLock lock(m_submitLock);
|
||||
|
||||
do
|
||||
{
|
||||
@@ -636,7 +636,6 @@ bool CD3D12CommandQueue::Submit(CD3D12CommandSlot& slot)
|
||||
}
|
||||
while (false);
|
||||
|
||||
ReleaseSRWLockExclusive(&m_submitLock);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CSRWLock.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <wdf.h>
|
||||
#include <wrl.h>
|
||||
@@ -147,7 +149,7 @@ class CD3D12CommandQueue
|
||||
ComPtr<ID3D12CommandQueue> m_queue;
|
||||
ComPtr<ID3D12Fence > m_fence;
|
||||
UINT64 m_fenceValue = 0;
|
||||
SRWLOCK m_submitLock = SRWLOCK_INIT;
|
||||
CSRWLock m_submitLock;
|
||||
std::atomic<bool> m_failed = false;
|
||||
|
||||
CD3D12CommandSlot m_slots[MAX_SLOTS];
|
||||
|
||||
@@ -178,7 +178,7 @@ bool CDisplayConfiguration::LoadModes(const FrameMemoryLimits& limits)
|
||||
if (!hasPreferred)
|
||||
newModes.front().preferred = true;
|
||||
|
||||
CSRWExclusiveLock lock(&m_modeLock);
|
||||
CSRWExclusiveLock lock(m_modeLock);
|
||||
m_modes = std::move(newModes);
|
||||
return true;
|
||||
}
|
||||
@@ -193,7 +193,7 @@ bool CDisplayConfiguration::ReloadSettings(
|
||||
{
|
||||
bool modesLoaded = false;
|
||||
{
|
||||
CSRWExclusiveLock reloadLock(&m_reloadLock);
|
||||
CSRWExclusiveLock reloadLock(m_reloadLock);
|
||||
|
||||
bool settingsUpdated = true;
|
||||
CSettings::DisplayMode extraMode = {};
|
||||
@@ -252,7 +252,7 @@ CDisplayConfiguration::SetResolution(
|
||||
mode.preferred = true;
|
||||
|
||||
{
|
||||
CSRWExclusiveLock reloadLock(&m_reloadLock);
|
||||
CSRWExclusiveLock reloadLock(m_reloadLock);
|
||||
if (!m_settings.SetExtraMode(mode))
|
||||
result.status = ResolutionStatus::SETTINGS_FAILED;
|
||||
else if (!LoadModes(limits))
|
||||
@@ -271,7 +271,7 @@ CDisplayConfiguration::SetResolution(
|
||||
|
||||
void CDisplayConfiguration::InitializeEdid(bool hdr)
|
||||
{
|
||||
CSRWExclusiveLock lock(&m_modeLock);
|
||||
CSRWExclusiveLock lock(m_modeLock);
|
||||
if (m_edid.Size())
|
||||
return;
|
||||
|
||||
@@ -281,7 +281,7 @@ void CDisplayConfiguration::InitializeEdid(bool hdr)
|
||||
|
||||
void CDisplayConfiguration::RebuildEdid(bool hdr)
|
||||
{
|
||||
CSRWExclusiveLock lock(&m_modeLock);
|
||||
CSRWExclusiveLock lock(m_modeLock);
|
||||
m_edid.Build(hdr);
|
||||
m_hdrEnabled = hdr;
|
||||
}
|
||||
@@ -290,7 +290,7 @@ CDisplayConfiguration::Description
|
||||
CDisplayConfiguration::GetDescription() const
|
||||
{
|
||||
Description result;
|
||||
CSRWSharedLock lock(&m_modeLock);
|
||||
CSRWSharedLock lock(m_modeLock);
|
||||
result.modeCount = m_modes.size();
|
||||
if (m_edid.Size())
|
||||
result.edid.assign(m_edid.Data(), m_edid.Data() + m_edid.Size());
|
||||
@@ -300,7 +300,7 @@ CDisplayConfiguration::GetDescription() const
|
||||
CSettings::DisplayModes CDisplayConfiguration::SnapshotModes(
|
||||
bool * hdrEnabled) const
|
||||
{
|
||||
CSRWSharedLock lock(&m_modeLock);
|
||||
CSRWSharedLock lock(m_modeLock);
|
||||
if (hdrEnabled)
|
||||
*hdrEnabled = m_hdrEnabled;
|
||||
return m_modes;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CSRWLock.h"
|
||||
|
||||
#include "config/CSettings.h"
|
||||
#include "display/CEdid.h"
|
||||
#include "display/IddCxCompat.h"
|
||||
@@ -59,8 +61,8 @@ private:
|
||||
|
||||
// Registry-backed changes are serialized before publishing a replacement
|
||||
// mode list. Readers only hold m_modeLock long enough to take a snapshot.
|
||||
SRWLOCK m_reloadLock = SRWLOCK_INIT;
|
||||
mutable SRWLOCK m_modeLock = SRWLOCK_INIT;
|
||||
CSRWLock m_reloadLock;
|
||||
mutable CSRWLock m_modeLock;
|
||||
|
||||
CSettings::DisplayModes m_modes;
|
||||
CEdid m_edid;
|
||||
|
||||
@@ -62,10 +62,10 @@ NTSTATUS CMonitorContext::AssignSwapChain(
|
||||
return STATUS_GRAPHICS_INDIRECT_DISPLAY_ABANDON_SWAPCHAIN;
|
||||
}
|
||||
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
if (!IsAssignmentCurrent(assignmentGeneration))
|
||||
{
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
lock.Unlock();
|
||||
DEBUG_INFO("Swap chain assignment canceled before processor startup");
|
||||
return STATUS_GRAPHICS_INDIRECT_DISPLAY_ABANDON_SWAPCHAIN;
|
||||
}
|
||||
@@ -82,13 +82,12 @@ NTSTATUS CMonitorContext::AssignSwapChain(
|
||||
{
|
||||
auto processor = std::move(m_swapChain);
|
||||
dx11Device = std::move(m_dx11Device);
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
lock.Unlock();
|
||||
processor.reset();
|
||||
dx11Device.reset();
|
||||
m_devContext->OnSwapChainReleased();
|
||||
return STATUS_GRAPHICS_INDIRECT_DISPLAY_ABANDON_SWAPCHAIN;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -105,10 +104,11 @@ void CMonitorContext::DetachSwapChain()
|
||||
std::unique_ptr<CSwapChainProcessor> processor;
|
||||
std::shared_ptr<CD3D11Device> dx11Device;
|
||||
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
processor = std::move(m_swapChain);
|
||||
dx11Device = std::move(m_dx11Device);
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
const bool hadSwapChain = !!processor;
|
||||
processor.reset();
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CSRWLock.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <wdf.h>
|
||||
#include <IddCx.h>
|
||||
@@ -40,7 +42,7 @@ private:
|
||||
// Guards the swap chain and device pointers. Assign and unassign can run
|
||||
// concurrently (an unassign triggered by the worker's WdfObjectDelete can
|
||||
// race the next assign), and shared_ptr copy/reset is not thread safe.
|
||||
SRWLOCK m_lock = SRWLOCK_INIT;
|
||||
CSRWLock m_lock;
|
||||
|
||||
// IddCx can issue a replacement assignment before an earlier assignment
|
||||
// has finished creating its devices. Serialize those expensive setup paths
|
||||
|
||||
@@ -30,9 +30,11 @@ void CMonitorManager::Create(UINT connectorIndex, IDDCX_ADAPTER adapter,
|
||||
|
||||
// We support a single monitor; never create a second one if one already
|
||||
// exists (a replug must clear m_monitor via departure first).
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
const bool haveMonitor = m_monitor != WDF_NO_HANDLE;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
bool haveMonitor;
|
||||
{
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
haveMonitor = m_monitor != WDF_NO_HANDLE;
|
||||
}
|
||||
if (haveMonitor)
|
||||
{
|
||||
DEBUG_WARN("FinishInit skipped: a monitor already exists");
|
||||
@@ -76,9 +78,10 @@ void CMonitorManager::Create(UINT connectorIndex, IDDCX_ADAPTER adapter,
|
||||
|
||||
DEBUG_INFO("Monitor object created (%p)", createOut.MonitorObject);
|
||||
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
m_monitor = createOut.MonitorObject;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
auto * wrapper = WdfObjectGet_CMonitorContextWrapper(m_monitor);
|
||||
wrapper->context = new CMonitorContext(m_monitor, owner);
|
||||
@@ -96,56 +99,65 @@ void CMonitorManager::Create(UINT connectorIndex, IDDCX_ADAPTER adapter,
|
||||
|
||||
CMonitorManager::ReplugAction CMonitorManager::Replug()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
IDDCX_MONITOR monitor;
|
||||
{
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
|
||||
if (m_replugMonitor || (m_swapChainAssigned && !m_swapChainReady))
|
||||
{
|
||||
// Coalesce changes received while a swap chain is being initialized, the
|
||||
// old one is draining, or its replacement is being initialized.
|
||||
// Coalesce changes received while a swap chain is being initialized,
|
||||
// the old one is draining, or its replacement is being initialized.
|
||||
m_replugPending = true;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
return ReplugAction::NONE;
|
||||
}
|
||||
|
||||
IDDCX_MONITOR monitor = m_monitor;
|
||||
monitor = m_monitor;
|
||||
if (monitor == WDF_NO_HANDLE)
|
||||
{
|
||||
m_replugMonitor = true;
|
||||
m_monitorDeparted = true;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Clear the handle before departing so nothing calls an IddCx monitor
|
||||
// API on a departing/destroyed handle. Create publishes the new one.
|
||||
m_replugMonitor = true;
|
||||
m_monitorDeparted = false;
|
||||
m_waitForSwapChainRelease = m_swapChainAssigned;
|
||||
m_monitor = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (monitor == WDF_NO_HANDLE)
|
||||
{
|
||||
// Either no monitor yet, or one is already pending; build it now and
|
||||
// cancel any queued rebuild so we do not create two.
|
||||
m_createQueued.store(0);
|
||||
return ReplugAction::CREATE;
|
||||
}
|
||||
|
||||
// Clear the handle before departing so nothing calls an IddCx monitor API
|
||||
// on a departing/destroyed handle. Create publishes the new one.
|
||||
m_replugMonitor = true;
|
||||
m_monitorDeparted = false;
|
||||
m_waitForSwapChainRelease = m_swapChainAssigned;
|
||||
m_monitor = nullptr;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
|
||||
DEBUG_TRACE("ReplugMonitor");
|
||||
NTSTATUS status = IddCxMonitorDeparture(monitor);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
m_replugMonitor = false;
|
||||
m_replugPending = false;
|
||||
m_monitorDeparted = false;
|
||||
m_waitForSwapChainRelease = false;
|
||||
m_monitor = monitor;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
DEBUG_ERROR("IddCxMonitorDeparture Failed (0x%08x)", status);
|
||||
return ReplugAction::NONE;
|
||||
}
|
||||
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
bool rebuild;
|
||||
{
|
||||
CSRWExclusiveLock departedLock(m_lock);
|
||||
m_monitorDeparted = true;
|
||||
const bool rebuild = !m_waitForSwapChainRelease;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
rebuild = !m_waitForSwapChainRelease;
|
||||
}
|
||||
|
||||
// If there was no swap chain there will be no unassign callback to queue
|
||||
// the rebuild. Otherwise OnSwapChainReleased does so after teardown drains.
|
||||
@@ -157,33 +169,31 @@ CMonitorManager::ReplugAction CMonitorManager::Replug()
|
||||
|
||||
void CMonitorManager::RequestMode(const CSettings::DisplayMode& mode)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
m_setMode = mode;
|
||||
m_doSetMode = true;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
void CMonitorManager::OnDestroyed(IDDCX_MONITOR monitor)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
if (m_monitor == monitor)
|
||||
m_monitor = nullptr;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
void CMonitorManager::OnSwapChainAssigned()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
m_swapChainAssigned = true;
|
||||
m_swapChainReady = false;
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
void CMonitorManager::OnSwapChainReleased()
|
||||
{
|
||||
bool rebuild = false;
|
||||
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
m_swapChainAssigned = false;
|
||||
m_swapChainReady = false;
|
||||
if (m_replugMonitor && m_waitForSwapChainRelease)
|
||||
@@ -191,7 +201,7 @@ void CMonitorManager::OnSwapChainReleased()
|
||||
m_waitForSwapChainRelease = false;
|
||||
rebuild = m_monitorDeparted;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
if (rebuild)
|
||||
m_createQueued.store(1);
|
||||
@@ -202,7 +212,8 @@ CMonitorManager::ReadyAction CMonitorManager::OnSwapChainReady()
|
||||
ReadyAction action = {};
|
||||
bool replug = false;
|
||||
|
||||
AcquireSRWLockExclusive(&m_lock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_lock);
|
||||
m_swapChainReady = true;
|
||||
if (m_replugMonitor)
|
||||
{
|
||||
@@ -228,7 +239,7 @@ CMonitorManager::ReadyAction CMonitorManager::OnSwapChainReady()
|
||||
m_doSetMode = false;
|
||||
action.setMode = true;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_lock);
|
||||
}
|
||||
|
||||
action.replug = replug;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CSRWLock.h"
|
||||
#include <Windows.h>
|
||||
#include <wdf.h>
|
||||
#include <IddCx.h>
|
||||
@@ -58,7 +59,7 @@ private:
|
||||
|
||||
// Guards the monitor/replug/swap-chain state. These values are touched by
|
||||
// IddCx callback threads, the swap-chain thread, and the transport timer.
|
||||
SRWLOCK m_lock = SRWLOCK_INIT;
|
||||
CSRWLock m_lock;
|
||||
|
||||
bool m_replugMonitor = false;
|
||||
bool m_replugPending = false;
|
||||
|
||||
@@ -95,7 +95,7 @@ void CInputPipeServer::DeInit()
|
||||
m_stopEvent = nullptr;
|
||||
}
|
||||
|
||||
CSRWExclusiveLock lock(&m_queueLock);
|
||||
CSRWExclusiveLock lock(m_queueLock);
|
||||
m_queueHead = 0;
|
||||
m_queueCount = 0;
|
||||
m_mouseMode = MouseMode::NONE;
|
||||
@@ -269,7 +269,7 @@ bool CInputPipeServer::SendMouseRelative(
|
||||
payload.mouseRelative.deltaY = deltaY;
|
||||
payload.mouseRelative.wheel = wheel;
|
||||
|
||||
CSRWExclusiveLock lock(&m_queueLock);
|
||||
CSRWExclusiveLock lock(m_queueLock);
|
||||
const bool pureMotion = wheel == 0 && buttons == m_relativeButtons;
|
||||
const bool switching = m_mouseMode == MouseMode::ABSOLUTE_INPUT;
|
||||
bool queued = (m_state.load(std::memory_order_relaxed) & 1) != 0;
|
||||
@@ -316,7 +316,7 @@ bool CInputPipeServer::SendMouseAbsolute(
|
||||
payload.mouseAbsolute.y = y;
|
||||
payload.mouseAbsolute.wheel = wheel;
|
||||
|
||||
CSRWExclusiveLock lock(&m_queueLock);
|
||||
CSRWExclusiveLock lock(m_queueLock);
|
||||
const bool pureMotion = wheel == 0 && buttons == m_absoluteButtons;
|
||||
const bool switching = m_mouseMode == MouseMode::RELATIVE_INPUT;
|
||||
bool queued = (m_state.load(std::memory_order_relaxed) & 1) != 0;
|
||||
@@ -360,7 +360,7 @@ bool CInputPipeServer::SendKeyboard(
|
||||
payload.keyboard.keys[i] = keys[i];
|
||||
}
|
||||
|
||||
CSRWExclusiveLock lock(&m_queueLock);
|
||||
CSRWExclusiveLock lock(m_queueLock);
|
||||
const bool queued = (m_state.load(std::memory_order_relaxed) & 1) &&
|
||||
QueueLocked(LG_INPUT_PIPE_MESSAGE_KEYBOARD, payload, false);
|
||||
if (!queued)
|
||||
@@ -373,7 +373,7 @@ bool CInputPipeServer::Reset()
|
||||
if (!(m_state.load(std::memory_order_acquire) & 1))
|
||||
return false;
|
||||
|
||||
CSRWExclusiveLock lock(&m_queueLock);
|
||||
CSRWExclusiveLock lock(m_queueLock);
|
||||
bool queued = (m_state.load(std::memory_order_relaxed) & 1) != 0;
|
||||
if (queued)
|
||||
queued = QueueResetLocked();
|
||||
@@ -384,7 +384,7 @@ bool CInputPipeServer::Reset()
|
||||
|
||||
bool CInputPipeServer::Pop(QueueItem& item)
|
||||
{
|
||||
CSRWExclusiveLock lock(&m_queueLock);
|
||||
CSRWExclusiveLock lock(m_queueLock);
|
||||
if (!m_queueCount)
|
||||
return false;
|
||||
|
||||
@@ -411,7 +411,7 @@ bool CInputPipeServer::Send(const QueueItem& item)
|
||||
LARGE_INTEGER start = {};
|
||||
LARGE_INTEGER end = {};
|
||||
{
|
||||
CSRWSharedLock lock(&m_connectionLock);
|
||||
CSRWSharedLock lock(m_connectionLock);
|
||||
const uint64_t state = m_state.load(std::memory_order_acquire);
|
||||
current = (state & 1) && item.state == state;
|
||||
if (current)
|
||||
@@ -465,7 +465,7 @@ void CInputPipeServer::LogStatistics()
|
||||
uint64_t resyncDiscarded;
|
||||
size_t queueHighWater;
|
||||
{
|
||||
CSRWExclusiveLock lock(&m_queueLock);
|
||||
CSRWExclusiveLock lock(m_queueLock);
|
||||
enqueued = m_statEnqueued;
|
||||
relativeCoalesced = m_statRelativeCoalesced;
|
||||
absoluteCoalesced = m_statAbsoluteCoalesced;
|
||||
@@ -526,7 +526,7 @@ void CInputPipeServer::LogStatistics()
|
||||
|
||||
void CInputPipeServer::Invalidate(uint64_t state, bool requireMatch)
|
||||
{
|
||||
CSRWExclusiveLock connectionLock(&m_connectionLock);
|
||||
CSRWExclusiveLock connectionLock(m_connectionLock);
|
||||
uint64_t current = m_state.load(std::memory_order_relaxed);
|
||||
for (;;)
|
||||
{
|
||||
@@ -537,7 +537,7 @@ void CInputPipeServer::Invalidate(uint64_t state, bool requireMatch)
|
||||
break;
|
||||
}
|
||||
|
||||
CSRWExclusiveLock queueLock(&m_queueLock);
|
||||
CSRWExclusiveLock queueLock(m_queueLock);
|
||||
m_queueHead = 0;
|
||||
m_queueCount = 0;
|
||||
}
|
||||
@@ -578,8 +578,8 @@ void CInputPipeServer::Thread()
|
||||
|
||||
void CInputPipeServer::OnPipeConnected()
|
||||
{
|
||||
CSRWExclusiveLock connectionLock(&m_connectionLock);
|
||||
CSRWExclusiveLock queueLock(&m_queueLock);
|
||||
CSRWExclusiveLock connectionLock(m_connectionLock);
|
||||
CSRWExclusiveLock queueLock(m_queueLock);
|
||||
|
||||
uint64_t state = m_state.load(std::memory_order_relaxed);
|
||||
if (state & 1)
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "CPipeEndpoint.h"
|
||||
#include "CSRWLock.h"
|
||||
#include "InputPipeProtocol.h"
|
||||
#include "input/IInputSink.h"
|
||||
|
||||
@@ -55,8 +56,8 @@ private:
|
||||
// Odd states are available. Endpoint changes and resyncs advance the state.
|
||||
std::atomic<uint64_t> m_state { 0 };
|
||||
|
||||
SRWLOCK m_queueLock = SRWLOCK_INIT;
|
||||
SRWLOCK m_connectionLock = SRWLOCK_INIT;
|
||||
CSRWLock m_queueLock;
|
||||
CSRWLock m_connectionLock;
|
||||
HANDLE m_stopEvent = nullptr;
|
||||
HANDLE m_queueEvent = nullptr;
|
||||
HANDLE m_thread = nullptr;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "ipc/CPipeServer.h"
|
||||
#include "CDebug.h"
|
||||
#include "CSRWLock.h"
|
||||
#include "display/CDeviceContext.h"
|
||||
|
||||
CPipeServer g_pipe;
|
||||
@@ -40,7 +41,7 @@ void CPipeServer::DeInit()
|
||||
|
||||
void CPipeServer::OnPipeConnected()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_queueLock);
|
||||
CSRWExclusiveLock lock(m_queueLock);
|
||||
std::vector<LGPipeMsg> queued;
|
||||
queued.swap(m_queue);
|
||||
|
||||
@@ -51,7 +52,6 @@ void CPipeServer::OnPipeConnected()
|
||||
QueueMsgLocked(queued[i]);
|
||||
break;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_queueLock);
|
||||
}
|
||||
|
||||
bool CPipeServer::OnPipeMessage(const void * message, size_t size)
|
||||
@@ -89,27 +89,24 @@ void CPipeServer::QueueMsgLocked(const LGPipeMsg & msg)
|
||||
|
||||
void CPipeServer::WriteMsg(const LGPipeMsg & msg)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_queueLock);
|
||||
CSRWExclusiveLock lock(m_queueLock);
|
||||
if (!m_endpoint.Send(&msg, sizeof(msg)))
|
||||
QueueMsgLocked(msg);
|
||||
ReleaseSRWLockExclusive(&m_queueLock);
|
||||
}
|
||||
|
||||
void CPipeServer::HandleReloadSettings()
|
||||
{
|
||||
DEBUG_INFO("Reloading settings");
|
||||
|
||||
AcquireSRWLockShared(&m_deviceContextLock);
|
||||
CSRWSharedLock lock(m_deviceContextLock);
|
||||
if (m_deviceContext)
|
||||
m_deviceContext->ReloadSettings();
|
||||
ReleaseSRWLockShared(&m_deviceContextLock);
|
||||
}
|
||||
|
||||
void CPipeServer::SetDeviceContext(CDeviceContext * context)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_deviceContextLock);
|
||||
CSRWExclusiveLock lock(m_deviceContextLock);
|
||||
m_deviceContext = context;
|
||||
ReleaseSRWLockExclusive(&m_deviceContextLock);
|
||||
}
|
||||
|
||||
void CPipeServer::SetCursorPos(uint32_t x, uint32_t y)
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "CPipeEndpoint.h"
|
||||
#include "CSRWLock.h"
|
||||
#include "PipeMsg.h"
|
||||
|
||||
class CDeviceContext;
|
||||
@@ -34,10 +35,10 @@ class CPipeServer : private IPipeEndpointHandler
|
||||
{
|
||||
private:
|
||||
CPipeEndpoint m_endpoint;
|
||||
SRWLOCK m_queueLock = SRWLOCK_INIT;
|
||||
CSRWLock m_queueLock;
|
||||
std::vector<LGPipeMsg> m_queue;
|
||||
|
||||
SRWLOCK m_deviceContextLock = SRWLOCK_INIT;
|
||||
CSRWLock m_deviceContextLock;
|
||||
CDeviceContext * m_deviceContext = nullptr;
|
||||
|
||||
void WriteMsg(const LGPipeMsg & msg);
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "CRGB24Effect.h"
|
||||
|
||||
#include "CDebug.h"
|
||||
#include "CSRWLock.h"
|
||||
#include "config/CSettings.h"
|
||||
#include "capture/FramePipeline.h"
|
||||
|
||||
@@ -65,7 +66,7 @@ struct CRGB24Effect::State
|
||||
static const unsigned SampleCount = 64;
|
||||
static const unsigned TrimCount = SampleCount / 8;
|
||||
|
||||
SRWLOCK lock = SRWLOCK_INIT;
|
||||
CSRWLock lock;
|
||||
Phase phase = Phase::DISABLED;
|
||||
FormatKey format = {};
|
||||
bool formatValid = false;
|
||||
@@ -125,7 +126,7 @@ struct CRGB24Effect::State
|
||||
|
||||
void Update(const D12FrameFormat& next)
|
||||
{
|
||||
AcquireSRWLockExclusive(&lock);
|
||||
CSRWExclusiveLock guard(lock);
|
||||
|
||||
const bool formatChanged = !formatValid ||
|
||||
format.resourceDimension != next.desc.Dimension ||
|
||||
@@ -218,51 +219,46 @@ struct CRGB24Effect::State
|
||||
break;
|
||||
}
|
||||
|
||||
ReleaseSRWLockExclusive(&lock);
|
||||
}
|
||||
|
||||
bool WantsPacked()
|
||||
{
|
||||
AcquireSRWLockShared(&lock);
|
||||
CSRWSharedLock guard(lock);
|
||||
const bool result = WantsPackedLocked();
|
||||
ReleaseSRWLockShared(&lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool IsBenchmarking()
|
||||
{
|
||||
AcquireSRWLockShared(&lock);
|
||||
CSRWSharedLock guard(lock);
|
||||
const bool result = IsBenchmarkingLocked();
|
||||
ReleaseSRWLockShared(&lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t GetTimingToken(bool packed)
|
||||
{
|
||||
AcquireSRWLockShared(&lock);
|
||||
CSRWSharedLock guard(lock);
|
||||
|
||||
const uint64_t result = IsBenchmarkingLocked() &&
|
||||
packed == WantsPackedLocked() ? generation : 0;
|
||||
|
||||
ReleaseSRWLockShared(&lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Reject()
|
||||
{
|
||||
AcquireSRWLockExclusive(&lock);
|
||||
CSRWExclusiveLock guard(lock);
|
||||
if (WantsPackedLocked())
|
||||
{
|
||||
phase = Phase::LOCKED_NATIVE;
|
||||
++generation;
|
||||
ResetStageLocked();
|
||||
}
|
||||
ReleaseSRWLockExclusive(&lock);
|
||||
}
|
||||
|
||||
void RecordTiming(uint64_t token, bool fullCopy, uint64_t totalTime)
|
||||
{
|
||||
AcquireSRWLockExclusive(&lock);
|
||||
CSRWExclusiveLock guard(lock);
|
||||
|
||||
if (token == generation && fullCopy)
|
||||
switch (phase)
|
||||
@@ -282,7 +278,6 @@ struct CRGB24Effect::State
|
||||
break;
|
||||
}
|
||||
|
||||
ReleaseSRWLockExclusive(&lock);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -207,18 +207,18 @@ void CLGMPControl::SendCursor(const IDARG_OUT_QUERY_HWCURSOR& info,
|
||||
void CLGMPControl::SetColorTransform(
|
||||
std::shared_ptr<const D12ColorTransform> transform)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_colorTransformLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_colorTransformLock);
|
||||
m_colorTransform = std::move(transform);
|
||||
ReleaseSRWLockExclusive(&m_colorTransformLock);
|
||||
}
|
||||
SendColorTransform();
|
||||
}
|
||||
|
||||
std::shared_ptr<const D12ColorTransform>
|
||||
CLGMPControl::GetColorTransform() const
|
||||
{
|
||||
AcquireSRWLockShared(&m_colorTransformLock);
|
||||
CSRWSharedLock lock(m_colorTransformLock);
|
||||
std::shared_ptr<const D12ColorTransform> transform = m_colorTransform;
|
||||
ReleaseSRWLockShared(&m_colorTransformLock);
|
||||
return transform;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CSRWLock.h"
|
||||
|
||||
#include "transport/lgmp/CLGMPHost.h"
|
||||
#include "transport/IControlTransport.h"
|
||||
|
||||
@@ -55,7 +57,7 @@ private:
|
||||
int m_cursorX = 0;
|
||||
int m_cursorY = 0;
|
||||
|
||||
mutable SRWLOCK m_colorTransformLock = SRWLOCK_INIT;
|
||||
mutable CSRWLock m_colorTransformLock;
|
||||
std::shared_ptr<const D12ColorTransform> m_colorTransform;
|
||||
|
||||
void SendColorTransform();
|
||||
|
||||
@@ -216,7 +216,8 @@ void CLGMPFrameTransport::DeInit()
|
||||
{
|
||||
m_frameScheduler.Reset();
|
||||
|
||||
AcquireSRWLockExclusive(&m_framePublishLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(m_framePublishLock);
|
||||
m_submittedFrameIndex.store(-1, std::memory_order_release);
|
||||
m_readyFrameIndex.store(-1, std::memory_order_release);
|
||||
m_deferredOwnerFrameIndex = -1;
|
||||
@@ -228,7 +229,7 @@ void CLGMPFrameTransport::DeInit()
|
||||
delivery = {};
|
||||
for (OwnerDelivery& delivery : m_ownerDelivery)
|
||||
delivery = {};
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
}
|
||||
|
||||
for (int i = 0; i < LGMP_Q_FRAME_BUFFER_LEN; ++i)
|
||||
{
|
||||
@@ -444,7 +445,7 @@ void CLGMPFrameTransport::ProcessFrameDeliveries()
|
||||
if (!m_frameOwnerQueue[i])
|
||||
return;
|
||||
|
||||
AcquireSRWLockExclusive(&m_framePublishLock);
|
||||
CSRWExclusiveLock lock(m_framePublishLock);
|
||||
|
||||
bool released = false;
|
||||
for (unsigned i = 0; i < LGMP_Q_FRAME_BUFFER_LEN; ++i)
|
||||
@@ -482,7 +483,7 @@ void CLGMPFrameTransport::ProcessFrameDeliveries()
|
||||
owner = {};
|
||||
released = true;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
lock.Unlock();
|
||||
|
||||
if (released)
|
||||
m_frameScheduler.NotifyPublisher();
|
||||
@@ -632,7 +633,7 @@ bool CLGMPFrameTransport::FrameBufferAvailable(
|
||||
if (!m_frameOwnerQueue[i])
|
||||
return false;
|
||||
|
||||
AcquireSRWLockShared(&m_framePublishLock);
|
||||
CSRWSharedLock lock(m_framePublishLock);
|
||||
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
|
||||
@@ -647,15 +648,11 @@ bool CLGMPFrameTransport::FrameBufferAvailable(
|
||||
(ownerBlocked || ownerQueuesBlocked);
|
||||
}
|
||||
else if (lgmpHostQueuePending(m_frameQueue) != 0)
|
||||
{
|
||||
ReleaseSRWLockShared(&m_framePublishLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
@@ -679,16 +676,13 @@ bool CLGMPFrameTransport::GetPendingDeliveryTarget(uint64_t now,
|
||||
if (!m_frameQueue)
|
||||
return false;
|
||||
|
||||
AcquireSRWLockShared(&m_framePublishLock);
|
||||
CSRWSharedLock lock(m_framePublishLock);
|
||||
const LONG frameIndex =
|
||||
m_readyFrameIndex.load(std::memory_order_acquire);
|
||||
if (frameIndex < 0 ||
|
||||
m_frameInFlight[frameIndex].load(std::memory_order_acquire) ||
|
||||
lgmpHostQueuePending(m_frameQueue) != 0)
|
||||
{
|
||||
ReleaseSRWLockShared(&m_framePublishLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t blockedClientIDs[LGMP_Q_FRAME_LEN] = {};
|
||||
unsigned blockedCount = 0;
|
||||
@@ -699,7 +693,6 @@ bool CLGMPFrameTransport::GetPendingDeliveryTarget(uint64_t now,
|
||||
const bool result = m_frameScheduler.GetSecondaryTarget(
|
||||
m_frame[frameIndex]->frameSerial, now,
|
||||
blockedClientIDs, blockedCount, target);
|
||||
ReleaseSRWLockShared(&m_framePublishLock);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -709,20 +702,17 @@ bool CLGMPFrameTransport::RetryPendingDelivery(uint64_t now, bool& retry)
|
||||
if (!m_frameQueue)
|
||||
return false;
|
||||
|
||||
AcquireSRWLockExclusive(&m_framePublishLock);
|
||||
CSRWExclusiveLock lock(m_framePublishLock);
|
||||
const LONG frameIndex =
|
||||
m_readyFrameIndex.load(std::memory_order_acquire);
|
||||
if (frameIndex < 0 ||
|
||||
m_frameInFlight[frameIndex].load(std::memory_order_acquire) ||
|
||||
lgmpHostQueuePending(m_frameQueue) != 0)
|
||||
{
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
const SharedFramePostResult result = PostSharedFrame(
|
||||
static_cast<unsigned>(frameIndex), 0, now);
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
lock.Unlock();
|
||||
retry = result == SHARED_FRAME_FAILED;
|
||||
return result == SHARED_FRAME_POSTED;
|
||||
}
|
||||
@@ -746,7 +736,7 @@ PreparedFrameBuffer CLGMPFrameTransport::PrepareFrameBuffer(
|
||||
return result;
|
||||
}
|
||||
|
||||
AcquireSRWLockExclusive(&m_framePublishLock);
|
||||
CSRWExclusiveLock lock(m_framePublishLock);
|
||||
const bool ownerBlocked = schedule.clientID &&
|
||||
CountOwnerDeliveries(schedule.clientID) >= LGMP_Q_FRAME_LEN;
|
||||
const bool allowReady = allowReadyReplacement &&
|
||||
@@ -774,7 +764,7 @@ PreparedFrameBuffer CLGMPFrameTransport::PrepareFrameBuffer(
|
||||
(!m_frameLastPublishSequence[availableFrameIndex] ||
|
||||
m_framePublishSequence >
|
||||
m_frameLastPublishSequence[availableFrameIndex] + 1);
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
lock.Unlock();
|
||||
if (!acquired)
|
||||
return result;
|
||||
const unsigned frameIndex = static_cast<unsigned>(availableFrameIndex);
|
||||
@@ -939,16 +929,13 @@ bool CLGMPFrameTransport::PublishFrameBuffer(unsigned frameIndex,
|
||||
return false;
|
||||
|
||||
const uint64_t now = CFrameScheduler::Nanotime();
|
||||
AcquireSRWLockExclusive(&m_framePublishLock);
|
||||
CSRWExclusiveLock lock(m_framePublishLock);
|
||||
CFrameScheduler::Schedule currentSchedule = {};
|
||||
const bool scheduling =
|
||||
m_frameScheduler.GetSchedule(currentSchedule);
|
||||
if (scheduling != (schedule.clientID != 0) ||
|
||||
(scheduling && !FrameScheduleMatches(schedule, currentSchedule)))
|
||||
{
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
KVMFRFrame * frame = m_frame[frameIndex];
|
||||
frame->timingFlags = 0;
|
||||
@@ -1023,7 +1010,7 @@ bool CLGMPFrameTransport::PublishFrameBuffer(unsigned frameIndex,
|
||||
m_submittedFrameIndex.store(
|
||||
static_cast<LONG>(frameIndex), std::memory_order_release);
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
lock.Unlock();
|
||||
|
||||
if (!published)
|
||||
{
|
||||
@@ -1042,14 +1029,11 @@ bool CLGMPFrameTransport::RepublishFrameBuffer(
|
||||
if (!schedule.clientID)
|
||||
return false;
|
||||
|
||||
AcquireSRWLockExclusive(&m_framePublishLock);
|
||||
CSRWExclusiveLock lock(m_framePublishLock);
|
||||
CFrameScheduler::Schedule currentSchedule = {};
|
||||
if (!m_frameScheduler.GetSchedule(currentSchedule) ||
|
||||
!FrameScheduleMatches(schedule, currentSchedule))
|
||||
{
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
LONG frameIndex = m_deferredOwnerFrameIndex;
|
||||
if (frameIndex >= 0 &&
|
||||
@@ -1063,10 +1047,7 @@ bool CLGMPFrameTransport::RepublishFrameBuffer(
|
||||
frameIndex = m_readyFrameIndex.load(std::memory_order_acquire);
|
||||
if (frameIndex < 0 ||
|
||||
m_frameInFlight[frameIndex].load(std::memory_order_acquire))
|
||||
{
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
CFrameScheduler::Schedule deliverySchedule = schedule;
|
||||
deliverySchedule.deliveryDeadlineSerial = 0;
|
||||
@@ -1078,16 +1059,13 @@ bool CLGMPFrameTransport::RepublishFrameBuffer(
|
||||
{
|
||||
if (m_deferredOwnerFrameIndex == frameIndex)
|
||||
m_deferredOwnerFrameIndex = -1;
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
lock.Unlock();
|
||||
m_frameScheduler.FrameRepublished(schedule, frameSerial);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (CountOwnerDeliveries(schedule.clientID) >= LGMP_Q_FRAME_LEN)
|
||||
{
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
return false;
|
||||
}
|
||||
|
||||
const int ownerQueueIndex =
|
||||
FindAvailableOwnerQueue(static_cast<unsigned>(frameIndex));
|
||||
@@ -1097,7 +1075,7 @@ bool CLGMPFrameTransport::RepublishFrameBuffer(
|
||||
static_cast<unsigned>(frameIndex), deliverySchedule);
|
||||
if (published && m_deferredOwnerFrameIndex == frameIndex)
|
||||
m_deferredOwnerFrameIndex = -1;
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
lock.Unlock();
|
||||
if (published)
|
||||
m_frameScheduler.FrameRepublished(schedule, frameSerial);
|
||||
return published;
|
||||
@@ -1123,7 +1101,7 @@ bool CLGMPFrameTransport::RepublishFrameBuffer(
|
||||
if (m_deferredOwnerFrameIndex == frameIndex)
|
||||
m_deferredOwnerFrameIndex = -1;
|
||||
}
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
lock.Unlock();
|
||||
|
||||
if (status != LGMP_OK || !recipientCount)
|
||||
{
|
||||
@@ -1201,7 +1179,7 @@ void CLGMPFrameTransport::AbortFrameBuffer(unsigned frameIndex)
|
||||
if (frameIndex >= LGMP_Q_FRAME_BUFFER_LEN)
|
||||
return;
|
||||
|
||||
AcquireSRWLockExclusive(&m_framePublishLock);
|
||||
CSRWExclusiveLock lock(m_framePublishLock);
|
||||
m_frameBuffer[frameIndex]->wp = 0;
|
||||
InterlockedExchange(
|
||||
(volatile LONG *)&m_frame[frameIndex]->timingValid, 0);
|
||||
@@ -1209,7 +1187,6 @@ void CLGMPFrameTransport::AbortFrameBuffer(unsigned frameIndex)
|
||||
if (m_deferredOwnerFrameIndex == static_cast<LONG>(frameIndex))
|
||||
m_deferredOwnerFrameIndex = -1;
|
||||
m_frameInFlight[frameIndex].store(false, std::memory_order_release);
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
}
|
||||
|
||||
void CLGMPFrameTransport::FailFrameBuffer(unsigned frameIndex)
|
||||
@@ -1229,7 +1206,7 @@ void CLGMPFrameTransport::CompleteFrameBuffer(
|
||||
if (frameIndex >= LGMP_Q_FRAME_BUFFER_LEN)
|
||||
return;
|
||||
|
||||
AcquireSRWLockExclusive(&m_framePublishLock);
|
||||
CSRWExclusiveLock lock(m_framePublishLock);
|
||||
m_frameCompleted[frameIndex] = succeeded;
|
||||
if (!succeeded &&
|
||||
m_deferredOwnerFrameIndex == static_cast<LONG>(frameIndex))
|
||||
@@ -1248,7 +1225,6 @@ void CLGMPFrameTransport::CompleteFrameBuffer(
|
||||
static_cast<LONG>(frameIndex), std::memory_order_release);
|
||||
}
|
||||
m_frameInFlight[frameIndex].store(false, std::memory_order_release);
|
||||
ReleaseSRWLockExclusive(&m_framePublishLock);
|
||||
}
|
||||
|
||||
void CLGMPFrameTransport::SetFrameTiming(unsigned frameIndex,
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CSRWLock.h"
|
||||
|
||||
#include <Windows.h>
|
||||
#include <atomic>
|
||||
#include <stdint.h>
|
||||
@@ -97,7 +99,7 @@ private:
|
||||
LONG m_deferredOwnerFrameIndex = -1;
|
||||
std::atomic<bool> m_frameInFlight[LGMP_Q_FRAME_BUFFER_LEN] = {};
|
||||
bool m_frameCompleted[LGMP_Q_FRAME_BUFFER_LEN] = {};
|
||||
SRWLOCK m_framePublishLock = SRWLOCK_INIT;
|
||||
CSRWLock m_framePublishLock;
|
||||
uint64_t m_framePublishSequence = 0;
|
||||
uint64_t m_frameLastPublishSequence[LGMP_Q_FRAME_BUFFER_LEN] = {};
|
||||
|
||||
|
||||
@@ -137,9 +137,8 @@ void CLGMPHost::DeInit()
|
||||
|
||||
LGMP_STATUS CLGMPHost::Process()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_processLock);
|
||||
CSRWExclusiveLock lock(m_processLock);
|
||||
const LGMP_STATUS status = lgmpHostProcess(m_host);
|
||||
ReleaseSRWLockExclusive(&m_processLock);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CSRWLock.h"
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
#include <stddef.h>
|
||||
@@ -35,7 +37,7 @@ class CLGMPHost
|
||||
{
|
||||
private:
|
||||
PLGMPHost m_host = nullptr;
|
||||
SRWLOCK m_processLock = SRWLOCK_INIT;
|
||||
CSRWLock m_processLock;
|
||||
|
||||
public:
|
||||
CLGMPHost() = default;
|
||||
|
||||
@@ -179,7 +179,7 @@ void CLGMPInputTransport::PublishStatus()
|
||||
|
||||
bool CLGMPInputTransport::Start(IInputSink& sink)
|
||||
{
|
||||
CSRWExclusiveLock lock(&m_lifecycleLock);
|
||||
CSRWExclusiveLock lock(m_lifecycleLock);
|
||||
if (m_thread)
|
||||
{
|
||||
const DWORD state = WaitForSingleObject(m_thread, 0);
|
||||
@@ -249,7 +249,7 @@ bool CLGMPInputTransport::Start(IInputSink& sink)
|
||||
|
||||
void CLGMPInputTransport::Stop()
|
||||
{
|
||||
CSRWExclusiveLock lock(&m_lifecycleLock);
|
||||
CSRWExclusiveLock lock(m_lifecycleLock);
|
||||
|
||||
if (m_stopEvent)
|
||||
SetEvent(m_stopEvent);
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CSRWLock.h"
|
||||
#include "transport/IInputTransport.h"
|
||||
#include "common/LGMPConfig.h"
|
||||
|
||||
@@ -64,7 +65,7 @@ private:
|
||||
PLGMPMemory m_statusMemory[LGMP_Q_INPUT_LEN] = {};
|
||||
IInputSink * m_sink = nullptr;
|
||||
|
||||
SRWLOCK m_lifecycleLock = SRWLOCK_INIT;
|
||||
CSRWLock m_lifecycleLock;
|
||||
HANDLE m_stopEvent = nullptr;
|
||||
HANDLE m_pollTimer = nullptr;
|
||||
HANDLE m_thread = nullptr;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "CPipeClient.h"
|
||||
#include "CDebug.h"
|
||||
#include "CSRWLock.h"
|
||||
#include "CNotifyWindow.h"
|
||||
|
||||
#include <setupapi.h>
|
||||
@@ -323,10 +324,8 @@ bool CPipeClient::EnsureOnlyDisplayLocked()
|
||||
|
||||
bool CPipeClient::EnsureOnlyDisplay()
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_displayLock);
|
||||
const bool result = EnsureOnlyDisplayLocked();
|
||||
ReleaseSRWLockExclusive(&m_displayLock);
|
||||
return result;
|
||||
CSRWExclusiveLock lock(m_displayLock);
|
||||
return EnsureOnlyDisplayLocked();
|
||||
}
|
||||
|
||||
bool CPipeClient::OnPipeMessage(const void * message, size_t size)
|
||||
@@ -370,13 +369,14 @@ void CPipeClient::HandleSetCursorPos(const LGPipeMsg& msg)
|
||||
|
||||
void CPipeClient::HandleSetDisplayMode(const LGPipeMsg& msg)
|
||||
{
|
||||
AcquireSRWLockExclusive(&m_displayLock);
|
||||
LONG result;
|
||||
{
|
||||
CSRWExclusiveLock lock(m_displayLock);
|
||||
|
||||
std::vector<DisplayState> displays;
|
||||
size_t lgIndex;
|
||||
if (!GetDisplayStates(displays, lgIndex))
|
||||
{
|
||||
ReleaseSRWLockExclusive(&m_displayLock);
|
||||
DEBUG_ERROR("Looking Glass display not found while setting its mode");
|
||||
return;
|
||||
}
|
||||
@@ -389,12 +389,11 @@ void CPipeClient::HandleSetDisplayMode(const LGPipeMsg& msg)
|
||||
dm.dmFields =
|
||||
DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFREQUENCY;
|
||||
|
||||
LONG result = ChangeDisplaySettingsEx(displays[lgIndex].device.DeviceName,
|
||||
result = ChangeDisplaySettingsEx(displays[lgIndex].device.DeviceName,
|
||||
&dm, NULL, CDS_UPDATEREGISTRY, NULL);
|
||||
if (result != DISP_CHANGE_SUCCESSFUL)
|
||||
DEBUG_ERROR("ChangeDisplaySettingsEx Failed (0x%08x)", result);
|
||||
|
||||
ReleaseSRWLockExclusive(&m_displayLock);
|
||||
}
|
||||
|
||||
if (result == DISP_CHANGE_SUCCESSFUL)
|
||||
EnsureOnlyDisplay();
|
||||
|
||||
@@ -24,13 +24,14 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "CPipeEndpoint.h"
|
||||
#include "CSRWLock.h"
|
||||
#include "PipeMsg.h"
|
||||
|
||||
class CPipeClient : private IPipeEndpointHandler
|
||||
{
|
||||
private:
|
||||
CPipeEndpoint m_endpoint;
|
||||
SRWLOCK m_displayLock = SRWLOCK_INIT;
|
||||
CSRWLock m_displayLock;
|
||||
|
||||
void WriteMsg(const LGPipeMsg& msg);
|
||||
|
||||
|
||||
@@ -64,8 +64,8 @@ struct HIDDeviceContext
|
||||
HID_DEVICE_ATTRIBUTES attributes;
|
||||
HID_DESCRIPTOR descriptor;
|
||||
UCHAR keyboardLeds;
|
||||
SRWLOCK lifecycleLock;
|
||||
SRWLOCK reportLock;
|
||||
CSRWLock lifecycleLock;
|
||||
CSRWLock reportLock;
|
||||
bool active;
|
||||
bool stopping;
|
||||
UCHAR mouseMode;
|
||||
@@ -83,7 +83,7 @@ struct HIDDeviceContext
|
||||
|
||||
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(HIDDeviceContext, HIDGetDeviceContext);
|
||||
|
||||
static SRWLOCK s_deviceLock = SRWLOCK_INIT;
|
||||
static CSRWLock s_deviceLock;
|
||||
static HIDDeviceContext * s_device = nullptr;
|
||||
|
||||
EVT_WDF_IO_QUEUE_IO_DEVICE_CONTROL HIDEvtIoDeviceControl;
|
||||
@@ -312,7 +312,7 @@ static NTSTATUS ReadReport(
|
||||
|
||||
NTSTATUS status;
|
||||
{
|
||||
CSRWExclusiveLock lock(&context->reportLock);
|
||||
CSRWExclusiveLock lock(context->reportLock);
|
||||
if (context->stopping || !context->active)
|
||||
status = STATUS_DEVICE_NOT_READY;
|
||||
else if (context->reportCount)
|
||||
@@ -335,8 +335,8 @@ static NTSTATUS ReadReport(
|
||||
|
||||
static NTSTATUS ActivateDevice(_Inout_ HIDDeviceContext * context)
|
||||
{
|
||||
CSRWExclusiveLock lifecycleLock(&context->lifecycleLock);
|
||||
CSRWExclusiveLock lock(&context->reportLock);
|
||||
CSRWExclusiveLock lifecycleLock(context->lifecycleLock);
|
||||
CSRWExclusiveLock lock(context->reportLock);
|
||||
if (context->stopping)
|
||||
return STATUS_DEVICE_NOT_READY;
|
||||
|
||||
@@ -347,9 +347,9 @@ static NTSTATUS ActivateDevice(_Inout_ HIDDeviceContext * context)
|
||||
|
||||
static NTSTATUS DeactivateDevice(_Inout_ HIDDeviceContext * context)
|
||||
{
|
||||
CSRWExclusiveLock lifecycleLock(&context->lifecycleLock);
|
||||
CSRWExclusiveLock lifecycleLock(context->lifecycleLock);
|
||||
{
|
||||
CSRWExclusiveLock lock(&context->reportLock);
|
||||
CSRWExclusiveLock lock(context->reportLock);
|
||||
if (context->stopping)
|
||||
return STATUS_DEVICE_NOT_READY;
|
||||
|
||||
@@ -412,9 +412,7 @@ NTSTATUS CHIDDevice::Create(_Inout_ PWDFDEVICE_INIT deviceInit)
|
||||
return status;
|
||||
|
||||
HIDDeviceContext * context = HIDGetDeviceContext(device);
|
||||
RtlZeroMemory(context, sizeof(*context));
|
||||
InitializeSRWLock(&context->lifecycleLock);
|
||||
InitializeSRWLock(&context->reportLock);
|
||||
new (context) HIDDeviceContext {};
|
||||
context->active = true;
|
||||
context->inputPipe = new (std::nothrow) CInputPipeClient;
|
||||
if (!context->inputPipe)
|
||||
@@ -442,7 +440,7 @@ NTSTATUS CHIDDevice::Create(_Inout_ PWDFDEVICE_INIT deviceInit)
|
||||
return status;
|
||||
|
||||
{
|
||||
CSRWExclusiveLock lock(&s_deviceLock);
|
||||
CSRWExclusiveLock lock(s_deviceLock);
|
||||
if (s_device)
|
||||
{
|
||||
DEBUG_ERROR("Only one LGInput device instance is supported");
|
||||
@@ -464,7 +462,7 @@ NTSTATUS CHIDDevice::SubmitReport(
|
||||
if (HIDGetInputReportSize(reportId) != size)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
CSRWSharedLock deviceLock(&s_deviceLock);
|
||||
CSRWSharedLock deviceLock(s_deviceLock);
|
||||
HIDDeviceContext * context = s_device;
|
||||
if (!context)
|
||||
return STATUS_DEVICE_NOT_READY;
|
||||
@@ -472,7 +470,7 @@ NTSTATUS CHIDDevice::SubmitReport(
|
||||
WDFREQUEST request = nullptr;
|
||||
NTSTATUS status;
|
||||
{
|
||||
CSRWExclusiveLock reportLock(&context->reportLock);
|
||||
CSRWExclusiveLock reportLock(context->reportLock);
|
||||
if (context->stopping || !context->active)
|
||||
status = STATUS_DEVICE_NOT_READY;
|
||||
else
|
||||
@@ -574,12 +572,12 @@ NTSTATUS CHIDDevice::ResetReports()
|
||||
uint16_t absoluteX = 0;
|
||||
uint16_t absoluteY = 0;
|
||||
{
|
||||
CSRWSharedLock deviceLock(&s_deviceLock);
|
||||
CSRWSharedLock deviceLock(s_deviceLock);
|
||||
HIDDeviceContext * context = s_device;
|
||||
if (!context)
|
||||
return STATUS_DEVICE_NOT_READY;
|
||||
|
||||
CSRWExclusiveLock reportLock(&context->reportLock);
|
||||
CSRWExclusiveLock reportLock(context->reportLock);
|
||||
if (context->stopping)
|
||||
return STATUS_DEVICE_NOT_READY;
|
||||
|
||||
@@ -655,12 +653,12 @@ void CHIDDevice::LogStatistics()
|
||||
{
|
||||
HIDStatistics statistics = {};
|
||||
{
|
||||
CSRWSharedLock deviceLock(&s_deviceLock);
|
||||
CSRWSharedLock deviceLock(s_deviceLock);
|
||||
HIDDeviceContext * context = s_device;
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
CSRWExclusiveLock reportLock(&context->reportLock);
|
||||
CSRWExclusiveLock reportLock(context->reportLock);
|
||||
statistics = context->statistics;
|
||||
context->statistics = {};
|
||||
context->statistics.queueHighWater = context->reportCount;
|
||||
@@ -752,12 +750,12 @@ VOID HIDEvtReportQueueCleanup(_In_ WDFOBJECT object)
|
||||
HIDDeviceContext * context =
|
||||
HIDGetDeviceContext(WdfIoQueueGetDevice((WDFQUEUE)object));
|
||||
|
||||
CSRWExclusiveLock deviceLock(&s_deviceLock);
|
||||
CSRWExclusiveLock deviceLock(s_deviceLock);
|
||||
if (s_device == context)
|
||||
s_device = nullptr;
|
||||
|
||||
{
|
||||
CSRWExclusiveLock reportLock(&context->reportLock);
|
||||
CSRWExclusiveLock reportLock(context->reportLock);
|
||||
context->stopping = true;
|
||||
context->reportHead = 0;
|
||||
context->reportCount = 0;
|
||||
@@ -774,7 +772,7 @@ VOID HIDEvtDeviceCleanup(_In_ WDFOBJECT object)
|
||||
context->inputPipe = nullptr;
|
||||
}
|
||||
|
||||
CSRWExclusiveLock deviceLock(&s_deviceLock);
|
||||
CSRWExclusiveLock deviceLock(s_deviceLock);
|
||||
if (s_device == context)
|
||||
s_device = nullptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user