-/** dri3_alloc_render_buffer
- *
- * Use the driver createImage function to construct a __DRIimage, then
- * get a file descriptor for that and create an X pixmap from that
- *
- * Allocate an xshmfence for synchronization
- */
-static struct dri3_buffer *
-dri3_alloc_render_buffer(struct glx_screen *glx_screen, Drawable draw,
- unsigned int format, int width, int height, int depth)
-{
- struct dri3_screen *psc = (struct dri3_screen *) glx_screen;
- Display *dpy = glx_screen->dpy;
- struct dri3_buffer *buffer;
- xcb_connection_t *c = XGetXCBConnection(dpy);
- xcb_pixmap_t pixmap;
- xcb_sync_fence_t sync_fence;
- struct xshmfence *shm_fence;
- int buffer_fd, fence_fd;
- int stride;
-
- /* Create an xshmfence object and
- * prepare to send that to the X server
- */
-
- fence_fd = xshmfence_alloc_shm();
- if (fence_fd < 0)
- return NULL;
- shm_fence = xshmfence_map_shm(fence_fd);
- if (shm_fence == NULL)
- goto no_shm_fence;
-
- /* Allocate the image from the driver
- */
- buffer = calloc(1, sizeof (struct dri3_buffer));
- if (!buffer)
- goto no_buffer;
-
- buffer->cpp = dri3_cpp_for_format(format);
- if (!buffer->cpp)
- goto no_image;
-
- buffer->image = (*psc->image->createImage) (psc->driScreen,
- width, height,
- format,
- __DRI_IMAGE_USE_SHARE|__DRI_IMAGE_USE_SCANOUT,
- buffer);
-
-
- if (!buffer->image)
- goto no_image;
-
- /* X wants the stride, so ask the image for it
- */
- if (!(*psc->image->queryImage)(buffer->image, __DRI_IMAGE_ATTRIB_STRIDE, &stride))
- goto no_buffer_attrib;
-
- buffer->pitch = stride;
-
- if (!(*psc->image->queryImage)(buffer->image, __DRI_IMAGE_ATTRIB_FD, &buffer_fd))
- goto no_buffer_attrib;
-
- xcb_dri3_pixmap_from_buffer(c,
- (pixmap = xcb_generate_id(c)),
- draw,
- buffer->size,
- width, height, buffer->pitch,
- depth, buffer->cpp * 8,
- buffer_fd);
-
- xcb_dri3_fence_from_fd(c,
- pixmap,
- (sync_fence = xcb_generate_id(c)),
- false,
- fence_fd);
-
- buffer->pixmap = pixmap;
- buffer->own_pixmap = true;
- buffer->sync_fence = sync_fence;
- buffer->shm_fence = shm_fence;
- buffer->width = width;
- buffer->height = height;
-
- /* Mark the buffer as idle
- */
- dri3_fence_set(buffer);
-
- return buffer;
-
-no_buffer_attrib:
- (*psc->image->destroyImage)(buffer->image);
-no_image:
- free(buffer);
-no_buffer:
- xshmfence_unmap_shm(shm_fence);
-no_shm_fence:
- close(fence_fd);
- return NULL;
-}
-
-/** dri3_free_render_buffer
- *
- * Free everything associated with one render buffer including pixmap, fence
- * stuff and the driver image
- */
-static void
-dri3_free_render_buffer(struct dri3_drawable *pdraw, struct dri3_buffer *buffer)
-{
- struct dri3_screen *psc = (struct dri3_screen *) pdraw->base.psc;
- xcb_connection_t *c = XGetXCBConnection(pdraw->base.psc->dpy);
-
- if (buffer->own_pixmap)
- xcb_free_pixmap(c, buffer->pixmap);
- xcb_sync_destroy_fence(c, buffer->sync_fence);
- xshmfence_unmap_shm(buffer->shm_fence);
- (*psc->image->destroyImage)(buffer->image);
- free(buffer);