mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-07-21 14:52:04 +00:00
[idd] remove debounce logic now the lifecycle is properly protected
This commit is contained in:
@@ -650,61 +650,9 @@ void CIndirectDeviceContext::SetResolution(int width, int height)
|
|||||||
mode.refresh = g_settings.GetDefaultRefresh();
|
mode.refresh = g_settings.GetDefaultRefresh();
|
||||||
mode.preferred = true;
|
mode.preferred = true;
|
||||||
|
|
||||||
// A window resize streams many WINDOWSIZE requests in quick succession.
|
|
||||||
// Record the latest request and (re)start a timer; the actual mode change and
|
|
||||||
// replug only happen once the requested resolution has settled (i.e. no new
|
|
||||||
// request has arrived) for m_resChangeDelayMs. Each new request restarts the
|
|
||||||
// countdown, coalescing a burst of resizes into a single replug.
|
|
||||||
AcquireSRWLockExclusive(&m_stateLock);
|
AcquireSRWLockExclusive(&m_stateLock);
|
||||||
m_pendingMode = mode;
|
m_setMode = mode;
|
||||||
m_resChangePending = true;
|
m_doSetMode = true;
|
||||||
ReleaseSRWLockExclusive(&m_stateLock);
|
|
||||||
|
|
||||||
// Create the debounce timer once; WdfTimerStart on an already-queued
|
|
||||||
// non-periodic timer simply updates its due time, giving us the restart.
|
|
||||||
if (!m_resChangeTimer)
|
|
||||||
{
|
|
||||||
WDF_TIMER_CONFIG config;
|
|
||||||
WDF_TIMER_CONFIG_INIT(&config,
|
|
||||||
[](WDFTIMER timer) -> void
|
|
||||||
{
|
|
||||||
WDFOBJECT parent = WdfTimerGetParentObject(timer);
|
|
||||||
auto wrapper = WdfObjectGet_CIndirectDeviceContextWrapper(parent);
|
|
||||||
wrapper->context->ApplyResolution();
|
|
||||||
});
|
|
||||||
config.AutomaticSerialization = FALSE;
|
|
||||||
|
|
||||||
WDF_OBJECT_ATTRIBUTES attribs;
|
|
||||||
WDF_OBJECT_ATTRIBUTES_INIT(&attribs);
|
|
||||||
attribs.ParentObject = m_wdfDevice;
|
|
||||||
attribs.ExecutionLevel = WdfExecutionLevelDispatch;
|
|
||||||
|
|
||||||
NTSTATUS status = WdfTimerCreate(&config, &attribs, &m_resChangeTimer);
|
|
||||||
if (!NT_SUCCESS(status))
|
|
||||||
{
|
|
||||||
DEBUG_ERROR_HR(status, "Resolution change timer creation failed");
|
|
||||||
m_resChangeTimer = nullptr;
|
|
||||||
// Fall back to applying immediately so a resize is not lost.
|
|
||||||
ApplyResolution();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WdfTimerStart(m_resChangeTimer, WDF_REL_TIMEOUT_IN_MS(m_resChangeDelayMs));
|
|
||||||
}
|
|
||||||
|
|
||||||
void CIndirectDeviceContext::ApplyResolution()
|
|
||||||
{
|
|
||||||
AcquireSRWLockExclusive(&m_stateLock);
|
|
||||||
if (!m_resChangePending)
|
|
||||||
{
|
|
||||||
ReleaseSRWLockExclusive(&m_stateLock);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CSettings::DisplayMode mode = m_pendingMode;
|
|
||||||
m_resChangePending = false;
|
|
||||||
m_setMode = mode;
|
|
||||||
m_doSetMode = true;
|
|
||||||
ReleaseSRWLockExclusive(&m_stateLock);
|
ReleaseSRWLockExclusive(&m_stateLock);
|
||||||
|
|
||||||
g_settings.SetExtraMode(mode);
|
g_settings.SetExtraMode(mode);
|
||||||
@@ -907,14 +855,6 @@ void CIndirectDeviceContext::DeInitLGMP()
|
|||||||
m_initTimer = nullptr;
|
m_initTimer = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The resolution debounce timer callback dereferences this context too; stop
|
|
||||||
// and drain it before tearing anything down.
|
|
||||||
if (m_resChangeTimer)
|
|
||||||
{
|
|
||||||
WdfTimerStop(m_resChangeTimer, TRUE);
|
|
||||||
m_resChangeTimer = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_lgmp == nullptr)
|
if (m_lgmp == nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -159,15 +159,6 @@ private:
|
|||||||
CSettings::DisplayMode m_setMode = {};
|
CSettings::DisplayMode m_setMode = {};
|
||||||
bool m_doSetMode = false;
|
bool m_doSetMode = false;
|
||||||
|
|
||||||
// Debounce for resolution changes. A window resize streams many WINDOWSIZE
|
|
||||||
// requests in quick succession; rather than replug the monitor for each, we
|
|
||||||
// (re)start a timer and only apply the last requested resolution once it has
|
|
||||||
// remained unchanged for m_resChangeDelayMs. Guarded by m_stateLock.
|
|
||||||
static const ULONG m_resChangeDelayMs = 1000;
|
|
||||||
WDFTIMER m_resChangeTimer = nullptr;
|
|
||||||
CSettings::DisplayMode m_pendingMode = {};
|
|
||||||
bool m_resChangePending = false;
|
|
||||||
|
|
||||||
// Set by ReplugMonitor after a departure to rebuild the monitor from the LGMP
|
// Set by ReplugMonitor after a departure to rebuild the monitor from the LGMP
|
||||||
// timer, off the IddCx callback thread.
|
// timer, off the IddCx callback thread.
|
||||||
volatile LONG m_finishInitQueued = 0;
|
volatile LONG m_finishInitQueued = 0;
|
||||||
@@ -206,7 +197,6 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void SetResolution(int width, int height);
|
void SetResolution(int width, int height);
|
||||||
void ApplyResolution();
|
|
||||||
|
|
||||||
size_t GetAlignSize () const { return m_alignSize ; }
|
size_t GetAlignSize () const { return m_alignSize ; }
|
||||||
size_t GetMaxFrameSize() const { return m_maxFrameSize ; }
|
size_t GetMaxFrameSize() const { return m_maxFrameSize ; }
|
||||||
|
|||||||
Reference in New Issue
Block a user