diff mbox

v2: dri3: Free resources when drawable is destroyed.

Message ID 1385098619-17099-1-git-send-email-keithp@keithp.com
State Not Applicable
Headers show

Commit Message

Keith Packard Nov. 22, 2013, 5:36 a.m. UTC
Always nice to clean up after ourselves.

Signed-off-by: Keith Packard <keithp@keithp.com>
---

v2: Include changes to dri3_priv.h as well

 src/glx/dri3_glx.c  | 17 ++++++++++++++++-
 src/glx/dri3_priv.h |  5 ++++-
 2 files changed, 20 insertions(+), 2 deletions(-)
diff mbox

Patch

diff --git a/src/glx/dri3_glx.c b/src/glx/dri3_glx.c
index 239d58b..669f0bb 100644
--- a/src/glx/dri3_glx.c
+++ b/src/glx/dri3_glx.c
@@ -266,13 +266,25 @@  dri3_create_context(struct glx_screen *base,
 }
 
 static void
+dri3_free_render_buffer(struct dri3_drawable *pdraw, struct dri3_buffer *buffer);
+
+static void
 dri3_destroy_drawable(__GLXDRIdrawable *base)
 {
    struct dri3_screen *psc = (struct dri3_screen *) base->psc;
    struct dri3_drawable *pdraw = (struct dri3_drawable *) base;
+   xcb_connection_t     *c = XGetXCBConnection(pdraw->base.psc->dpy);
+   int i;
 
    (*psc->core->destroyDrawable) (pdraw->driDrawable);
 
+   for (i = 0; i < DRI3_NUM_BUFFERS; i++) {
+      if (pdraw->buffers[i])
+         dri3_free_render_buffer(pdraw, pdraw->buffers[i]);
+   }
+
+   if (pdraw->special_event)
+      xcb_unregister_for_special_event(c, pdraw->special_event);
    free(pdraw);
 }
 
@@ -736,6 +748,7 @@  dri3_alloc_render_buffer(struct glx_screen *glx_screen, Drawable draw,
                           fence_fd);
 
    buffer->pixmap = pixmap;
+   buffer->own_pixmap = true;
    buffer->sync_fence = sync_fence;
    buffer->shm_fence = shm_fence;
    buffer->width = width;
@@ -769,7 +782,8 @@  dri3_free_render_buffer(struct dri3_drawable *pdraw, struct dri3_buffer *buffer)
    struct dri3_screen   *psc = (struct dri3_screen *) pdraw->base.psc;
    xcb_connection_t     *c = XGetXCBConnection(pdraw->base.psc->dpy);
 
-   xcb_free_pixmap(c, buffer->pixmap);
+   if (buffer->own_pixmap)
+      xcb_free_pixmap(c, buffer->pixmap);
    xcb_sync_destroy_fence(c, buffer->sync_fence);
    xshmfence_unmap_shm(buffer->shm_fence);
    (*psc->image->destroyImage)(buffer->image);
@@ -988,6 +1002,7 @@  dri3_get_pixmap_buffer(__DRIdrawable *driDrawable,
       goto no_image;
 
    buffer->pixmap = pixmap;
+   buffer->own_pixmap = false;
    buffer->width = bp_reply->width;
    buffer->height = bp_reply->height;
    buffer->buffer_type = buffer_type;
diff --git a/src/glx/dri3_priv.h b/src/glx/dri3_priv.h
index 0d21e67..05f66cf 100644
--- a/src/glx/dri3_priv.h
+++ b/src/glx/dri3_priv.h
@@ -89,6 +89,7 @@  struct dri3_buffer {
    uint32_t     sync_fence;     /* XID of X SyncFence object */
    void         *shm_fence;     /* pointer to xshmfence object */
    GLboolean    busy;           /* Set on swap, cleared on IdleNotify */
+   GLboolean    own_pixmap;     /* We allocated the pixmap ID, free on destroy */
    void         *driverPrivate;
 
    uint32_t     size;
@@ -171,6 +172,8 @@  dri3_pixmap_buf_id(enum dri3_buffer_type buffer_type)
       return DRI3_FRONT_ID;
 }
 
+#define DRI3_NUM_BUFFERS        (1 + DRI3_MAX_BACK)
+
 struct dri3_drawable {
    __GLXDRIdrawable base;
    __DRIdrawable *driDrawable;
@@ -194,7 +197,7 @@  struct dri3_drawable {
    uint64_t previous_time;
    unsigned frames;
 
-   struct dri3_buffer *buffers[1 + DRI3_MAX_BACK];
+   struct dri3_buffer *buffers[DRI3_NUM_BUFFERS];
    int cur_back;
    int depth;