[client] scheduler: qualify presentation feedback

Track cadence, interruption, and calibration wake reasons independently
across X11 and Wayland. Feed phase correction back only when a pure
cadence wake renders the exact frame that was queued at that wake.

Propagate EGL swap results through the display-server boundary. Reject
failed presentations and keep pending Wayland HDR descriptions inactive
until the preceding surface commit succeeds.
This commit is contained in:
Geoffrey McRae
2026-08-06 16:17:23 +10:00
parent 515f4ba06f
commit 3d1064001d
12 changed files with 119 additions and 57 deletions

View File

@@ -113,6 +113,13 @@ static const struct wl_surface_listener wlSurfaceListener = {
.leave = wlSurfaceLeaveHandler,
};
static void waylandSignalFrame(LG_DSWaitFrameResult result)
{
atomic_fetch_or_explicit(
&wlWm.frameEventFlags, result, memory_order_release);
lgSignalEvent(wlWm.frameEvent);
}
static void fractionalScalePreferredScale(void * data,
struct wp_fractional_scale_v1 * fractionalScale, uint32_t scale)
{
@@ -133,7 +140,7 @@ bool waylandWindowInit(const char * title, const char * appId, bool fullscreen,
DEBUG_ERROR("Failed to initialize event for waitFrame");
return false;
}
lgSignalEvent(wlWm.frameEvent);
waylandSignalFrame(LG_DS_WAIT_FRAME_INTERRUPTED);
if (!wlWm.compositor)
{
@@ -220,7 +227,7 @@ bool waylandIsValidPointerPos(int x, int y)
static void frameHandler(void * opaque, struct wl_callback * callback, unsigned int data)
{
lgSignalEvent(wlWm.frameEvent);
waylandSignalFrame(LG_DS_WAIT_FRAME_CADENCE);
wl_callback_destroy(callback);
}
@@ -228,9 +235,11 @@ static const struct wl_callback_listener frame_listener = {
.done = frameHandler,
};
bool waylandWaitFrame(void)
LG_DSWaitFrameResult waylandWaitFrame(void)
{
lgWaitEvent(wlWm.frameEvent, TIMEOUT_INFINITE);
const LG_DSWaitFrameResult result = atomic_exchange_explicit(
&wlWm.frameEventFlags, LG_DS_WAIT_FRAME_NONE, memory_order_acquire);
INTERLOCKED_SECTION(wlWm.surfaceLock,
{
@@ -239,7 +248,7 @@ bool waylandWaitFrame(void)
wl_callback_add_listener(callback, &frame_listener, NULL);
});
return false;
return result;
}
void waylandSkipFrame(void)
@@ -253,5 +262,5 @@ void waylandSkipFrame(void)
void waylandStopWaitFrame(void)
{
lgSignalEvent(wlWm.frameEvent);
waylandSignalFrame(LG_DS_WAIT_FRAME_INTERRUPTED);
}