mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-03 08:08:43 +00:00
LibGfx: Free WebGL painting surface resources on resize
If a WebGL canvas is resized through the set_size function, we will re-create the painting surface. However, this currently leaks all of the associated EGL/OpenGL objects. This change introduces the free_surface_resources function which will free all resources associated with the painting surface. It will be called before allocating a new surface and during context destruction. It keeps track of the OpenGL texture for the color buffer in m_impl instead of just storing it on the stack.
This commit is contained in:
parent
41f1e920d8
commit
df09472d4d
Notes:
github-actions[bot]
2025-08-18 22:31:44 +00:00
Author: https://github.com/erik-kz
Commit: df09472d4d
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5864
Reviewed-by: https://github.com/kalenikaliaksandr ✅
2 changed files with 36 additions and 8 deletions
|
@ -35,6 +35,7 @@ struct OpenGLContext::Impl {
|
||||||
EGLSurface surface { nullptr };
|
EGLSurface surface { nullptr };
|
||||||
|
|
||||||
GLuint framebuffer { 0 };
|
GLuint framebuffer { 0 };
|
||||||
|
GLuint color_buffer { 0 };
|
||||||
GLuint depth_buffer { 0 };
|
GLuint depth_buffer { 0 };
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
@ -49,15 +50,38 @@ OpenGLContext::OpenGLContext(NonnullRefPtr<Gfx::SkiaBackendContext> skia_backend
|
||||||
OpenGLContext::~OpenGLContext()
|
OpenGLContext::~OpenGLContext()
|
||||||
{
|
{
|
||||||
#ifdef AK_OS_MACOS
|
#ifdef AK_OS_MACOS
|
||||||
|
free_surface_resources();
|
||||||
eglMakeCurrent(m_impl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
eglMakeCurrent(m_impl->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
|
||||||
glDeleteFramebuffers(1, &m_impl->framebuffer);
|
|
||||||
glDeleteRenderbuffers(1, &m_impl->depth_buffer);
|
|
||||||
eglDestroyContext(m_impl->display, m_impl->context);
|
eglDestroyContext(m_impl->display, m_impl->context);
|
||||||
eglReleaseTexImage(m_impl->display, m_impl->surface, EGL_BACK_BUFFER);
|
|
||||||
eglDestroySurface(m_impl->display, m_impl->surface);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef AK_OS_MACOS
|
||||||
|
void OpenGLContext::free_surface_resources()
|
||||||
|
{
|
||||||
|
if (m_impl->framebuffer) {
|
||||||
|
glDeleteFramebuffers(1, &m_impl->framebuffer);
|
||||||
|
m_impl->framebuffer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_impl->color_buffer) {
|
||||||
|
glDeleteTextures(1, &m_impl->color_buffer);
|
||||||
|
m_impl->color_buffer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_impl->depth_buffer) {
|
||||||
|
glDeleteRenderbuffers(1, &m_impl->depth_buffer);
|
||||||
|
m_impl->depth_buffer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_impl->surface != EGL_NO_SURFACE) {
|
||||||
|
eglReleaseTexImage(m_impl->display, m_impl->surface, EGL_BACK_BUFFER);
|
||||||
|
eglDestroySurface(m_impl->display, m_impl->surface);
|
||||||
|
m_impl->surface = EGL_NO_SURFACE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef AK_OS_MACOS
|
#ifdef AK_OS_MACOS
|
||||||
static EGLConfig get_egl_config(EGLDisplay display)
|
static EGLConfig get_egl_config(EGLDisplay display)
|
||||||
{
|
{
|
||||||
|
@ -174,6 +198,7 @@ void OpenGLContext::allocate_painting_surface_if_needed()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
VERIFY(!m_size.is_empty());
|
VERIFY(!m_size.is_empty());
|
||||||
|
free_surface_resources();
|
||||||
|
|
||||||
auto iosurface = Core::IOSurfaceHandle::create(m_size.width(), m_size.height());
|
auto iosurface = Core::IOSurfaceHandle::create(m_size.width(), m_size.height());
|
||||||
|
|
||||||
|
@ -212,15 +237,14 @@ void OpenGLContext::allocate_painting_surface_if_needed()
|
||||||
eglGetConfigAttrib(display, config, EGL_BIND_TO_TEXTURE_TARGET_ANGLE, &texture_target_name);
|
eglGetConfigAttrib(display, config, EGL_BIND_TO_TEXTURE_TARGET_ANGLE, &texture_target_name);
|
||||||
VERIFY(texture_target_name == EGL_TEXTURE_RECTANGLE_ANGLE || texture_target_name == EGL_TEXTURE_2D);
|
VERIFY(texture_target_name == EGL_TEXTURE_RECTANGLE_ANGLE || texture_target_name == EGL_TEXTURE_2D);
|
||||||
|
|
||||||
GLuint texture = 0;
|
glGenTextures(1, &m_impl->color_buffer);
|
||||||
glGenTextures(1, &texture);
|
glBindTexture(texture_target_name == EGL_TEXTURE_RECTANGLE_ANGLE ? GL_TEXTURE_RECTANGLE_ANGLE : GL_TEXTURE_2D, m_impl->color_buffer);
|
||||||
glBindTexture(texture_target_name == EGL_TEXTURE_RECTANGLE_ANGLE ? GL_TEXTURE_RECTANGLE_ANGLE : GL_TEXTURE_2D, texture);
|
|
||||||
auto result = eglBindTexImage(display, m_impl->surface, EGL_BACK_BUFFER);
|
auto result = eglBindTexImage(display, m_impl->surface, EGL_BACK_BUFFER);
|
||||||
VERIFY(result == EGL_TRUE);
|
VERIFY(result == EGL_TRUE);
|
||||||
|
|
||||||
glGenFramebuffers(1, &m_impl->framebuffer);
|
glGenFramebuffers(1, &m_impl->framebuffer);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_impl->framebuffer);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_impl->framebuffer);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target_name == EGL_TEXTURE_RECTANGLE_ANGLE ? GL_TEXTURE_RECTANGLE_ANGLE : GL_TEXTURE_2D, texture, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texture_target_name == EGL_TEXTURE_RECTANGLE_ANGLE ? GL_TEXTURE_RECTANGLE_ANGLE : GL_TEXTURE_2D, m_impl->color_buffer, 0);
|
||||||
|
|
||||||
// NOTE: ANGLE doesn't allocate depth buffer for us, so we need to do it manually
|
// NOTE: ANGLE doesn't allocate depth buffer for us, so we need to do it manually
|
||||||
// FIXME: Depth buffer only needs to be allocated if it's configured in WebGL context attributes
|
// FIXME: Depth buffer only needs to be allocated if it's configured in WebGL context attributes
|
||||||
|
|
|
@ -50,6 +50,10 @@ private:
|
||||||
NonnullOwnPtr<Impl> m_impl;
|
NonnullOwnPtr<Impl> m_impl;
|
||||||
Optional<Vector<String>> m_requestable_extensions;
|
Optional<Vector<String>> m_requestable_extensions;
|
||||||
WebGLVersion m_webgl_version;
|
WebGLVersion m_webgl_version;
|
||||||
|
|
||||||
|
#ifdef AK_OS_MACOS
|
||||||
|
void free_surface_resources();
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue