From: Dongwon Kim <[email protected]>

Currently, the texture associated with a DisplaySurface is not deleted
when the surface is switched or freed, leading to a memory leak in the
GPU process. This occurs because the GTK backend lacks a mapping for the
'dpy_gl_ctx_destroy_texture' operation.

This patch implements the necessary cleanup functions for both EGL and
GL Area backends. Each implementation ensures the appropriate GL context
is made current before calling surface_gl_destroy_texture(), ensuring
that the underlying GL texture ID is safely released by the driver.

Cc: Gerd Hoffmann <[email protected]>
Cc: Marc-André Lureau <[email protected]>
Cc: Vivek Kasireddy <[email protected]>
Signed-off-by: Dongwon Kim <[email protected]>
---
 include/ui/gtk.h |  4 ++++
 ui/gtk-egl.c     | 10 ++++++++++
 ui/gtk-gl-area.c |  8 ++++++++
 ui/gtk.c         |  2 ++
 4 files changed, 24 insertions(+)

diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index 3e6ce3cb48..f1765ad5cb 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -170,6 +170,8 @@ void gd_egl_switch(DisplayChangeListener *dcl,
                    DisplaySurface *surface);
 QEMUGLContext gd_egl_create_context(DisplayGLCtx *dgc,
                                     QEMUGLParams *params);
+void gd_egl_destroy_texture(DisplayGLCtx *dgc,
+                            DisplaySurface *surface);
 void gd_egl_scanout_disable(DisplayChangeListener *dcl);
 void gd_egl_scanout_texture(DisplayChangeListener *dcl,
                             uint32_t backing_id,
@@ -206,6 +208,8 @@ QEMUGLContext gd_gl_area_create_context(DisplayGLCtx *dgc,
                                         QEMUGLParams *params);
 void gd_gl_area_destroy_context(DisplayGLCtx *dgc,
                                 QEMUGLContext ctx);
+void gd_gl_area_destroy_texture(DisplayGLCtx *dgc,
+                                DisplaySurface *surface);
 void gd_gl_area_scanout_dmabuf(DisplayChangeListener *dcl,
                                QemuDmaBuf *dmabuf);
 void gd_gl_area_scanout_texture(DisplayChangeListener *dcl,
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index ae9239999c..c1b32bc41b 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -225,6 +225,16 @@ QEMUGLContext gd_egl_create_context(DisplayGLCtx *dgc,
     return qemu_egl_create_context(dgc, params);
 }
 
+void gd_egl_destroy_texture(DisplayGLCtx *dgc, DisplaySurface *surface)
+{
+    VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc);
+
+    eglMakeCurrent(qemu_egl_display, vc->gfx.esurface,
+                   vc->gfx.esurface, vc->gfx.ectx);
+
+    surface_gl_destroy_texture(dgc->gls, surface);
+}
+
 void gd_egl_scanout_disable(DisplayChangeListener *dcl)
 {
     VirtualConsole *vc = container_of(dcl, VirtualConsole, gfx.dcl);
diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index cd86022d26..84e41f4221 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -299,6 +299,14 @@ void gd_gl_area_destroy_context(DisplayGLCtx *dgc, 
QEMUGLContext ctx)
     g_clear_object(&ctx);
 }
 
+void gd_gl_area_destroy_texture(DisplayGLCtx *dgc, DisplaySurface *surface)
+{
+    VirtualConsole *vc = container_of(dgc, VirtualConsole, gfx.dgc);
+
+    gtk_gl_area_make_current(GTK_GL_AREA(vc->gfx.drawing_area));
+    surface_gl_destroy_texture(dgc->gls, surface);
+}
+
 void gd_gl_area_scanout_texture(DisplayChangeListener *dcl,
                                 uint32_t backing_id,
                                 bool backing_y_0_top,
diff --git a/ui/gtk.c b/ui/gtk.c
index 9ebe7e8df0..217f425075 100644
--- a/ui/gtk.c
+++ b/ui/gtk.c
@@ -636,6 +636,7 @@ static const DisplayGLCtxOps gl_area_ctx_ops = {
     .dpy_gl_ctx_is_compatible_dcl = gd_gl_area_is_compatible_dcl,
     .dpy_gl_ctx_create       = gd_gl_area_create_context,
     .dpy_gl_ctx_destroy      = gd_gl_area_destroy_context,
+    .dpy_gl_ctx_destroy_texture = gd_gl_area_destroy_texture,
     .dpy_gl_ctx_make_current = gd_gl_area_make_current,
 };
 
@@ -670,6 +671,7 @@ static const DisplayGLCtxOps egl_ctx_ops = {
     .dpy_gl_ctx_is_compatible_dcl = gd_egl_is_compatible_dcl,
     .dpy_gl_ctx_create       = gd_egl_create_context,
     .dpy_gl_ctx_destroy      = qemu_egl_destroy_context,
+    .dpy_gl_ctx_destroy_texture = gd_egl_destroy_texture,
     .dpy_gl_ctx_make_current = gd_egl_make_current,
 };
 #endif
-- 
2.43.0


Reply via email to