loader/dri3: Expose function to create __DRIimage from pixmap

Used to support EGL_KHR_image_pixmap.

Signed-off-by: Boyan Ding <boyan.j.ding@gmail.com>
Reviewed-by: Martin Peres <martin.peres@linux.intel.com>
Reviewed-by: Kristian Høgsberg <krh@bitplanet.net>
Reviewed-by: Emil Velikov <emil.velikov@collabora.co.uk>
This commit is contained in:
Boyan Ding
2015-07-21 23:44:01 +08:00
committed by Martin Peres
parent f35198bade
commit bd6131a8d1
2 changed files with 58 additions and 29 deletions
+49 -29
View File
@@ -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:
+9
View File
@@ -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,