gl_engine: ++thread safety

The `dispose()` method can be called on a worker thread.
GL resources are released on `sync()`, ensuring guaranteed thread safety.
This commit is contained in:
Hermet Park 2024-07-05 01:01:36 +09:00
parent 45c0e532fb
commit a3c5b0ec2f
2 changed files with 26 additions and 3 deletions

View file

@ -42,6 +42,15 @@ static void _termEngine()
//TODO: Clean up global resources //TODO: Clean up global resources
} }
void GlRenderer::clearDisposes()
{
if (mDisposed.textures.count > 0) {
glDeleteTextures(mDisposed.textures.count, mDisposed.textures.data);
mDisposed.textures.clear();
}
}
/************************************************************************/ /************************************************************************/
/* External Class Implementation */ /* External Class Implementation */
/************************************************************************/ /************************************************************************/
@ -50,8 +59,8 @@ static void _termEngine()
bool GlRenderer::clear() bool GlRenderer::clear()
{ {
//TODO: (Request) to clear target clearDisposes();
// Will be adding glClearColor for input buffer
return true; return true;
} }
@ -113,6 +122,8 @@ bool GlRenderer::sync()
mRenderPassStack.clear(); mRenderPassStack.clear();
clearDisposes();
delete task; delete task;
return true; return true;
@ -385,7 +396,11 @@ void GlRenderer::dispose(RenderData data)
auto sdata = static_cast<GlShape*>(data); auto sdata = static_cast<GlShape*>(data);
if (!sdata) return; if (!sdata) return;
if (sdata->texId) glDeleteTextures(1, &sdata->texId); //dispose the non thread-safety resources on clearDisposes() call
if (sdata->texId) {
ScopedLock lock(mDisposed.key);
mDisposed.textures.push(sdata->texId);
}
delete sdata; delete sdata;
} }

View file

@ -96,6 +96,8 @@ private:
void prepareCmpTask(GlRenderTask* task, const RenderRegion& vp, uint32_t cmpWidth, uint32_t cmpHeight); void prepareCmpTask(GlRenderTask* task, const RenderRegion& vp, uint32_t cmpWidth, uint32_t cmpHeight);
void endRenderPass(Compositor* cmp); void endRenderPass(Compositor* cmp);
void clearDisposes();
Surface surface; Surface surface;
GLint mTargetFboId = 0; GLint mTargetFboId = 0;
RenderRegion mViewport; RenderRegion mViewport;
@ -106,6 +108,12 @@ private:
Array<GlRenderTargetPool*> mComposePool = {}; Array<GlRenderTargetPool*> mComposePool = {};
vector<GlRenderPass> mRenderPassStack = {}; vector<GlRenderPass> mRenderPassStack = {};
vector<unique_ptr<GlCompositor>> mComposeStack = {}; vector<unique_ptr<GlCompositor>> mComposeStack = {};
//Disposed resources. They should be released on synced call.
struct {
Array<GLuint> textures = {};
Key key;
} mDisposed;
}; };
#endif /* _TVG_GL_RENDERER_H_ */ #endif /* _TVG_GL_RENDERER_H_ */