BOOL DRI3DmaBufFromPixmap(Display *dpy, Pixmap pixmap, int *fd, int *width, int *height, int *stride, int *depth, int *bpp) { xcb_connection_t *xcb_connection = XGetXCBConnection(dpy); xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie; xcb_dri3_buffer_from_pixmap_reply_t *bp_reply; bp_cookie = xcb_dri3_buffer_from_pixmap(xcb_connection, pixmap); bp_reply = xcb_dri3_buffer_from_pixmap_reply(xcb_connection, bp_cookie, NULL); if (!bp_reply) return FALSE; *fd = xcb_dri3_buffer_from_pixmap_reply_fds(xcb_connection, bp_reply)[0]; *width = bp_reply->width; *height = bp_reply->height; *stride = bp_reply->stride; *depth = bp_reply->depth; *bpp = bp_reply->depth; return TRUE; }
__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; }
static struct vl_dri3_buffer * dri3_get_front_buffer(struct vl_dri3_screen *scrn) { xcb_dri3_buffer_from_pixmap_cookie_t bp_cookie; xcb_dri3_buffer_from_pixmap_reply_t *bp_reply; xcb_sync_fence_t sync_fence; struct xshmfence *shm_fence; int fence_fd, *fds; struct winsys_handle whandle; struct pipe_resource templ, *texture = NULL; if (scrn->front_buffer) { pipe_resource_reference(&texture, scrn->front_buffer->texture); return scrn->front_buffer; } scrn->front_buffer = CALLOC_STRUCT(vl_dri3_buffer); if (!scrn->front_buffer) return NULL; fence_fd = xshmfence_alloc_shm(); if (fence_fd < 0) goto free_buffer; shm_fence = xshmfence_map_shm(fence_fd); if (!shm_fence) goto close_fd; bp_cookie = xcb_dri3_buffer_from_pixmap(scrn->conn, scrn->drawable); bp_reply = xcb_dri3_buffer_from_pixmap_reply(scrn->conn, bp_cookie, NULL); if (!bp_reply) goto unmap_shm; fds = xcb_dri3_buffer_from_pixmap_reply_fds(scrn->conn, bp_reply); if (fds[0] < 0) goto free_reply; memset(&whandle, 0, sizeof(whandle)); whandle.type = DRM_API_HANDLE_TYPE_FD; whandle.handle = (unsigned)fds[0]; whandle.stride = bp_reply->stride; memset(&templ, 0, sizeof(templ)); templ.bind = PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; templ.format = PIPE_FORMAT_B8G8R8X8_UNORM; templ.target = PIPE_TEXTURE_2D; templ.last_level = 0; templ.width0 = bp_reply->width; templ.height0 = bp_reply->height; templ.depth0 = 1; templ.array_size = 1; scrn->front_buffer->texture = scrn->base.pscreen->resource_from_handle(scrn->base.pscreen, &templ, &whandle, PIPE_HANDLE_USAGE_READ_WRITE); close(fds[0]); if (!scrn->front_buffer->texture) goto free_reply; xcb_dri3_fence_from_fd(scrn->conn, scrn->drawable, (sync_fence = xcb_generate_id(scrn->conn)), false, fence_fd); pipe_resource_reference(&texture, scrn->front_buffer->texture); scrn->front_buffer->pixmap = scrn->drawable; scrn->front_buffer->width = bp_reply->width; scrn->front_buffer->height = bp_reply->height; scrn->front_buffer->shm_fence = shm_fence; scrn->front_buffer->sync_fence = sync_fence; free(bp_reply); return scrn->front_buffer; free_reply: free(bp_reply); unmap_shm: xshmfence_unmap_shm(shm_fence); close_fd: close(fence_fd); free_buffer: FREE(scrn->front_buffer); return NULL; }