mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-07-28 10:52:02 +00:00
[client] spice: make display switching atomic and failure-aware
This commit is contained in:
@@ -1162,38 +1162,92 @@ void app_stopVideo(bool stop)
|
|||||||
|
|
||||||
bool app_useSpiceDisplay(bool enable)
|
bool app_useSpiceDisplay(bool enable)
|
||||||
{
|
{
|
||||||
static bool lastState = false;
|
if (!g_params.useSpice)
|
||||||
if (!g_params.useSpice || lastState == enable)
|
return false;
|
||||||
return g_params.useSpice && lastState;
|
|
||||||
|
atomic_store_explicit(&g_state.spiceDisplayRequested, enable,
|
||||||
|
memory_order_release);
|
||||||
|
|
||||||
// if spice is not yet ready, flag the state we want for when it is
|
// if spice is not yet ready, flag the state we want for when it is
|
||||||
if (!g_state.spiceReady)
|
if (!g_state.spiceReady)
|
||||||
{
|
|
||||||
g_state.initialSpiceDisplay = enable;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if (!purespice_hasChannel(PS_CHANNEL_DISPLAY))
|
bool active = atomic_load_explicit(&g_state.spiceDisplayActive,
|
||||||
return false;
|
memory_order_acquire);
|
||||||
|
if (active == enable)
|
||||||
|
return active;
|
||||||
|
|
||||||
// do not allow stopping of the host app if not connected
|
// do not allow stopping of the host app if not connected
|
||||||
if (!enable && !g_state.lgHostConnected)
|
if (!enable && !g_state.lgHostConnected)
|
||||||
|
{
|
||||||
|
atomic_store_explicit(&g_state.spiceDisplayRequested, active,
|
||||||
|
memory_order_release);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool expected = false;
|
||||||
|
if (!atomic_compare_exchange_strong_explicit(
|
||||||
|
&g_state.spiceDisplayTransition, &expected, true,
|
||||||
|
memory_order_acquire, memory_order_relaxed))
|
||||||
|
return atomic_load_explicit(&g_state.spiceDisplayActive,
|
||||||
|
memory_order_acquire);
|
||||||
|
|
||||||
|
active = atomic_load_explicit(&g_state.spiceDisplayActive,
|
||||||
|
memory_order_relaxed);
|
||||||
|
if (active == enable)
|
||||||
|
goto done;
|
||||||
|
|
||||||
lastState = enable;
|
|
||||||
if (enable)
|
if (enable)
|
||||||
{
|
{
|
||||||
purespice_connectChannel(PS_CHANNEL_DISPLAY);
|
if (!purespice_hasChannel(PS_CHANNEL_DISPLAY) ||
|
||||||
purespice_connectChannel(PS_CHANNEL_CURSOR);
|
!purespice_hasChannel(PS_CHANNEL_CURSOR))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (!purespice_connectChannel(PS_CHANNEL_DISPLAY))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (!purespice_connectChannel(PS_CHANNEL_CURSOR))
|
||||||
|
{
|
||||||
|
purespice_disconnectChannel(PS_CHANNEL_DISPLAY);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
renderQueue_spiceShow(true);
|
renderQueue_spiceShow(true);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
renderQueue_spiceShow(false);
|
if (!purespice_disconnectChannel(PS_CHANNEL_DISPLAY))
|
||||||
purespice_disconnectChannel(PS_CHANNEL_DISPLAY);
|
goto fail;
|
||||||
purespice_disconnectChannel(PS_CHANNEL_CURSOR);
|
|
||||||
|
if (!purespice_disconnectChannel(PS_CHANNEL_CURSOR))
|
||||||
|
{
|
||||||
|
purespice_connectChannel(PS_CHANNEL_DISPLAY);
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderQueue_spiceShow(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
active = enable;
|
||||||
|
atomic_store_explicit(&g_state.spiceDisplayActive, active,
|
||||||
|
memory_order_release);
|
||||||
overlayStatus_set(LG_USER_STATUS_SPICE, enable);
|
overlayStatus_set(LG_USER_STATUS_SPICE, enable);
|
||||||
return enable;
|
|
||||||
|
done:
|
||||||
|
atomic_store_explicit(&g_state.spiceDisplayTransition, false,
|
||||||
|
memory_order_release);
|
||||||
|
|
||||||
|
enable = atomic_load_explicit(&g_state.spiceDisplayRequested,
|
||||||
|
memory_order_acquire);
|
||||||
|
if (enable != active)
|
||||||
|
return app_useSpiceDisplay(enable);
|
||||||
|
|
||||||
|
return active;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
DEBUG_ERROR("Failed to %s the SPICE display",
|
||||||
|
enable ? "enable" : "disable");
|
||||||
|
atomic_store_explicit(&g_state.spiceDisplayRequested, active,
|
||||||
|
memory_order_release);
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -959,7 +959,8 @@ static void checkUUID(void)
|
|||||||
void spiceReady(void)
|
void spiceReady(void)
|
||||||
{
|
{
|
||||||
g_state.spiceReady = true;
|
g_state.spiceReady = true;
|
||||||
if (g_state.initialSpiceDisplay)
|
if (atomic_load_explicit(&g_state.spiceDisplayRequested,
|
||||||
|
memory_order_acquire))
|
||||||
app_useSpiceDisplay(true);
|
app_useSpiceDisplay(true);
|
||||||
|
|
||||||
// set the intial mouse mode
|
// set the intial mouse mode
|
||||||
|
|||||||
@@ -80,8 +80,11 @@ struct AppState
|
|||||||
|
|
||||||
uint8_t spiceUUID[16];
|
uint8_t spiceUUID[16];
|
||||||
bool spiceReady;
|
bool spiceReady;
|
||||||
bool initialSpiceDisplay;
|
atomic_bool spiceDisplayRequested;
|
||||||
|
atomic_bool spiceDisplayActive;
|
||||||
|
atomic_bool spiceDisplayTransition;
|
||||||
bool spicePrimarySurfaceValid;
|
bool spicePrimarySurfaceValid;
|
||||||
|
|
||||||
uint8_t guestUUID[16];
|
uint8_t guestUUID[16];
|
||||||
bool guestUUIDValid;
|
bool guestUUIDValid;
|
||||||
KVMFROS guestOS;
|
KVMFROS guestOS;
|
||||||
|
|||||||
Reference in New Issue
Block a user