aboutsummaryrefslogtreecommitdiffstats
path: root/src/loader/loader_dri3_helper.c
diff options
context:
space:
mode:
authorBoyan Ding <[email protected]>2015-07-21 23:44:01 +0800
committerMartin Peres <[email protected]>2015-11-17 17:26:20 +0200
commitbd6131a8d1e1cf0e6eb5494b50607a4ccb21e1f9 (patch)
treeb0a9d95748af8a03c919674668517653ec0335f9 /src/loader/loader_dri3_helper.c
parentf35198badeb956a8f435727d805a47c7e42610d0 (diff)
loader/dri3: Expose function to create __DRIimage from pixmap
Used to support EGL_KHR_image_pixmap. Signed-off-by: Boyan Ding <[email protected]> Reviewed-by: Martin Peres <[email protected]> Reviewed-by: Kristian Høgsberg <[email protected]> Reviewed-by: Emil Velikov <[email protected]>
Diffstat (limited to 'src/loader/loader_dri3_helper.c')
-rw-r--r--src/loader/loader_dri3_helper.c78
1 files changed, 49 insertions, 29 deletions
diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c
index 9093b179317..62bfe845c08 100644
--- a/src/loader/loader_dri3_helper.c
+++ b/src/loader/loader_dri3_helper.c
@@ -1054,6 +1054,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
@@ -1069,12 +1110,9 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, unsigned int format,
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;
if (buffer)
return buffer;
@@ -1100,36 +1138,14 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, unsigned int format,
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)(draw->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->dri_screen, draw->ext->image,
+ buffer);
if (!buffer->image)
goto no_image;
@@ -1142,9 +1158,13 @@ dri3_get_pixmap_buffer(__DRIdrawable *driDrawable, unsigned int format,
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: