From d1e421f8a8679cbc2b47af7606743fb1ea7f83dc Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Tue, 24 May 2022 09:48:54 +1000 Subject: [PATCH] [client] spice: delay showing the spice display until spice is ready --- client/src/app.c | 12 +++++-- client/src/main.c | 13 +++++--- client/src/main.h | 1 + client/src/render_queue.c | 69 +++++++++++++++++++++++---------------- client/src/render_queue.h | 17 +++++++--- repos/PureSpice | 2 +- 6 files changed, 75 insertions(+), 39 deletions(-) diff --git a/client/src/app.c b/client/src/app.c index 4c2fb890..fe638409 100644 --- a/client/src/app.c +++ b/client/src/app.c @@ -24,6 +24,7 @@ #include "core.h" #include "util.h" #include "clipboard.h" +#include "render_queue.h" #include "kb.h" @@ -1043,6 +1044,13 @@ void app_useSpiceDisplay(bool enable) if (!g_params.useSpice || lastState == enable) return; + // if spice is not yet ready, flag the state we want for when it is + if (!g_state.spiceReady) + { + g_state.initialSpiceDisplay = enable; + return; + } + if (!purespice_hasChannel(PS_CHANNEL_DISPLAY)) return; @@ -1054,11 +1062,11 @@ void app_useSpiceDisplay(bool enable) if (enable) { purespice_connectChannel(PS_CHANNEL_DISPLAY); - RENDERER(spiceShow, true); + renderQueue_spiceShow(true); } else { + renderQueue_spiceShow(false); purespice_disconnectChannel(PS_CHANNEL_DISPLAY); - RENDERER(spiceShow, false); } } diff --git a/client/src/main.c b/client/src/main.c index 4f64fe8b..9756d304 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -845,6 +845,10 @@ static void checkUUID(void) void spiceReady(void) { + g_state.spiceReady = true; + if (g_state.initialSpiceDisplay) + app_useSpiceDisplay(true); + // set the intial mouse mode purespice_mouseMode(true); @@ -864,7 +868,6 @@ void spiceReady(void) return; memcpy(g_state.spiceUUID, info.uuid, sizeof(g_state.spiceUUID)); - g_state.spiceReady = true; checkUUID(); if (g_params.useSpiceInput) @@ -962,6 +965,11 @@ int spiceThread(void * arg) #endif }; + /* use the spice display until we get frames from the LG host application + * it is safe to call this before connect as it will be delayed until + * spiceReady is called */ + app_useSpiceDisplay(true); + if (!purespice_connect(&config)) { DEBUG_ERROR("Failed to connect to spice server"); @@ -1317,9 +1325,6 @@ static int lg_run(void) if (g_state.cbAvailable) g_state.cbRequestList = ll_new(); - // use the spice display until we get frames from the LG host application - app_useSpiceDisplay(true); - LGMP_STATUS status; while(g_state.state == APP_STATE_RUNNING) diff --git a/client/src/main.h b/client/src/main.h index 47184ef7..6c98e7a6 100644 --- a/client/src/main.h +++ b/client/src/main.h @@ -71,6 +71,7 @@ struct AppState uint8_t spiceUUID[16]; bool spiceReady; + bool initialSpiceDisplay; uint8_t guestUUID[16]; bool guestUUIDValid; KVMFROS guestOS; diff --git a/client/src/render_queue.c b/client/src/render_queue.c index 162e7dde..03a4db10 100644 --- a/client/src/render_queue.c +++ b/client/src/render_queue.c @@ -47,7 +47,7 @@ void renderQueue_clear(void) while(ll_shift(l_renderQueue, (void **)&cmd)) { if (cmd->op == SPICE_OP_DRAW_BITMAP) - free(cmd->drawBitmap.data); + free(cmd->spiceDrawBitmap.data); free(cmd); } } @@ -58,9 +58,9 @@ void renderQueue_spiceConfigure(int width, int height) renderQueue_clear(); RenderCommand * cmd = malloc(sizeof(*cmd)); - cmd->op = SPICE_OP_CONFIGURE; - cmd->configure.width = width; - cmd->configure.height = height; + cmd->op = SPICE_OP_CONFIGURE; + cmd->spiceConfigure.width = width; + cmd->spiceConfigure.height = height; ll_push(l_renderQueue, cmd); app_invalidateWindow(true); } @@ -69,12 +69,12 @@ void renderQueue_spiceDrawFill(int x, int y, int width, int height, uint32_t color) { RenderCommand * cmd = malloc(sizeof(*cmd)); - cmd->op = SPICE_OP_DRAW_FILL; - cmd->fillRect.x = x; - cmd->fillRect.y = y; - cmd->fillRect.width = width; - cmd->fillRect.height = height; - cmd->fillRect.color = color; + cmd->op = SPICE_OP_DRAW_FILL; + cmd->spiceFillRect.x = x; + cmd->spiceFillRect.y = y; + cmd->spiceFillRect.width = width; + cmd->spiceFillRect.height = height; + cmd->spiceFillRect.color = color; ll_push(l_renderQueue, cmd); app_invalidateWindow(true); } @@ -83,15 +83,24 @@ void renderQueue_spiceDrawBitmap(int x, int y, int width, int height, int stride void * data, bool topDown) { RenderCommand * cmd = malloc(sizeof(*cmd)); - cmd->op = SPICE_OP_DRAW_BITMAP; - cmd->drawBitmap.x = x; - cmd->drawBitmap.y = y; - cmd->drawBitmap.width = width; - cmd->drawBitmap.height = height; - cmd->drawBitmap.stride = stride; - cmd->drawBitmap.data = malloc(height * stride); - cmd->drawBitmap.topDown = topDown; - memcpy(cmd->drawBitmap.data, data, height * stride); + cmd->op = SPICE_OP_DRAW_BITMAP; + cmd->spiceDrawBitmap.x = x; + cmd->spiceDrawBitmap.y = y; + cmd->spiceDrawBitmap.width = width; + cmd->spiceDrawBitmap.height = height; + cmd->spiceDrawBitmap.stride = stride; + cmd->spiceDrawBitmap.data = malloc(height * stride); + cmd->spiceDrawBitmap.topDown = topDown; + memcpy(cmd->spiceDrawBitmap.data, data, height * stride); + ll_push(l_renderQueue, cmd); + app_invalidateWindow(true); +} + +void renderQueue_spiceShow(bool show) +{ + RenderCommand * cmd = malloc(sizeof(*cmd)); + cmd->op = SPICE_OP_SHOW; + cmd->spiceShow.show = show; ll_push(l_renderQueue, cmd); app_invalidateWindow(true); } @@ -105,23 +114,27 @@ void renderQueue_process(void) { case SPICE_OP_CONFIGURE: RENDERER(spiceConfigure, - cmd->configure.width, cmd->configure.height); + cmd->spiceConfigure.width, cmd->spiceConfigure.height); break; case SPICE_OP_DRAW_FILL: RENDERER(spiceDrawFill, - cmd->fillRect.x , cmd->fillRect.y, - cmd->fillRect.width, cmd->fillRect.height, - cmd->fillRect.color); + cmd->spiceFillRect.x , cmd->spiceFillRect.y, + cmd->spiceFillRect.width, cmd->spiceFillRect.height, + cmd->spiceFillRect.color); break; case SPICE_OP_DRAW_BITMAP: RENDERER(spiceDrawBitmap, - cmd->drawBitmap.x , cmd->drawBitmap.y, - cmd->drawBitmap.width , cmd->drawBitmap.height, - cmd->drawBitmap.stride, cmd->drawBitmap.data, - cmd->drawBitmap.topDown); - free(cmd->drawBitmap.data); + cmd->spiceDrawBitmap.x , cmd->spiceDrawBitmap.y, + cmd->spiceDrawBitmap.width , cmd->spiceDrawBitmap.height, + cmd->spiceDrawBitmap.stride, cmd->spiceDrawBitmap.data, + cmd->spiceDrawBitmap.topDown); + free(cmd->spiceDrawBitmap.data); + break; + + case SPICE_OP_SHOW: + RENDERER(spiceShow, cmd->spiceShow.show); break; } free(cmd); diff --git a/client/src/render_queue.h b/client/src/render_queue.h index ac675ea6..b9f46718 100644 --- a/client/src/render_queue.h +++ b/client/src/render_queue.h @@ -26,7 +26,8 @@ typedef struct { SPICE_OP_CONFIGURE, SPICE_OP_DRAW_FILL, - SPICE_OP_DRAW_BITMAP + SPICE_OP_DRAW_BITMAP, + SPICE_OP_SHOW } op; @@ -36,7 +37,7 @@ typedef struct { int width, height; } - configure; + spiceConfigure; struct { @@ -44,7 +45,7 @@ typedef struct int width, height; uint32_t color; } - fillRect; + spiceFillRect; struct { @@ -54,7 +55,13 @@ typedef struct uint8_t * data; bool topDown; } - drawBitmap; + spiceDrawBitmap; + + struct + { + bool show; + } + spiceShow; }; } RenderCommand; @@ -71,3 +78,5 @@ void renderQueue_spiceDrawFill(int x, int y, int width, int height, void renderQueue_spiceDrawBitmap(int x, int y, int width, int height, int stride, void * data, bool topDown); + +void renderQueue_spiceShow(bool show); diff --git a/repos/PureSpice b/repos/PureSpice index d58cb4ac..5936cd4f 160000 --- a/repos/PureSpice +++ b/repos/PureSpice @@ -1 +1 @@ -Subproject commit d58cb4acd3e2dc7d7d117bb25e8a67a078416d6b +Subproject commit 5936cd4f1d887ca49a168c5c996d81c9e78ba10f