Beispiel #1
0
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;
}
Beispiel #3
0
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;
}