dri3: Free resources when drawable is destroyed.
authorKeith Packard <keithp@keithp.com>
Fri, 22 Nov 2013 05:30:07 +0000 (21:30 -0800)
committerKenneth Graunke <kenneth@whitecape.org>
Sat, 21 Dec 2013 00:17:59 +0000 (16:17 -0800)
Always nice to clean up after ourselves.

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/glx/dri3_glx.c
src/glx/dri3_priv.h

index 1834c6d4a8e933695e7a6b608e2c367aac8c91b2..4c0dc29fdf847489bbe2b6ab3e7a06beaf5a9963 100644 (file)
@@ -265,14 +265,26 @@ dri3_create_context(struct glx_screen *base,
                                       0, NULL, &error);
 }
 
+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);
@@ -987,6 +1001,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;
index efdc2ae2d2f6abda3a63cf49fc31716785ae43fe..eb81ce7bdb1558592cc4e2c881113ae9234e0e83 100644 (file)
@@ -89,6 +89,7 @@ struct dri3_buffer {
    uint32_t     sync_fence;     /* XID of X SyncFence object */
    struct xshmfence *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;