mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-11-25 14:57:20 +00:00
[client] egl: use a lock for desktop damage to eliminate all races
There used to be a possible race when a bunch of rectangle is appended, but the total count is not updated before it's read. Using a lock eliminates all such races.
This commit is contained in:
parent
f08e2ece93
commit
23c77e8508
@ -104,7 +104,8 @@ struct Inst
|
|||||||
|
|
||||||
bool hadOverlay;
|
bool hadOverlay;
|
||||||
struct DesktopDamage desktopDamage[DESKTOP_DAMAGE_COUNT];
|
struct DesktopDamage desktopDamage[DESKTOP_DAMAGE_COUNT];
|
||||||
atomic_uint desktopDamageIdx;
|
unsigned int desktopDamageIdx;
|
||||||
|
LG_Lock desktopDamageLock;
|
||||||
|
|
||||||
RingBuffer importTimings;
|
RingBuffer importTimings;
|
||||||
GraphHandle importGraph;
|
GraphHandle importGraph;
|
||||||
@ -182,16 +183,6 @@ static void egl_setup(void)
|
|||||||
option_register(egl_options);
|
option_register(egl_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static struct DesktopDamage * currentDesktopDamage(struct Inst * this)
|
|
||||||
{
|
|
||||||
return this->desktopDamage + atomic_load(&this->desktopDamageIdx) % DESKTOP_DAMAGE_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline static struct DesktopDamage * finishDesktopDamage(struct Inst * this)
|
|
||||||
{
|
|
||||||
return this->desktopDamage + atomic_fetch_add(&this->desktopDamageIdx, 1) % DESKTOP_DAMAGE_COUNT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool egl_create(void ** opaque, const LG_RendererParams params, bool * needsOpenGL)
|
static bool egl_create(void ** opaque, const LG_RendererParams params, bool * needsOpenGL)
|
||||||
{
|
{
|
||||||
// check if EGL is even available
|
// check if EGL is even available
|
||||||
@ -221,7 +212,7 @@ static bool egl_create(void ** opaque, const LG_RendererParams params, bool * ne
|
|||||||
this->screenScaleY = 1.0f;
|
this->screenScaleY = 1.0f;
|
||||||
this->uiScale = 1.0;
|
this->uiScale = 1.0;
|
||||||
|
|
||||||
atomic_init(&this->desktopDamageIdx, 0);
|
LG_LOCK_INIT(this->desktopDamageLock);
|
||||||
this->desktopDamage[0].count = -1;
|
this->desktopDamage[0].count = -1;
|
||||||
|
|
||||||
this->importTimings = ringbuffer_new(256, sizeof(float));
|
this->importTimings = ringbuffer_new(256, sizeof(float));
|
||||||
@ -254,6 +245,7 @@ static void egl_deinitialize(void * opaque)
|
|||||||
egl_damage_free (&this->damage);
|
egl_damage_free (&this->damage);
|
||||||
|
|
||||||
LG_LOCK_FREE(this->lock);
|
LG_LOCK_FREE(this->lock);
|
||||||
|
LG_LOCK_FREE(this->desktopDamageLock);
|
||||||
|
|
||||||
eglMakeCurrent(this->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
eglMakeCurrent(this->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
|
|
||||||
@ -432,7 +424,9 @@ static void egl_on_resize(void * opaque, const int width, const int height, cons
|
|||||||
|
|
||||||
egl_calc_mouse_state(this);
|
egl_calc_mouse_state(this);
|
||||||
|
|
||||||
currentDesktopDamage(this)->count = -1;
|
INTERLOCKED_SECTION(this->desktopDamageLock, {
|
||||||
|
this->desktopDamage[this->desktopDamageIdx].count = -1;
|
||||||
|
});
|
||||||
|
|
||||||
// this is needed to refresh the font atlas texture
|
// this is needed to refresh the font atlas texture
|
||||||
ImGui_ImplOpenGL3_Shutdown();
|
ImGui_ImplOpenGL3_Shutdown();
|
||||||
@ -518,14 +512,16 @@ static bool egl_on_frame(void * opaque, const FrameBuffer * frame, int dmaFd,
|
|||||||
|
|
||||||
this->start = true;
|
this->start = true;
|
||||||
|
|
||||||
struct DesktopDamage * damage = currentDesktopDamage(this);
|
INTERLOCKED_SECTION(this->desktopDamageLock, {
|
||||||
if (damage->count == -1 || damage->count + damageRectsCount >= KVMFR_MAX_DAMAGE_RECTS)
|
struct DesktopDamage * damage = this->desktopDamage + this->desktopDamageIdx;
|
||||||
damage->count = -1;
|
if (damage->count == -1 || damage->count + damageRectsCount >= KVMFR_MAX_DAMAGE_RECTS)
|
||||||
else
|
damage->count = -1;
|
||||||
{
|
else
|
||||||
memcpy(damage->rects + damage->count, damageRects, damageRectsCount * sizeof(FrameDamageRect));
|
{
|
||||||
damage->count += damageRectsCount;
|
memcpy(damage->rects + damage->count, damageRects, damageRectsCount * sizeof(FrameDamageRect));
|
||||||
}
|
damage->count += damageRectsCount;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -821,7 +817,12 @@ static bool egl_render(void * opaque, LG_RendererRotate rotate, const bool newFr
|
|||||||
|
|
||||||
bool hasOverlay = false;
|
bool hasOverlay = false;
|
||||||
struct CursorState cursorState = { .visible = false };
|
struct CursorState cursorState = { .visible = false };
|
||||||
struct DesktopDamage * desktopDamage = finishDesktopDamage(this);
|
struct DesktopDamage * desktopDamage;
|
||||||
|
|
||||||
|
INTERLOCKED_SECTION(this->desktopDamageLock, {
|
||||||
|
desktopDamage = this->desktopDamage + this->desktopDamageIdx;
|
||||||
|
this->desktopDamageIdx = (this->desktopDamageIdx + 1) % DESKTOP_DAMAGE_COUNT;
|
||||||
|
});
|
||||||
|
|
||||||
if (this->start)
|
if (this->start)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user