Hi On Tue, Mar 3, 2026 at 4:13 AM <[email protected]> wrote: > > 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,
But there is no dpy_gl_ctx_create_texture(), how can dpy_gl_ctx_destroy_texture() get called? > }; > #endif > -- > 2.43.0 > > -- Marc-André Lureau
