[Mesa-dev] [PATCH 7/8] glx: fix the refcounting of dri drawables

Miklós Máté mtmkls at gmail.com
Thu Mar 24 00:13:01 UTC 2016


This fixes premature deallocation on unbind, and introduces
support for deleting GLX drawables while they are current to a context.

Note that in practice this also introduces a resource leak, because nobody
uses the GLX 1.3 glXDestroyWindow and glXDestroyPixmap calls.

This fixes disappearing characters in SW:KotOR when soft shadows are enabled.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93955

Signed-off-by: Miklós Máté <mtmkls at gmail.com>
---
 src/glx/dri_common.c  | 3 ++-
 src/glx/glx_pbuffer.c | 8 ++++++--
 src/glx/glxcmds.c     | 8 ++++++--
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c
index 6728d38..7051fa0 100644
--- a/src/glx/dri_common.c
+++ b/src/glx/dri_common.c
@@ -420,7 +420,8 @@ driFetchDrawable(struct glx_context *gc, GLXDrawable glxDrawable)
       (*pdraw->destroyDrawable) (pdraw);
       return NULL;
    }
-   pdraw->refcount = 1;
+   /* created and bound */
+   pdraw->refcount = 1 + 1;
 
    return pdraw;
 }
diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c
index 231ab20..860c039 100644
--- a/src/glx/glx_pbuffer.c
+++ b/src/glx/glx_pbuffer.c
@@ -217,6 +217,7 @@ CreateDRIDrawable(Display *dpy, struct glx_config *config,
       (*pdraw->destroyDrawable) (pdraw);
       return GL_FALSE;
    }
+   pdraw->refcount = 1;
 
    pdraw->textureTarget = determineTextureTarget(attrib_list, num_attribs);
    pdraw->textureFormat = determineTextureFormat(attrib_list, num_attribs);
@@ -233,8 +234,11 @@ DestroyDRIDrawable(Display *dpy, GLXDrawable drawable, int destroy_xdrawable)
 
    if (priv != NULL && pdraw != NULL) {
       xid = pdraw->xDrawable;
-      (*pdraw->destroyDrawable) (pdraw);
-      __glxHashDelete(priv->drawHash, drawable);
+      pdraw->refcount --;
+      if (pdraw->refcount == 0) {
+         (*pdraw->destroyDrawable) (pdraw);
+         __glxHashDelete(priv->drawHash, drawable);
+      }
       if (destroy_xdrawable)
          XFreePixmap(priv->dpy, xid);
    }
diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
index 93e8db5..ce798c6 100644
--- a/src/glx/glxcmds.c
+++ b/src/glx/glxcmds.c
@@ -753,6 +753,7 @@ glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
          xid = None;
          break;
       }
+      pdraw->refcount = 1;
    } while (0);
 
    if (xid == None) {
@@ -806,8 +807,11 @@ glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap)
       __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap);
 
       if (priv != NULL && pdraw != NULL) {
-         (*pdraw->destroyDrawable) (pdraw);
-         __glxHashDelete(priv->drawHash, glxpixmap);
+         pdraw->refcount --;
+         if (pdraw->refcount == 0) {
+            (*pdraw->destroyDrawable) (pdraw);
+            __glxHashDelete(priv->drawHash, glxpixmap);
+         }
       }
    }
 #endif
-- 
2.8.0.rc3



More information about the mesa-dev mailing list