Re: [Mesa-dev] [PATCH] glx: implement drawable refcounting.

2011-06-17 Thread Adam Jackson

On 6/15/11 6:22 PM, Stéphane Marchesin wrote:

The current dri context unbind logic will leak drawables until the process
dies (they will then get released by the GEM code). There are two ways to fix
this: either always call driReleaseDrawables every time we unbind a context
(but that costs us round trips to the X server at getbuffers() time) or
implement proper drawable refcounting. This patch implements the latter.

Signed-off-by: Antoine Labourpi...@chromium.org
Signed-off-by: Stéphane Marchesinmarc...@chromium.org


Reviewed-by: Adam Jackson a...@redhat.com

- ajax
___
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev


[Mesa-dev] [PATCH] glx: implement drawable refcounting.

2011-06-15 Thread Stéphane Marchesin
The current dri context unbind logic will leak drawables until the process
dies (they will then get released by the GEM code). There are two ways to fix
this: either always call driReleaseDrawables every time we unbind a context
(but that costs us round trips to the X server at getbuffers() time) or
implement proper drawable refcounting. This patch implements the latter.

Signed-off-by: Antoine Labour pi...@chromium.org
Signed-off-by: Stéphane Marchesin marc...@chromium.org
---
 src/glx/dri2_glx.c   |5 ++---
 src/glx/dri_common.c |   26 +++---
 src/glx/dri_glx.c|6 --
 src/glx/drisw_glx.c  |6 --
 src/glx/glxclient.h  |1 +
 src/glx/glxcurrent.c |   14 +++---
 6 files changed, 37 insertions(+), 21 deletions(-)

diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index 506754c..e7c18ff 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -143,6 +143,8 @@ dri2_bind_context(struct glx_context *context, struct 
glx_context *old,
pdraw = (struct dri2_drawable *) driFetchDrawable(context, draw);
pread = (struct dri2_drawable *) driFetchDrawable(context, read);
 
+   driReleaseDrawables(pcp-base);
+
if (pdraw == NULL || pread == NULL)
   return GLXBadDrawable;
 
@@ -170,9 +172,6 @@ dri2_unbind_context(struct glx_context *context, struct 
glx_context *new)
struct dri2_screen *psc = (struct dri2_screen *) pcp-base.psc;
 
(*psc-core-unbindContext) (pcp-driContext);
-
-   if (context == new)
-  driReleaseDrawables(pcp-base);
 }
 
 static struct glx_context *
diff --git a/src/glx/dri_common.c b/src/glx/dri_common.c
index 06a73e4..bac0c9e 100644
--- a/src/glx/dri_common.c
+++ b/src/glx/dri_common.c
@@ -369,8 +369,10 @@ driFetchDrawable(struct glx_context *gc, GLXDrawable 
glxDrawable)
if (priv-drawHash == NULL)
   return NULL;
 
-   if (__glxHashLookup(priv-drawHash, glxDrawable, (void *) pdraw) == 0)
+   if (__glxHashLookup(priv-drawHash, glxDrawable, (void *) pdraw) == 0) {
+  pdraw-refcount ++;
   return pdraw;
+   }
 
pdraw = psc-driScreen-createDrawable(psc, glxDrawable,
   glxDrawable, gc-config);
@@ -378,6 +380,7 @@ driFetchDrawable(struct glx_context *gc, GLXDrawable 
glxDrawable)
   (*pdraw-destroyDrawable) (pdraw);
   return NULL;
}
+   pdraw-refcount = 1;
 
return pdraw;
 }
@@ -394,19 +397,28 @@ driReleaseDrawables(struct glx_context *gc)
if (__glxHashLookup(priv-drawHash,
   gc-currentDrawable, (void *) pdraw) == 0) {
   if (pdraw-drawable == pdraw-xDrawable) {
-(*pdraw-destroyDrawable)(pdraw);
-__glxHashDelete(priv-drawHash, gc-currentDrawable);
+pdraw-refcount --;
+if (pdraw-refcount == 0) {
+   (*pdraw-destroyDrawable)(pdraw);
+   __glxHashDelete(priv-drawHash, gc-currentDrawable);
+}
   }
}
 
-   if (gc-currentDrawable != gc-currentReadable 
-   __glxHashLookup(priv-drawHash,
+   if (__glxHashLookup(priv-drawHash,
   gc-currentReadable, (void *) pdraw) == 0) {
   if (pdraw-drawable == pdraw-xDrawable) {
-(*pdraw-destroyDrawable)(pdraw);
-__glxHashDelete(priv-drawHash, gc-currentReadable);
+pdraw-refcount --;
+if (pdraw-refcount == 0) {
+   (*pdraw-destroyDrawable)(pdraw);
+   __glxHashDelete(priv-drawHash, gc-currentReadable);
+}
   }
}
+
+   gc-currentDrawable = None;
+   gc-currentReadable = None;
+
 }
 
 #endif /* GLX_DIRECT_RENDERING */
diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c
index ff027dc..d59784c 100644
--- a/src/glx/dri_glx.c
+++ b/src/glx/dri_glx.c
@@ -503,6 +503,8 @@ dri_destroy_context(struct glx_context * context)
struct dri_context *pcp = (struct dri_context *) context;
struct dri_screen *psc = (struct dri_screen *) context-psc;
 
+   driReleaseDrawables(pcp-base);
+
if (context-xid)
   glx_send_destroy_context(psc-base.dpy, context-xid);
 
@@ -526,6 +528,8 @@ dri_bind_context(struct glx_context *context, struct 
glx_context *old,
pdraw = (struct dri_drawable *) driFetchDrawable(context, draw);
pread = (struct dri_drawable *) driFetchDrawable(context, read);
 
+   driReleaseDrawables(pcp-base);
+
if (pdraw == NULL || pread == NULL)
   return GLXBadDrawable;
 
@@ -543,8 +547,6 @@ dri_unbind_context(struct glx_context *context, struct 
glx_context *new)
struct dri_screen *psc = (struct dri_screen *) pcp-base.psc;
 
(*psc-core-unbindContext) (pcp-driContext);
-
-   driReleaseDrawables(pcp-base);
 }
 
 static const struct glx_context_vtable dri_context_vtable = {
diff --git a/src/glx/drisw_glx.c b/src/glx/drisw_glx.c
index 2eaa3c5..0075695 100644
--- a/src/glx/drisw_glx.c
+++ b/src/glx/drisw_glx.c
@@ -242,6 +242,8 @@ drisw_destroy_context(struct glx_context *context)
struct drisw_context *pcp = (struct drisw_context *) context;
struct drisw_screen *psc = (struct drisw_screen *) context-psc;
 
+