VirtGL: Fix memory leak in eglDestroyPixmap
authorFrédéric Dalleau <frederic.dalleau@linux.intel.com>
Mon, 8 Jul 2013 15:32:39 +0000 (17:32 +0200)
committerjinhyung.jo <jinhyung.jo@samsung.com>
Wed, 11 Sep 2013 09:04:30 +0000 (18:04 +0900)
The code in qemu for glXDestroyPixmap make some verifications that fails :
if ( qsurface &&
     qsurface != process->current_state->current_qsurface &&
     qsurface->glstate == NULL &&
     qsurface->type == SURFACE_PIXMAP)
    /* free  image data */

We can see that before freeing surface : qemu checks that it is pixmap, it is
not current and it is not bound.

I added some traces and this is a sample from output :
[trace:qemu:opengl][2225]> glXDestroyPixmap
[trace:qemu:opengl]glXDestroyPixmap: 0x7f6898fff150
[trace:qemu:opengl]process->current_state->current_qsurface: (nil)
[trace:qemu:opengl]qsurface->glstate: 0x7f689801eef0
[trace:qemu:opengl]qsurface->type: 1, SURFACE_PIXMAP: 1
[trace:qemu:opengl]process->current_state: 0x1627680, qsurface->glstate:
0x7f689801eef0

We can interpret this as : the application requested to free the surface, but
it was still bound in the context.

The two following reasons suggest to resolve the leak by forcing unbinding the
image from qemu.
* Having a destroyed image in a context doesn't really make sense,
* In this use case it is likely that the context will be destroyed soon after
the pixmap.

tizen/src/hw/opengl_exec.c

index 3518cafd497f16545a9a4319352ee8477d00105f..b28077cfd405f540ff62040cb885dc22346ed308 100644 (file)
@@ -2105,6 +2105,10 @@ int do_function_call(ProcessState *process, int func_number, unsigned long *args
             /* glXPixmap same as input Pixmap */
             ClientGLXDrawable client_drawable = to_drawable(args[1]);
             QGloSurface *qsurface = find_qsurface_from_client_drawable(process, client_drawable);
+            if (qsurface->glstate != NULL) {
+                unbind_qsurface(qsurface->glstate, qsurface);
+            }
+
             if ( qsurface &&
                  qsurface != process->current_state->current_qsurface &&
                  qsurface->glstate == NULL &&