[client] overlay: coalesce pointer redraws during splash fade

Pointer updates bypassed the paced overlay render and woke the renderer
for every cursor packet. On the default single-buffer EGL surface,
each full fade redraw could expose the desktop before the splash was
blended again.

Coalesce pointer redraws into the existing fade cadence while keeping
the latest cursor state. Immediate cursor redraw resumes when the fade
ends.
This commit is contained in:
Geoffrey McRae
2026-08-06 18:17:34 +10:00
parent d8604ec144
commit 604b3082f3
3 changed files with 19 additions and 2 deletions

View File

@@ -916,7 +916,9 @@ int main_cursorThread(void * unused)
(g_cursor.draw || !g_params.useSpiceInput),
g_cursor.guest.x, g_cursor.guest.y,
g_cursor.guest.hx, g_cursor.guest.hy);
if (!g_state.stopVideo)
/* The active fade already schedules a render. Coalesce pointer
* changes into it instead of exposing rapid single-buffer redraws. */
if (!g_state.stopVideo && !overlaySplash_isFading())
lgSignalEvent(g_state.frameEvent);
}
continue;
@@ -990,7 +992,8 @@ int main_cursorThread(void * unused)
if ((g_params.mouseRedraw ||
(pointer.flags & LG_TRANSPORT_POINTER_COLOR_TRANSFORM)) &&
g_cursor.guest.visible && !g_state.stopVideo)
g_cursor.guest.visible && !g_state.stopVideo &&
!overlaySplash_isFading())
lgSignalEvent(g_state.frameEvent);
g_state.transportOps->releasePointer(g_state.transport, &pointer);

View File

@@ -49,6 +49,7 @@ enum SplashState
};
static _Atomic(bool) l_requestedShow;
static _Atomic(bool) l_fading;
static bool l_appliedShow;
static enum SplashState l_state;
static uint64_t l_fadeStart;
@@ -99,6 +100,7 @@ static void drawRadialGradient(ImDrawList * list, int x, int y, int w, int h,
static bool splash_init(void ** udata, const void * params)
{
atomic_store_explicit(&l_requestedShow, true, memory_order_relaxed);
atomic_store_explicit(&l_fading, false, memory_order_relaxed);
l_appliedShow = true;
l_state = SPLASH_VISIBLE;
l_fadeStart = 0;
@@ -176,6 +178,7 @@ static int splash_render(void * udata, bool interactive, struct Rect * windowRec
if (elapsed >= FADE_TIME_NS)
{
l_state = SPLASH_HIDDEN;
atomic_store_explicit(&l_fading, false, memory_order_release);
return 0;
}
alpha -= (float)elapsed / (float)FADE_TIME_NS;
@@ -267,13 +270,18 @@ static bool splash_needsFullRender(void * udata)
{
l_state = SPLASH_VISIBLE;
l_fadeStart = 0;
atomic_store_explicit(&l_fading, false, memory_order_release);
}
else if (g_params.quickSplash)
{
l_state = SPLASH_HIDDEN;
atomic_store_explicit(&l_fading, false, memory_order_release);
}
else
{
l_state = SPLASH_FADING;
l_fadeStart = nanotime();
atomic_store_explicit(&l_fading, true, memory_order_release);
}
}
@@ -298,3 +306,8 @@ void overlaySplash_show(bool show)
app_invalidateWindow(true);
}
bool overlaySplash_isFading(void)
{
return atomic_load_explicit(&l_fading, memory_order_acquire);
}

View File

@@ -122,6 +122,7 @@ typedef enum LG_UserStatus
LGUserStatus;
void overlaySplash_show(bool show);
bool overlaySplash_isFading(void);
void overlayStatus_set(LGUserStatus, bool value);
#endif