diff options
-rw-r--r-- | src/loader/loader_dri3_helper.c | 78 | ||||
-rw-r--r-- | src/loader/loader_dri3_helper.h | 9 |
2 files changed, 58 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: diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h index 54c2a52f5e1..5b8fd1d24ca 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> @@ -221,6 +222,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, |