diff options
author | Boyan Ding <[email protected]> | 2015-07-21 23:44:01 +0800 |
---|---|---|
committer | Martin Peres <[email protected]> | 2015-11-17 17:26:20 +0200 |
commit | bd6131a8d1e1cf0e6eb5494b50607a4ccb21e1f9 (patch) | |
tree | b0a9d95748af8a03c919674668517653ec0335f9 /src/loader/loader_dri3_helper.c | |
parent | f35198badeb956a8f435727d805a47c7e42610d0 (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.c | 78 |
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: |