gl_engine: fix memoty leak on target resize
Some checks are pending
Android / build_x86_64 (push) Waiting to run
Android / build_aarch64 (push) Waiting to run
iOS / build_x86_64 (push) Waiting to run
iOS / build_arm64 (push) Waiting to run
macOS / build (push) Waiting to run
macOS / compact_test (push) Waiting to run
macOS / unit_test (push) Waiting to run
Ubuntu / build (push) Waiting to run
Ubuntu / compact_test (push) Waiting to run
Ubuntu / unit_test (push) Waiting to run
Windows / build (push) Waiting to run
Windows / compact_test (push) Waiting to run
Windows / unit_test (push) Waiting to run

We must to remove offscreen render buffers during removing render target

https://github.com/thorvg/thorvg/issues/3210
This commit is contained in:
Sergii Liebodkin 2025-05-22 16:46:57 +03:00 committed by Hermet Park
parent 32c38041db
commit 55847bdcb3
3 changed files with 26 additions and 20 deletions

View file

@ -22,25 +22,18 @@
#include "tvgGlRenderTarget.h" #include "tvgGlRenderTarget.h"
GlRenderTarget::GlRenderTarget(uint32_t width, uint32_t height): mWidth(width), mHeight(height) {} GlRenderTarget::GlRenderTarget() {}
GlRenderTarget::~GlRenderTarget() GlRenderTarget::~GlRenderTarget()
{ {
if (mFbo == 0) return; reset();
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
GL_CHECK(glDeleteFramebuffers(1, &mFbo));
if (mColorTex != 0) {
GL_CHECK(glDeleteTextures(1, &mColorTex));
}
if (mDepthStencilBuffer != 0) {
GL_CHECK(glDeleteRenderbuffers(1, &mDepthStencilBuffer));
}
} }
void GlRenderTarget::init(GLint resolveId) void GlRenderTarget::init(uint32_t width, uint32_t height, GLint resolveId)
{ {
if (mFbo != GL_INVALID_VALUE || mWidth == 0 || mHeight == 0) return; if (mFbo != GL_INVALID_VALUE || width == 0 || height == 0) return;
mWidth = width;
mHeight = height;
//TODO: fbo is used. maybe we can consider the direct rendering with resolveId as well. //TODO: fbo is used. maybe we can consider the direct rendering with resolveId as well.
GL_CHECK(glGenFramebuffers(1, &mFbo)); GL_CHECK(glGenFramebuffers(1, &mFbo));
@ -82,6 +75,18 @@ void GlRenderTarget::init(GLint resolveId)
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, resolveId)); GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, resolveId));
} }
void GlRenderTarget::reset()
{
if (mFbo == 0) return;
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0));
GL_CHECK(glDeleteFramebuffers(1, &mFbo));
GL_CHECK(glDeleteRenderbuffers(1, &mColorBuffer));
GL_CHECK(glDeleteRenderbuffers(1, &mDepthStencilBuffer));
GL_CHECK(glDeleteFramebuffers(1, &mResolveFbo));
GL_CHECK(glDeleteTextures(1, &mColorTex));
mFbo = GL_INVALID_VALUE;
}
GlRenderTargetPool::GlRenderTargetPool(uint32_t maxWidth, uint32_t maxHeight): mMaxWidth(maxWidth), mMaxHeight(maxHeight), mPool() {} GlRenderTargetPool::GlRenderTargetPool(uint32_t maxWidth, uint32_t maxHeight): mMaxWidth(maxWidth), mMaxHeight(maxHeight), mPool() {}
GlRenderTargetPool::~GlRenderTargetPool() GlRenderTargetPool::~GlRenderTargetPool()
@ -125,8 +130,8 @@ GlRenderTarget* GlRenderTargetPool::getRenderTarget(const RenderRegion& vp, GLui
} }
} }
auto rt = new GlRenderTarget(width, height); auto rt = new GlRenderTarget();
rt->init(resolveId); rt->init(width, height, resolveId);
rt->setViewport(vp); rt->setViewport(vp);
mPool.push(rt); mPool.push(rt);
return rt; return rt;

View file

@ -28,11 +28,11 @@
class GlRenderTarget class GlRenderTarget
{ {
public: public:
GlRenderTarget() = default; GlRenderTarget();
GlRenderTarget(uint32_t width, uint32_t height);
~GlRenderTarget(); ~GlRenderTarget();
void init(GLint resolveId); void init(uint32_t width, uint32_t height, GLint resolveId);
void reset();
GLuint getFboId() { return mFbo; } GLuint getFboId() { return mFbo; }
GLuint getResolveFboId() { return mResolveFbo; } GLuint getResolveFboId() { return mResolveFbo; }

View file

@ -52,6 +52,8 @@ void GlRenderer::flush()
{ {
clearDisposes(); clearDisposes();
mRootTarget.reset();
ARRAY_FOREACH(p, mComposePool) delete(*p); ARRAY_FOREACH(p, mComposePool) delete(*p);
mComposePool.clear(); mComposePool.clear();
@ -834,9 +836,8 @@ bool GlRenderer::target(void* context, int32_t id, uint32_t w, uint32_t h)
currentContext(); currentContext();
mRootTarget = GlRenderTarget(surface.w, surface.h);
mRootTarget.setViewport({0, 0, static_cast<int32_t>(surface.w), static_cast<int32_t>(surface.h)}); mRootTarget.setViewport({0, 0, static_cast<int32_t>(surface.w), static_cast<int32_t>(surface.h)});
mRootTarget.init(mTargetFboId); mRootTarget.init(surface.w, surface.h, mTargetFboId);
return true; return true;
} }