From 81be5a388ad1d9449253f85e569bc1da0ecb9e94 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Wed, 12 Aug 2026 04:18:12 +1000 Subject: [PATCH] [client] render: bind invalidation to queue batches --- client/src/main.c | 4 ++-- client/src/render_queue.c | 29 +++++++++++++++++------------ client/src/render_queue.h | 2 +- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/client/src/main.c b/client/src/main.c index cf26572a..6bac5a3d 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -985,7 +985,7 @@ static int renderThread(void * unused) LG_LOCK(g_state.lgrLock); - renderQueue_process(); + const bool queueFull = renderQueue_process(); if (g_state.videoGeometryDirty) { @@ -1009,7 +1009,7 @@ static int renderThread(void * unused) const bool windowInvalid = atomic_exchange(&g_state.invalidateWindow, false); const bool overlayFull = app_overlayNeedsFullRender(); - const bool invalidate = windowInvalid || overlayFull; + const bool invalidate = queueFull || windowInvalid || overlayFull; const uint64_t prepareTime = nanotime() - prepareStart; if (unlikely(invalidate)) diff --git a/client/src/render_queue.c b/client/src/render_queue.c index 86111807..681f914f 100644 --- a/client/src/render_queue.c +++ b/client/src/render_queue.c @@ -439,22 +439,24 @@ static bool queueSwSurfaceUpdate(RenderQueueSource source, return queueCommand(cmd, RENDER_QUEUE_INVALIDATE_PARTIAL); } -static void wakeQueue(RenderQueueInvalidate invalidate, bool wake) +static void wakeQueue(bool wake) { if (wake) - app_invalidateWindow(invalidate == RENDER_QUEUE_INVALIDATE_FULL); + app_invalidateWindow(false); } static void enqueueCommand(RenderCommand * cmd, RenderQueueInvalidate invalidate) { - wakeQueue(invalidate, queueCommand(cmd, invalidate)); + wakeQueue(queueCommand(cmd, invalidate)); } -static RenderCommand * detachCommands(void) +static RenderCommand * detachCommands(RenderQueueInvalidate * invalidate) { LG_LOCK(l_renderQueueLock); RenderCommand * head = l_renderQueueHead; + if (invalidate) + *invalidate = l_renderQueueInvalidate; l_renderQueueHead = NULL; l_renderQueueTail = NULL; l_renderQueueInvalidate = RENDER_QUEUE_INVALIDATE_NONE; @@ -598,7 +600,7 @@ void renderQueue_free(void) void renderQueue_clear(void) { - RenderCommand * cmd = detachCommands(); + RenderCommand * cmd = detachCommands(NULL); while(cmd) { RenderCommand * next = cmd->next; @@ -795,7 +797,7 @@ static uint64_t enqueueTransition(RenderCommand * cmd, if (publishedSerial) atomic_store_explicit(publishedSerial, serial, memory_order_release); LG_UNLOCK(l_transitionLock); - wakeQueue(RENDER_QUEUE_INVALIDATE_FULL, wake); + wakeQueue(wake); return serial; } @@ -913,7 +915,7 @@ void renderQueue_sourceSwSurfaceDrawFill(RenderQueueSource source, swSurfaceDamageAdd(surface, &damage); const bool wake = queueSwSurfaceUpdate(source, surface); LG_UNLOCK(surface->lock); - wakeQueue(RENDER_QUEUE_INVALIDATE_PARTIAL, wake); + wakeQueue(wake); } void renderQueue_sourceSwSurfaceDrawBitmap(RenderQueueSource source, @@ -989,7 +991,7 @@ void renderQueue_sourceSwSurfaceDrawBitmap(RenderQueueSource source, swSurfaceDamageAdd(surface, &damage); const bool wake = queueSwSurfaceUpdate(source, surface); LG_UNLOCK(surface->lock); - wakeQueue(RENDER_QUEUE_INVALIDATE_PARTIAL, wake); + wakeQueue(wake); } void renderQueue_sourceSurfaceFormat(RenderQueueSource source, @@ -1303,9 +1305,10 @@ static void rejectSourceTransition(const RenderCommand * cmd) cmd->source, cmd->transitionSerial); } -void renderQueue_process(void) +bool renderQueue_process(void) { - RenderCommand * cmd = detachCommands(); + RenderQueueInvalidate invalidate; + RenderCommand * cmd = detachCommands(&invalidate); while(cmd) { RenderCommand * next = cmd->next; @@ -1324,7 +1327,7 @@ void renderQueue_process(void) if (transition) LG_UNLOCK(l_transitionLock); freeCommand(cmd); - wakeQueue(RENDER_QUEUE_INVALIDATE_PARTIAL, wake); + wakeQueue(wake); cmd = next; continue; } @@ -1477,9 +1480,11 @@ void renderQueue_process(void) if (transition) LG_UNLOCK(l_transitionLock); freeCommand(cmd); - wakeQueue(RENDER_QUEUE_INVALIDATE_PARTIAL, wake); + wakeQueue(wake); cmd = next; } + + return invalidate == RENDER_QUEUE_INVALIDATE_FULL; } void renderQueue_presented(void) diff --git a/client/src/render_queue.h b/client/src/render_queue.h index 12d8a6c3..fd919811 100644 --- a/client/src/render_queue.h +++ b/client/src/render_queue.h @@ -42,7 +42,7 @@ typedef void (*RenderQueueSourceRejectFn)(void * opaque, void renderQueue_init(void); void renderQueue_free(void); void renderQueue_clear(void); -void renderQueue_process(void); +bool renderQueue_process(void); void renderQueue_presented(void); void renderQueue_setSourceFns(RenderQueueSourcePrepareFn prepare,