[Mesa-dev] [PATCH RFC 8/9] loader/dri3: Expose function to create __DRIimage from pixmap

Boyan Ding boyan.j.ding at gmail.com
Tue Jul 21 08:44:01 PDT 2015


Used to support EGL_KHR_image_pixmap.

Signed-off-by: Boyan Ding <boyan.j.ding at gmail.com>
---
 src/loader/loader_dri3_helper.c | 82 ++++++++++++++++++++++++-----------------
 src/loader/loader_dri3_helper.h |  9 +++++
 2 files changed, 58 insertions(+), 33 deletions(-)

diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index ee438ab..fb9f830 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -1065,6 +1065,47 @@ image_format_to_fourcc(int format)
    return 0;
 }
 
+__DRIimage *
+loader_dri3_create_image(xcb_connection_t *c,
+                         xcb_dri3_buffer_from_pixmap_reply_t *bp_reply,
+                         unsigned int format,
+                         __DRIscreen *dri_screen,
+                         const __DRIimageExtension *image,
+                         void *loaderPrivate)
+{
+   int                                  *fds;
+   __DRIimage                           *image_planar, *ret;
+   int                                  stride, offset;
+
+   /* Get an FD for the pixmap object
+    */
+   fds = xcb_dri3_buffer_from_pixmap_reply_fds(c, bp_reply);
+
+   stride = bp_reply->stride;
+   offset = 0;
+
+   /* createImageFromFds creates a wrapper __DRIimage structure which
+    * can deal with multiple planes for things like Yuv images. So, once
+    * we've gotten the planar wrapper, pull the single plane out of it and
+    * discard the wrapper.
+    */
+   image_planar = (image->createImageFromFds)(dri_screen,
+                                              bp_reply->width,
+                                              bp_reply->height,
+                                              image_format_to_fourcc(format),
+                                              fds, 1,
+                                              &stride, &offset, loaderPrivate);
+   close(fds[0]);
+   if (!image_planar)
+      return NULL;
+
+   ret = (image->fromPlanar)(image_planar, 0, loaderPrivate);
+
+   (image->destroyImage)(image_planar);
+
+   return ret;
+}
+
 /** dri3_get_pixmap_buffer
  *
  * Get the DRM object for a pixmap from the X server and
@@ -1081,15 +1122,9 @@ loader_dri3_get_pixmap_buffer(__DRIdrawable *driDrawable,
    xcb_drawable_t                       pixmap;
    xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie;
    xcb_dri3_buffer_from_pixmap_reply_t  *bp_reply;
-   int                                  *fds;
    xcb_sync_fence_t                     sync_fence;
    struct xshmfence                     *shm_fence;
    int                                  fence_fd;
-   __DRIimage                           *image_planar;
-   int                                  stride, offset;
-   __DRIscreen                          *dri_screen;
-
-   dri_screen = draw->vtable->get_dri_screen(draw);
 
    if (buffer)
       return buffer;
@@ -1115,37 +1150,14 @@ loader_dri3_get_pixmap_buffer(__DRIdrawable *driDrawable,
                           false,
                           fence_fd);
 
-   /* Get an FD for the pixmap object
-    */
    bp_cookie = xcb_dri3_buffer_from_pixmap(draw->conn, pixmap);
-   bp_reply = xcb_dri3_buffer_from_pixmap_reply(draw->conn,
-                                                bp_cookie, NULL);
+   bp_reply = xcb_dri3_buffer_from_pixmap_reply(draw->conn, bp_cookie, NULL);
    if (!bp_reply)
       goto no_image;
-   fds = xcb_dri3_buffer_from_pixmap_reply_fds(draw->conn, bp_reply);
-
-   stride = bp_reply->stride;
-   offset = 0;
-
-   /* createImageFromFds creates a wrapper __DRIimage structure which
-    * can deal with multiple planes for things like Yuv images. So, once
-    * we've gotten the planar wrapper, pull the single plane out of it and
-    * discard the wrapper.
-    */
-   image_planar = (draw->ext->image->createImageFromFds)(dri_screen,
-                                                         bp_reply->width,
-                                                         bp_reply->height,
-                                                         image_format_to_fourcc(format),
-                                                         fds, 1,
-                                                         &stride, &offset, buffer);
-   close(fds[0]);
-   if (!image_planar)
-      goto no_image;
-
-   buffer->image = (draw->ext->image->fromPlanar)(image_planar, 0, buffer);
-
-   (draw->ext->image->destroyImage)(image_planar);
 
+   buffer->image = loader_dri3_create_image(draw->conn, bp_reply, format,
+                                            draw->vtable->get_dri_screen(draw),
+                                            draw->ext->image, buffer);
    if (!buffer->image)
       goto no_image;
 
@@ -1158,9 +1170,13 @@ loader_dri3_get_pixmap_buffer(__DRIdrawable *driDrawable,
    buffer->sync_fence = sync_fence;
 
    draw->buffers[buf_id] = buffer;
+
+   free(bp_reply);
+
    return buffer;
 
 no_image:
+   free(bp_reply);
    xcb_sync_destroy_fence(draw->conn, sync_fence);
    xshmfence_unmap_shm(shm_fence);
 no_fence:
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
index c6537a6..c280077 100644
--- a/src/loader/loader_dri3_helper.h
+++ b/src/loader/loader_dri3_helper.h
@@ -28,6 +28,7 @@
 #include <stdint.h>
 
 #include <xcb/xcb.h>
+#include <xcb/dri3.h>
 #include <xcb/present.h>
 
 #include <GL/gl.h>
@@ -215,6 +216,14 @@ int loader_dri3_open(xcb_connection_t *conn,
                      xcb_window_t root,
                      uint32_t provider);
 
+__DRIimage *
+loader_dri3_create_image(xcb_connection_t *c,
+                         xcb_dri3_buffer_from_pixmap_reply_t *bp_reply,
+                         unsigned int format,
+                         __DRIscreen *dri_screen,
+                         const __DRIimageExtension *image,
+                         void *loaderPrivate);
+
 int
 loader_dri3_get_buffers(__DRIdrawable *driDrawable,
                         unsigned int format,
-- 
2.4.4



More information about the mesa-dev mailing list