mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-23 05:53:40 +00:00
[client] all: make it possible to signal full window invalidation
Now that we are drawing with damage rects, when the window is hidden and then exposed the window may not get fully redrawn. This provides `app_invalidateWindow` for the display server backend to call when the screen needs a full redraw.
This commit is contained in:
parent
8c2a77e84e
commit
60a58d4d8d
@ -46,6 +46,7 @@ bool app_isFormatValid(void);
|
|||||||
void app_updateCursorPos(double x, double y);
|
void app_updateCursorPos(double x, double y);
|
||||||
void app_updateWindowPos(int x, int y);
|
void app_updateWindowPos(int x, int y);
|
||||||
void app_handleResizeEvent(int w, int h, double scale, const struct Border border);
|
void app_handleResizeEvent(int w, int h, double scale, const struct Border border);
|
||||||
|
void app_invalidateWindow(void);
|
||||||
|
|
||||||
void app_handleMouseRelative(double normx, double normy,
|
void app_handleMouseRelative(double normx, double normy,
|
||||||
double rawx, double rawy);
|
double rawx, double rawy);
|
||||||
|
@ -112,7 +112,7 @@ typedef bool (* LG_RendererOnMouseEvent )(void * opaque, const bool visi
|
|||||||
typedef bool (* LG_RendererOnFrameFormat)(void * opaque, const LG_RendererFormat format, bool useDMA);
|
typedef bool (* LG_RendererOnFrameFormat)(void * opaque, const LG_RendererFormat format, bool useDMA);
|
||||||
typedef bool (* LG_RendererOnFrame )(void * opaque, const FrameBuffer * frame, int dmaFD, const FrameDamageRect * damage, int damageCount);
|
typedef bool (* LG_RendererOnFrame )(void * opaque, const FrameBuffer * frame, int dmaFD, const FrameDamageRect * damage, int damageCount);
|
||||||
typedef bool (* LG_RendererRenderStartup)(void * opaque);
|
typedef bool (* LG_RendererRenderStartup)(void * opaque);
|
||||||
typedef bool (* LG_RendererRender )(void * opaque, LG_RendererRotate rotate, const bool newFrame);
|
typedef bool (* LG_RendererRender )(void * opaque, LG_RendererRotate rotate, const bool newFrame, const bool invalidateWindow);
|
||||||
|
|
||||||
typedef struct LG_Renderer
|
typedef struct LG_Renderer
|
||||||
{
|
{
|
||||||
|
@ -791,7 +791,8 @@ bool egl_render_startup(void * opaque)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egl_render(void * opaque, LG_RendererRotate rotate, const bool newFrame)
|
bool egl_render(void * opaque, LG_RendererRotate rotate, const bool newFrame,
|
||||||
|
const bool invalidateWindow)
|
||||||
{
|
{
|
||||||
struct Inst * this = (struct Inst *)opaque;
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
|
|
||||||
@ -856,6 +857,7 @@ bool egl_render(void * opaque, LG_RendererRotate rotate, const bool newFrame)
|
|||||||
}
|
}
|
||||||
|
|
||||||
hasOverlay |= egl_damage_render(this->damage, newFrame ? desktopDamage : NULL);
|
hasOverlay |= egl_damage_render(this->damage, newFrame ? desktopDamage : NULL);
|
||||||
|
hasOverlay |= invalidateWindow;
|
||||||
|
|
||||||
struct Rect damage[KVMFR_MAX_DAMAGE_RECTS + MAX_OVERLAY_RECTS + 2];
|
struct Rect damage[KVMFR_MAX_DAMAGE_RECTS + MAX_OVERLAY_RECTS + 2];
|
||||||
int damageIdx = app_renderOverlay(damage, MAX_OVERLAY_RECTS);
|
int damageIdx = app_renderOverlay(damage, MAX_OVERLAY_RECTS);
|
||||||
|
@ -456,7 +456,8 @@ bool opengl_render_startup(void * opaque)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool opengl_render(void * opaque, LG_RendererRotate rotate, const bool newFrame)
|
bool opengl_render(void * opaque, LG_RendererRotate rotate, const bool newFrame,
|
||||||
|
const bool invalidateWindow)
|
||||||
{
|
{
|
||||||
struct Inst * this = (struct Inst *)opaque;
|
struct Inst * this = (struct Inst *)opaque;
|
||||||
if (!this)
|
if (!this)
|
||||||
|
@ -418,6 +418,12 @@ void app_handleResizeEvent(int w, int h, double scale, const struct Border borde
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void app_invalidateWindow(void)
|
||||||
|
{
|
||||||
|
atomic_store(&g_state.invalidateWindow, true);
|
||||||
|
lgSignalEvent(g_state.frameEvent);
|
||||||
|
}
|
||||||
|
|
||||||
void app_handleCloseEvent(void)
|
void app_handleCloseEvent(void)
|
||||||
{
|
{
|
||||||
if (!g_params.ignoreQuit || !g_cursor.inView)
|
if (!g_params.ignoreQuit || !g_cursor.inView)
|
||||||
|
@ -64,7 +64,6 @@ static int cursorThread(void * unused);
|
|||||||
static int renderThread(void * unused);
|
static int renderThread(void * unused);
|
||||||
|
|
||||||
static LGEvent *e_startup = NULL;
|
static LGEvent *e_startup = NULL;
|
||||||
static LGEvent *e_frame = NULL;
|
|
||||||
static LGThread *t_spice = NULL;
|
static LGThread *t_spice = NULL;
|
||||||
static LGThread *t_render = NULL;
|
static LGThread *t_render = NULL;
|
||||||
static LGThread *t_cursor = NULL;
|
static LGThread *t_cursor = NULL;
|
||||||
@ -170,7 +169,7 @@ static int renderThread(void * unused)
|
|||||||
{
|
{
|
||||||
float ups = atomic_load_explicit(&g_state.ups, memory_order_relaxed);
|
float ups = atomic_load_explicit(&g_state.ups, memory_order_relaxed);
|
||||||
|
|
||||||
if (!lgWaitEventAbs(e_frame, &time) || ups > g_params.fpsMin)
|
if (!lgWaitEventAbs(g_state.frameEvent, &time) || ups > g_params.fpsMin)
|
||||||
{
|
{
|
||||||
/* only update the time if we woke up early */
|
/* only update the time if we woke up early */
|
||||||
clock_gettime(CLOCK_MONOTONIC, &time);
|
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||||
@ -208,8 +207,11 @@ static int renderThread(void * unused)
|
|||||||
const bool newFrame = frameCount != lastFrameCount;
|
const bool newFrame = frameCount != lastFrameCount;
|
||||||
lastFrameCount = frameCount;
|
lastFrameCount = frameCount;
|
||||||
|
|
||||||
|
const bool invalidate = atomic_exchange(&g_state.invalidateWindow, false);
|
||||||
|
|
||||||
LG_LOCK(g_state.lgrLock);
|
LG_LOCK(g_state.lgrLock);
|
||||||
if (!g_state.lgr->render(g_state.lgrData, g_params.winRotate, newFrame))
|
if (!g_state.lgr->render(g_state.lgrData, g_params.winRotate, newFrame,
|
||||||
|
invalidate))
|
||||||
{
|
{
|
||||||
LG_UNLOCK(g_state.lgrLock);
|
LG_UNLOCK(g_state.lgrLock);
|
||||||
break;
|
break;
|
||||||
@ -306,7 +308,7 @@ static int cursorThread(void * unused)
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!g_state.stopVideo)
|
if (!g_state.stopVideo)
|
||||||
lgSignalEvent(e_frame);
|
lgSignalEvent(g_state.frameEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct timespec req =
|
const struct timespec req =
|
||||||
@ -405,7 +407,7 @@ static int cursorThread(void * unused)
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (g_params.mouseRedraw && g_cursor.guest.visible && !g_state.stopVideo)
|
if (g_params.mouseRedraw && g_cursor.guest.visible && !g_state.stopVideo)
|
||||||
lgSignalEvent(e_frame);
|
lgSignalEvent(g_state.frameEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
lgmpClientUnsubscribe(&queue);
|
lgmpClientUnsubscribe(&queue);
|
||||||
@ -678,7 +680,7 @@ int main_frameThread(void * unused)
|
|||||||
g_state.lastFrameTimeValid = true;
|
g_state.lastFrameTimeValid = true;
|
||||||
|
|
||||||
atomic_fetch_add_explicit(&g_state.frameCount, 1, memory_order_relaxed);
|
atomic_fetch_add_explicit(&g_state.frameCount, 1, memory_order_relaxed);
|
||||||
lgSignalEvent(e_frame);
|
lgSignalEvent(g_state.frameEvent);
|
||||||
lgmpClientMessageDone(queue);
|
lgmpClientMessageDone(queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -950,7 +952,7 @@ static int lg_run(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// setup the new frame event
|
// setup the new frame event
|
||||||
if (!(e_frame = lgCreateEvent(true, 0)))
|
if (!(g_state.frameEvent = lgCreateEvent(true, 0)))
|
||||||
{
|
{
|
||||||
DEBUG_ERROR("failed to create the frame event");
|
DEBUG_ERROR("failed to create the frame event");
|
||||||
return -1;
|
return -1;
|
||||||
@ -1092,7 +1094,7 @@ restart:
|
|||||||
if (g_state.state == APP_STATE_RESTART)
|
if (g_state.state == APP_STATE_RESTART)
|
||||||
{
|
{
|
||||||
lgSignalEvent(e_startup);
|
lgSignalEvent(e_startup);
|
||||||
lgSignalEvent(e_frame);
|
lgSignalEvent(g_state.frameEvent);
|
||||||
|
|
||||||
core_stopFrameThread();
|
core_stopFrameThread();
|
||||||
|
|
||||||
@ -1116,7 +1118,7 @@ static void lg_shutdown(void)
|
|||||||
if (t_render)
|
if (t_render)
|
||||||
{
|
{
|
||||||
lgSignalEvent(e_startup);
|
lgSignalEvent(e_startup);
|
||||||
lgSignalEvent(e_frame);
|
lgSignalEvent(g_state.frameEvent);
|
||||||
lgJoinThread(t_render, NULL);
|
lgJoinThread(t_render, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1129,10 +1131,10 @@ static void lg_shutdown(void)
|
|||||||
g_state.overlays = NULL;
|
g_state.overlays = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e_frame)
|
if (g_state.frameEvent)
|
||||||
{
|
{
|
||||||
lgFreeEvent(e_frame);
|
lgFreeEvent(g_state.frameEvent);
|
||||||
e_frame = NULL;
|
g_state.frameEvent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e_startup)
|
if (e_startup)
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include "common/ivshmem.h"
|
#include "common/ivshmem.h"
|
||||||
#include "common/locking.h"
|
#include "common/locking.h"
|
||||||
#include "common/ringbuffer.h"
|
#include "common/ringbuffer.h"
|
||||||
|
#include "common/event.h"
|
||||||
|
|
||||||
#include "spice/spice.h"
|
#include "spice/spice.h"
|
||||||
#include <lgmp/client.h>
|
#include <lgmp/client.h>
|
||||||
@ -103,6 +104,8 @@ struct AppState
|
|||||||
PLGMPClientQueue pointerQueue;
|
PLGMPClientQueue pointerQueue;
|
||||||
|
|
||||||
LGThread * frameThread;
|
LGThread * frameThread;
|
||||||
|
LGEvent * frameEvent;
|
||||||
|
atomic_bool invalidateWindow;
|
||||||
bool formatValid;
|
bool formatValid;
|
||||||
atomic_uint_least64_t frameTime;
|
atomic_uint_least64_t frameTime;
|
||||||
uint64_t lastFrameTime;
|
uint64_t lastFrameTime;
|
||||||
|
Loading…
Reference in New Issue
Block a user