mirror of
https://github.com/gnif/LookingGlass.git
synced 2026-08-24 16:11:31 +00:00
[client] opengl: retain deferred frame leases
This commit is contained in:
@@ -100,6 +100,13 @@ struct OpenGL_Options
|
|||||||
bool amdPinnedMem;
|
bool amdPinnedMem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OpenGL_FrameRelease
|
||||||
|
{
|
||||||
|
LG_FrameReleaseFn fn;
|
||||||
|
void * opaque;
|
||||||
|
uint64_t handle;
|
||||||
|
};
|
||||||
|
|
||||||
struct Inst
|
struct Inst
|
||||||
{
|
{
|
||||||
LG_Renderer base;
|
LG_Renderer base;
|
||||||
@@ -127,6 +134,7 @@ struct Inst
|
|||||||
float scaleX, scaleY;
|
float scaleX, scaleY;
|
||||||
const FrameBuffer * frame;
|
const FrameBuffer * frame;
|
||||||
LG_RendererFrameToken pendingFrameToken;
|
LG_RendererFrameToken pendingFrameToken;
|
||||||
|
struct OpenGL_FrameRelease frameRelease;
|
||||||
|
|
||||||
uint64_t drawStart;
|
uint64_t drawStart;
|
||||||
bool hasBuffers;
|
bool hasBuffers;
|
||||||
@@ -179,6 +187,7 @@ enum ConfigStatus
|
|||||||
|
|
||||||
static void deconfigure(struct Inst * this);
|
static void deconfigure(struct Inst * this);
|
||||||
static enum ConfigStatus configure(struct Inst * this);
|
static enum ConfigStatus configure(struct Inst * this);
|
||||||
|
static void releasePendingFrame(struct Inst * this);
|
||||||
static void updateMouseShape(struct Inst * this);
|
static void updateMouseShape(struct Inst * this);
|
||||||
static bool drawFrame(struct Inst * this,
|
static bool drawFrame(struct Inst * this,
|
||||||
LG_RendererFrameToken frameTokenLimit,
|
LG_RendererFrameToken frameTokenLimit,
|
||||||
@@ -203,6 +212,33 @@ static bool swSurfaceEnsureBuffer(struct Inst * this, size_t size)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct OpenGL_FrameRelease takePendingFrameLocked(struct Inst * this)
|
||||||
|
{
|
||||||
|
const struct OpenGL_FrameRelease release = this->frameRelease;
|
||||||
|
|
||||||
|
this->frame = NULL;
|
||||||
|
this->pendingFrameToken = LG_RENDERER_FRAME_TOKEN_NONE;
|
||||||
|
this->frameRelease = (struct OpenGL_FrameRelease) {};
|
||||||
|
atomic_store_explicit(&this->frameUpdate, false, memory_order_release);
|
||||||
|
return release;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void invokeFrameRelease(const struct OpenGL_FrameRelease release)
|
||||||
|
{
|
||||||
|
if (release.fn)
|
||||||
|
release.fn(release.opaque, release.handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void releasePendingFrame(struct Inst * this)
|
||||||
|
{
|
||||||
|
LG_LOCK(this->frameLock);
|
||||||
|
const struct OpenGL_FrameRelease release =
|
||||||
|
takePendingFrameLocked(this);
|
||||||
|
LG_UNLOCK(this->frameLock);
|
||||||
|
|
||||||
|
invokeFrameRelease(release);
|
||||||
|
}
|
||||||
|
|
||||||
const char * opengl_getName(void)
|
const char * opengl_getName(void)
|
||||||
{
|
{
|
||||||
return "OpenGL";
|
return "OpenGL";
|
||||||
@@ -252,6 +288,8 @@ void opengl_deinitialize(LG_Renderer * renderer)
|
|||||||
{
|
{
|
||||||
struct Inst * this = UPCAST(struct Inst, renderer);
|
struct Inst * this = UPCAST(struct Inst, renderer);
|
||||||
|
|
||||||
|
releasePendingFrame(this);
|
||||||
|
|
||||||
if (this->renderStarted)
|
if (this->renderStarted)
|
||||||
{
|
{
|
||||||
ImGui_ImplOpenGL2_Shutdown();
|
ImGui_ImplOpenGL2_Shutdown();
|
||||||
@@ -290,7 +328,8 @@ void opengl_deinitialize(LG_Renderer * renderer)
|
|||||||
|
|
||||||
void opengl_onRestart(LG_Renderer * renderer)
|
void opengl_onRestart(LG_Renderer * renderer)
|
||||||
{
|
{
|
||||||
// struct Inst * this = UPCAST(struct Inst, renderer);
|
struct Inst * this = UPCAST(struct Inst, renderer);
|
||||||
|
releasePendingFrame(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setupModelView(struct Inst * this)
|
static void setupModelView(struct Inst * this)
|
||||||
@@ -449,20 +488,25 @@ bool opengl_onFrame(LG_Renderer * renderer, const FrameBuffer * frame, int dmaFd
|
|||||||
{
|
{
|
||||||
struct Inst * this = UPCAST(struct Inst, renderer);
|
struct Inst * this = UPCAST(struct Inst, renderer);
|
||||||
|
|
||||||
/* The legacy renderer retains the shared framebuffer until render. It does
|
/* The legacy renderer supports only deferred CPU reads. */
|
||||||
* not support asynchronous DMA ownership. */
|
if (!frame || dmaFd >= 0)
|
||||||
if (releaseFn)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
(void)releaseOpaque;
|
|
||||||
(void)releaseHandle;
|
|
||||||
|
|
||||||
LG_LOCK(this->frameLock);
|
LG_LOCK(this->frameLock);
|
||||||
|
const struct OpenGL_FrameRelease oldRelease =
|
||||||
|
takePendingFrameLocked(this);
|
||||||
this->frame = frame;
|
this->frame = frame;
|
||||||
this->pendingFrameToken = frameToken;
|
this->pendingFrameToken = frameToken;
|
||||||
|
this->frameRelease = (struct OpenGL_FrameRelease)
|
||||||
|
{
|
||||||
|
.fn = releaseFn,
|
||||||
|
.opaque = releaseOpaque,
|
||||||
|
.handle = releaseHandle,
|
||||||
|
};
|
||||||
atomic_store_explicit(&this->frameUpdate, true, memory_order_release);
|
atomic_store_explicit(&this->frameUpdate, true, memory_order_release);
|
||||||
LG_UNLOCK(this->frameLock);
|
LG_UNLOCK(this->frameLock);
|
||||||
|
|
||||||
|
invokeFrameRelease(oldRelease);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1327,8 +1371,10 @@ static bool drawFrame(struct Inst * this,
|
|||||||
LG_UNLOCK(this->frameLock);
|
LG_UNLOCK(this->frameLock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
atomic_store_explicit(&this->frameUpdate, false, memory_order_release);
|
const FrameBuffer * frame = this->frame;
|
||||||
const LG_RendererFrameToken pendingFrameToken = this->pendingFrameToken;
|
const LG_RendererFrameToken pendingFrameToken = this->pendingFrameToken;
|
||||||
|
const struct OpenGL_FrameRelease release =
|
||||||
|
takePendingFrameLocked(this);
|
||||||
|
|
||||||
LG_LOCK(this->formatLock);
|
LG_LOCK(this->formatLock);
|
||||||
glBindTexture(GL_TEXTURE_2D, this->frames[this->texWIndex]);
|
glBindTexture(GL_TEXTURE_2D, this->frames[this->texWIndex]);
|
||||||
@@ -1340,7 +1386,7 @@ static bool drawFrame(struct Inst * this,
|
|||||||
|
|
||||||
this->texPos = 0;
|
this->texPos = 0;
|
||||||
framebuffer_read_fn(
|
framebuffer_read_fn(
|
||||||
this->frame,
|
frame,
|
||||||
this->format.dataHeight,
|
this->format.dataHeight,
|
||||||
this->format.dataWidth,
|
this->format.dataWidth,
|
||||||
bpp,
|
bpp,
|
||||||
@@ -1406,6 +1452,7 @@ static bool drawFrame(struct Inst * this,
|
|||||||
glFlush();
|
glFlush();
|
||||||
|
|
||||||
LG_UNLOCK(this->formatLock);
|
LG_UNLOCK(this->formatLock);
|
||||||
|
invokeFrameRelease(release);
|
||||||
this->texReady = true;
|
this->texReady = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1622,7 +1622,7 @@ int main_frameThread(void * unused)
|
|||||||
g_state.frameImportTime = 0;
|
g_state.frameImportTime = 0;
|
||||||
g_state.frameImportWaitTime = 0;
|
g_state.frameImportWaitTime = 0;
|
||||||
|
|
||||||
const bool rendererOwnsFrame = frame.dmaFD >= 0 && frame.releaseFn;
|
const bool rendererOwnsFrame = frame.releaseFn != NULL;
|
||||||
if (!RENDERER(onFrame, frame.framebuffer, frame.dmaFD,
|
if (!RENDERER(onFrame, frame.framebuffer, frame.dmaFD,
|
||||||
frame.damageRects, damageCount, frameToken,
|
frame.damageRects, damageCount, frameToken,
|
||||||
rendererOwnsFrame ? frame.releaseFn : NULL,
|
rendererOwnsFrame ? frame.releaseFn : NULL,
|
||||||
@@ -1638,7 +1638,7 @@ int main_frameThread(void * unused)
|
|||||||
primaryWorkerFailed();
|
primaryWorkerFailed();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* A DMA snapshot can complete on the render thread immediately after it
|
/* A leased frame can complete on the render thread immediately after it
|
||||||
* is signalled below, so sample producer timing while this lease is still
|
* is signalled below, so sample producer timing while this lease is still
|
||||||
* unambiguously owned by the frame thread. */
|
* unambiguously owned by the frame thread. */
|
||||||
LG_TransportFrameTiming timing = {};
|
LG_TransportFrameTiming timing = {};
|
||||||
|
|||||||
Reference in New Issue
Block a user