mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-04 06:12:04 +00:00
[client/idd] preserve frame timing across reconnects
This commit is contained in:
@@ -47,7 +47,6 @@ static struct
|
|||||||
_Atomic(uint32_t) generation;
|
_Atomic(uint32_t) generation;
|
||||||
_Atomic(uint64_t) period;
|
_Atomic(uint64_t) period;
|
||||||
uint64_t lastSend;
|
uint64_t lastSend;
|
||||||
uint64_t lastCadence;
|
|
||||||
|
|
||||||
int64_t phaseError;
|
int64_t phaseError;
|
||||||
uint32_t feedbackFrameSerial;
|
uint32_t feedbackFrameSerial;
|
||||||
@@ -177,15 +176,10 @@ void frameScheduler_start(LG_TransportFeatureFlags features)
|
|||||||
features & LG_TRANSPORT_FEATURE_FRAME_SCHEDULE;
|
features & LG_TRANSPORT_FEATURE_FRAME_SCHEDULE;
|
||||||
l_frameScheduler.active = false;
|
l_frameScheduler.active = false;
|
||||||
l_frameScheduler.controlPending = false;
|
l_frameScheduler.controlPending = false;
|
||||||
l_frameScheduler.period = 0;
|
|
||||||
l_frameScheduler.lastSend = 0;
|
l_frameScheduler.lastSend = 0;
|
||||||
l_frameScheduler.lastCadence = 0;
|
|
||||||
++l_frameScheduler.generation;
|
++l_frameScheduler.generation;
|
||||||
|
|
||||||
LG_LOCK(l_frameScheduler.lock);
|
LG_LOCK(l_frameScheduler.lock);
|
||||||
l_frameScheduler.renderSampleIndex = 0;
|
|
||||||
l_frameScheduler.renderSampleCount = 0;
|
|
||||||
l_frameScheduler.lastRender = 0;
|
|
||||||
l_frameScheduler.phaseError = 0;
|
l_frameScheduler.phaseError = 0;
|
||||||
l_frameScheduler.feedbackFrameSerial = 0;
|
l_frameScheduler.feedbackFrameSerial = 0;
|
||||||
l_frameScheduler.feedbackSamples = 0;
|
l_frameScheduler.feedbackSamples = 0;
|
||||||
@@ -208,30 +202,17 @@ void frameScheduler_update(void)
|
|||||||
if (!l_frameScheduler.supported)
|
if (!l_frameScheduler.supported)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const uint64_t now = nanotime();
|
const uint64_t now = nanotime();
|
||||||
const uint64_t period = presentationPeriod();
|
uint64_t period = presentationPeriod();
|
||||||
if (period < FRAME_SCHEDULER_MIN_PERIOD_NS ||
|
if (period < FRAME_SCHEDULER_MIN_PERIOD_NS ||
|
||||||
period > FRAME_SCHEDULER_MAX_PERIOD_NS)
|
period > FRAME_SCHEDULER_MAX_PERIOD_NS)
|
||||||
{
|
{
|
||||||
if (l_frameScheduler.active && l_frameScheduler.lastCadence &&
|
period = l_frameScheduler.period;
|
||||||
now - l_frameScheduler.lastCadence > FRAME_SCHEDULER_RENEW_NS * 2)
|
if (period < FRAME_SCHEDULER_MIN_PERIOD_NS ||
|
||||||
{
|
period > FRAME_SCHEDULER_MAX_PERIOD_NS)
|
||||||
if (sendSchedule(LG_TRANSPORT_FRAME_SCHEDULE_RELEASE, 0))
|
return;
|
||||||
{
|
|
||||||
l_frameScheduler.active = false;
|
|
||||||
l_frameScheduler.period = 0;
|
|
||||||
LG_LOCK(l_frameScheduler.lock);
|
|
||||||
l_frameScheduler.phaseError = 0;
|
|
||||||
l_frameScheduler.feedbackFrameSerial = 0;
|
|
||||||
l_frameScheduler.feedbackSamples = 0;
|
|
||||||
l_frameScheduler.feedbackDirty = false;
|
|
||||||
LG_UNLOCK(l_frameScheduler.lock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
l_frameScheduler.lastCadence = now;
|
|
||||||
bool reset = !l_frameScheduler.period;
|
bool reset = !l_frameScheduler.period;
|
||||||
if (!reset)
|
if (!reset)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -104,8 +104,8 @@ void CFrameScheduler::ElectOwner(uint64_t now)
|
|||||||
m_scheduling = true;
|
m_scheduling = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldClientID != m_schedule.clientID ||
|
const bool ownerChanged = oldClientID != m_schedule.clientID;
|
||||||
oldGeneration != m_schedule.generation)
|
if (ownerChanged || oldGeneration != m_schedule.generation)
|
||||||
{
|
{
|
||||||
m_nextDeadline = m_scheduling ? now + m_schedule.period : 0;
|
m_nextDeadline = m_scheduling ? now + m_schedule.period : 0;
|
||||||
m_forceNext = m_scheduling;
|
m_forceNext = m_scheduling;
|
||||||
@@ -117,11 +117,11 @@ void CFrameScheduler::ElectOwner(uint64_t now)
|
|||||||
m_lastLogSkipped = m_skippedFrames;
|
m_lastLogSkipped = m_skippedFrames;
|
||||||
m_lastLogPublished = m_publishedFrames;
|
m_lastLogPublished = m_publishedFrames;
|
||||||
|
|
||||||
if (m_scheduling)
|
if (ownerChanged && m_scheduling)
|
||||||
DEBUG_INFO("Frame timing owner %u generation %u at %.3f Hz",
|
DEBUG_INFO("Frame timing owner %u generation %u at %.3f Hz",
|
||||||
m_schedule.clientID, m_schedule.generation,
|
m_schedule.clientID, m_schedule.generation,
|
||||||
1000000000.0 / m_schedule.period);
|
1000000000.0 / m_schedule.period);
|
||||||
else if (oldClientID)
|
else if (ownerChanged && oldClientID)
|
||||||
DEBUG_INFO("Frame timing owner released; using push delivery");
|
DEBUG_INFO("Frame timing owner released; using push delivery");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -202,21 +202,25 @@ bool CFrameScheduler::UpdateSchedule(const KVMFRFrameSchedule& schedule,
|
|||||||
|
|
||||||
AcquireSRWLockExclusive(&m_lock);
|
AcquireSRWLockExclusive(&m_lock);
|
||||||
Client * client = FindClient(schedule.clientID);
|
Client * client = FindClient(schedule.clientID);
|
||||||
|
|
||||||
|
if (schedule.flags & KVMFR_FRAME_SCHEDULE_RELEASE)
|
||||||
|
{
|
||||||
|
if (client && client->subscribed)
|
||||||
|
{
|
||||||
|
client->active = false;
|
||||||
|
client->expiry = 0;
|
||||||
|
ElectOwner(now);
|
||||||
|
}
|
||||||
|
ReleaseSRWLockExclusive(&m_lock);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!client || !client->subscribed)
|
if (!client || !client->subscribed)
|
||||||
{
|
{
|
||||||
ReleaseSRWLockExclusive(&m_lock);
|
ReleaseSRWLockExclusive(&m_lock);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schedule.flags & KVMFR_FRAME_SCHEDULE_RELEASE)
|
|
||||||
{
|
|
||||||
client->active = false;
|
|
||||||
client->expiry = 0;
|
|
||||||
ElectOwner(now);
|
|
||||||
ReleaseSRWLockExclusive(&m_lock);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(schedule.flags & KVMFR_FRAME_SCHEDULE_ACTIVE) ||
|
if (!(schedule.flags & KVMFR_FRAME_SCHEDULE_ACTIVE) ||
|
||||||
schedule.period < MIN_PERIOD_NS ||
|
schedule.period < MIN_PERIOD_NS ||
|
||||||
schedule.period > MAX_PERIOD_NS ||
|
schedule.period > MAX_PERIOD_NS ||
|
||||||
|
|||||||
Reference in New Issue
Block a user