[client] overlay: restore every splash fade frame

Mark the active fade as requiring a fully restored render target.
This also covers guest-driven renders between animation ticks so they
cannot blend over stale splash content.
This commit is contained in:
Geoffrey McRae
2026-08-05 10:53:52 +10:00
parent 606a06535e
commit d815ef87d5
5 changed files with 40 additions and 6 deletions

View File

@@ -114,6 +114,7 @@ void app_registerOverlay(const struct LG_OverlayOps * ops, const void * params);
void app_initOverlays(void); void app_initOverlays(void);
void app_setOverlay(bool enable); void app_setOverlay(bool enable);
bool app_overlayNeedsRender(void); bool app_overlayNeedsRender(void);
bool app_overlayNeedsFullRender(void);
/** /**
* render the overlay * render the overlay
* returns: * returns:

View File

@@ -45,6 +45,10 @@ struct LG_OverlayOps
* optional, if omitted assumes false */ * optional, if omitted assumes false */
bool (*needs_render)(void * udata, bool interactive); bool (*needs_render)(void * udata, bool interactive);
/* return true if the overlay must be drawn over a fully restored frame
* optional, if omitted assumes false */
bool (*needs_full_render)(void * udata);
/* return true if the overlay currently requires overlay mode /* return true if the overlay currently requires overlay mode
* optional, if omitted assumes false */ * optional, if omitted assumes false */
bool (*needs_overlay)(void * udata); bool (*needs_overlay)(void * udata);

View File

@@ -1030,6 +1030,27 @@ bool app_overlayNeedsRender(void)
return result; return result;
} }
bool app_overlayNeedsFullRender(void)
{
bool result = false;
struct Overlay * overlay;
ll_lock(g_state.overlays);
ll_forEachNL(g_state.overlays, item, overlay)
{
if (!overlay->ops->needs_full_render)
continue;
if (overlay->ops->needs_full_render(overlay->udata))
{
result = true;
break;
}
}
ll_unlock(g_state.overlays);
return result;
}
int app_renderOverlay(struct Rect * rects, int maxRects) int app_renderOverlay(struct Rect * rects, int maxRects)
{ {
int totalRects = 0; int totalRects = 0;

View File

@@ -695,7 +695,9 @@ static int renderThread(void * unused)
atomic_compare_exchange_weak(&g_state.lgrResize, &resize, 0); atomic_compare_exchange_weak(&g_state.lgrResize, &resize, 0);
} }
const bool invalidate = atomic_exchange(&g_state.invalidateWindow, false); const bool invalidate =
atomic_exchange(&g_state.invalidateWindow, false) ||
app_overlayNeedsFullRender();
const LG_RendererFrameToken frameTokenLimit = frameTimingQueuedToken(); const LG_RendererFrameToken frameTokenLimit = frameTimingQueuedToken();
const uint64_t prepareStart = nanotime(); const uint64_t prepareStart = nanotime();

View File

@@ -247,11 +247,17 @@ static bool splash_tick(void * udata, unsigned long long tickCount)
return false; return false;
} }
static bool splash_needsFullRender(void * udata)
{
return !l_show && !l_fadeDone;
}
struct LG_OverlayOps LGOverlaySplash = struct LG_OverlayOps LGOverlaySplash =
{ {
.name = "splash", .name = "splash",
.init = splash_init, .init = splash_init,
.free = splash_free, .free = splash_free,
.needs_full_render = splash_needsFullRender,
.render = splash_render, .render = splash_render,
.tick = splash_tick, .tick = splash_tick,
}; };