[Libva] [PATCH 1/1] vaDetsroyDrawable to avoid a problem with internal X-drawable access

gimli gimli at dark-green.com
Fri Jul 8 03:29:42 PDT 2011


vaDetsroyDrawable is introduced to free internal allocated dri_drawable.

vaPustSurface is requesting a dri drawable through dri_get_drawable for the
provided X-Drawable.
libva stores all drawables it sees from the application. On closing it trys
to destroy all drawables, 
even if the application already destroyed the drawable. This leads to the
following error :

X Error of failed request:  BadDrawable (invalid Pixmap or Window
parameter)
Major opcode of failed request:  137 (DRI2)
Minor opcode of failed request:  4 (DRI2DestroyDrawable)
Resource id in failed request:  0x400032d
Serial number of failed request:  2629
Current serial number in output stream:  2630

vaDetsroyDrawable gives the application the chance to free the drawable and
it's allocated resources.

Signed-off-by: Edgar Hucek <gimli at dark-green.com>
-------------- next part --------------
diff --git a/va/va_x11.h b/va/va_x11.h
index c6f9670..c834b76 100644
--- a/va/va_x11.h
+++ b/va/va_x11.h
@@ -16,6 +16,14 @@ VADisplay vaGetDisplay (
 );
 
 /*
+ * Destroy the allocated drawable.
+ */
+VAStatus vaDetsroyDrawable (
+    VADisplay dpy,
+    Drawable draw /* X Drawable */
+);
+
+/*
  * Output rendering
  * Following is the rendering interface for X windows, 
  * to get the decode output surface to a X drawable
diff --git a/va/x11/va_x11.c b/va/x11/va_x11.c
index 947b5b1..98b55ee 100644
--- a/va/x11/va_x11.c
+++ b/va/x11/va_x11.c
@@ -208,6 +208,35 @@ VADisplay vaGetDisplay (
 #define CTX(dpy) (((VADisplayContextP)dpy)->pDriverContext)
 #define CHECK_DISPLAY(dpy) if( !vaDisplayIsValid(dpy) ) { return VA_STATUS_ERROR_INVALID_DISPLAY; }
 
+#include <stdio.h>
+VAStatus vaDetsroyDrawable (
+    VADisplay dpy,
+    Drawable draw /* X Drawable */
+)
+{
+  VADriverContextP ctx;
+
+  CHECK_DISPLAY(dpy);
+  ctx = CTX(dpy);
+
+  struct dri_state *dri_state = (struct dri_state *)ctx->dri_state;
+  int i = 0;
+  struct dri_drawable *dri_drawable;
+
+  assert (dri_state != NULL);
+
+  while (i++ < DRAWABLE_HASH_SZ) {
+    dri_drawable = dri_state->drawable_hash[i];
+  	if (dri_drawable && dri_drawable->x_drawable == draw) {
+	    dri_state->destroyDrawable(ctx, dri_drawable);
+	    dri_state->drawable_hash[i] = NULL;
+      break;
+    }
+	}
+
+  return VA_STATUS_SUCCESS;
+}
+
 extern int fool_postp; /* do nothing for vaPutSurface if set */
 extern int trace_flag; /* trace vaPutSurface parameters */
 #define VA_TRACE(trace_func,...)                \
@@ -232,7 +261,6 @@ void va_TracePutSurface (
     unsigned int flags /* de-interlacing flags */
 );
 
-
 VAStatus vaPutSurface (
     VADisplay dpy,
     VASurfaceID surface,


More information about the Libva mailing list