mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-09 08:41:31 +00:00
[client] scheduler: release ownership without live cadence
Renew the frame-schedule lease only while the display server is producing real cadence callbacks. Release ownership after the cadence stalls, and reacquire with an immediate reset when it resumes. For non-JIT rendering, treat only a successful presentation as live cadence.
This commit is contained in:
@@ -47,7 +47,7 @@ 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;
|
_Atomic(uint64_t) lastCadence;
|
||||||
|
|
||||||
int64_t phaseError;
|
int64_t phaseError;
|
||||||
uint32_t feedbackFrameSerial;
|
uint32_t feedbackFrameSerial;
|
||||||
@@ -181,19 +181,24 @@ void frameScheduler_stop(void)
|
|||||||
l_frameScheduler.immediatePending = false;
|
l_frameScheduler.immediatePending = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void frameScheduler_observeCadence(void)
|
||||||
|
{
|
||||||
|
atomic_store_explicit(
|
||||||
|
&l_frameScheduler.lastCadence, nanotime(), memory_order_release);
|
||||||
|
}
|
||||||
|
|
||||||
void frameScheduler_update(void)
|
void frameScheduler_update(void)
|
||||||
{
|
{
|
||||||
if (!l_frameScheduler.supported)
|
if (!l_frameScheduler.supported)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const uint64_t lastCadence = atomic_load_explicit(
|
||||||
|
&l_frameScheduler.lastCadence, memory_order_acquire);
|
||||||
const uint64_t now = nanotime();
|
const uint64_t now = nanotime();
|
||||||
const uint64_t period = presentationPeriod();
|
if (!lastCadence ||
|
||||||
if (period < FRAME_SCHEDULER_MIN_PERIOD_NS ||
|
now - lastCadence > FRAME_SCHEDULER_CADENCE_GRACE_NS)
|
||||||
period > FRAME_SCHEDULER_MAX_PERIOD_NS)
|
|
||||||
{
|
{
|
||||||
if (l_frameScheduler.active && l_frameScheduler.lastCadence &&
|
if (l_frameScheduler.active &&
|
||||||
now - l_frameScheduler.lastCadence >
|
|
||||||
FRAME_SCHEDULER_CADENCE_GRACE_NS &&
|
|
||||||
sendSchedule(LG_TRANSPORT_FRAME_SCHEDULE_RELEASE, 0))
|
sendSchedule(LG_TRANSPORT_FRAME_SCHEDULE_RELEASE, 0))
|
||||||
{
|
{
|
||||||
l_frameScheduler.active = false;
|
l_frameScheduler.active = false;
|
||||||
@@ -210,7 +215,11 @@ void frameScheduler_update(void)
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
l_frameScheduler.lastCadence = now;
|
|
||||||
|
const uint64_t period = presentationPeriod();
|
||||||
|
if (period < FRAME_SCHEDULER_MIN_PERIOD_NS ||
|
||||||
|
period > FRAME_SCHEDULER_MAX_PERIOD_NS)
|
||||||
|
return;
|
||||||
|
|
||||||
bool reset = !l_frameScheduler.period;
|
bool reset = !l_frameScheduler.period;
|
||||||
if (!reset)
|
if (!reset)
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ void frameScheduler_init(void);
|
|||||||
void frameScheduler_free(void);
|
void frameScheduler_free(void);
|
||||||
void frameScheduler_start(LG_TransportFeatureFlags features);
|
void frameScheduler_start(LG_TransportFeatureFlags features);
|
||||||
void frameScheduler_stop(void);
|
void frameScheduler_stop(void);
|
||||||
|
void frameScheduler_observeCadence(void);
|
||||||
void frameScheduler_update(void);
|
void frameScheduler_update(void);
|
||||||
void frameScheduler_feedback(uint64_t frameSerial, uint32_t generation,
|
void frameScheduler_feedback(uint64_t frameSerial, uint32_t generation,
|
||||||
uint32_t scheduleEpoch, uint32_t deadlineSerial,
|
uint32_t scheduleEpoch, uint32_t deadlineSerial,
|
||||||
|
|||||||
@@ -647,6 +647,9 @@ static int renderThread(void * unused)
|
|||||||
if (g_state.jitRender)
|
if (g_state.jitRender)
|
||||||
{
|
{
|
||||||
const LG_DSWaitFrameResult waitResult = g_state.ds->waitFrame();
|
const LG_DSWaitFrameResult waitResult = g_state.ds->waitFrame();
|
||||||
|
if (waitResult & LG_DS_WAIT_FRAME_CADENCE)
|
||||||
|
frameScheduler_observeCadence();
|
||||||
|
|
||||||
const LG_RendererFrameToken queuedAtWake =
|
const LG_RendererFrameToken queuedAtWake =
|
||||||
waitResult == LG_DS_WAIT_FRAME_CADENCE ?
|
waitResult == LG_DS_WAIT_FRAME_CADENCE ?
|
||||||
frameTimingQueuedToken() : LG_RENDERER_FRAME_TOKEN_NONE;
|
frameTimingQueuedToken() : LG_RENDERER_FRAME_TOKEN_NONE;
|
||||||
@@ -756,6 +759,9 @@ static int renderThread(void * unused)
|
|||||||
const uint64_t renderEnd = nanotime();
|
const uint64_t renderEnd = nanotime();
|
||||||
LG_UNLOCK(g_state.lgrLock);
|
LG_UNLOCK(g_state.lgrLock);
|
||||||
|
|
||||||
|
if (!g_state.jitRender)
|
||||||
|
frameScheduler_observeCadence();
|
||||||
|
|
||||||
if (rendererTiming.frameToken != LG_RENDERER_FRAME_TOKEN_NONE)
|
if (rendererTiming.frameToken != LG_RENDERER_FRAME_TOKEN_NONE)
|
||||||
frameTimingFinishRender(
|
frameTimingFinishRender(
|
||||||
&rendererTiming, prepareStart, prepareTime, renderEnd,
|
&rendererTiming, prepareStart, prepareTime, renderEnd,
|
||||||
|
|||||||
Reference in New Issue
Block a user