gbm: add gbm_bo_get_fd_for_plane
authorSimon Ser <contact@emersion.fr>
Fri, 12 Jun 2020 15:58:48 +0000 (17:58 +0200)
committerMarge Bot <eric+marge@anholt.net>
Thu, 25 Mar 2021 05:48:00 +0000 (05:48 +0000)
This commit adds a new gbm_bo_get_fd_for_plane function, which does the
same as gbm_bo_get_fd but allows specifying the plane.

v2: - Rename to gbm_bo_get_fd_for_plane (Emil)

Signed-off-by: Simon Ser <contact@emersion.fr>
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5442>

src/gbm/backends/dri/gbm_dri.c
src/gbm/gbm-symbols.txt
src/gbm/main/gbm.c
src/gbm/main/gbm.h
src/gbm/main/gbmint.h

index 856e691..ac579ef 100644 (file)
@@ -750,6 +750,45 @@ gbm_dri_bo_get_handle_for_plane(struct gbm_bo *_bo, int plane)
    return ret;
 }
 
+static int
+gbm_dri_bo_get_plane_fd(struct gbm_bo *_bo, int plane)
+{
+   struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm);
+   struct gbm_dri_bo *bo = gbm_dri_bo(_bo);
+   int fd = -1;
+
+   if (!dri->image || dri->image->base.version < 13 || !dri->image->fromPlanar) {
+      /* Preserve legacy behavior if plane is 0 */
+      if (plane == 0)
+         return gbm_dri_bo_get_fd(_bo);
+
+      errno = ENOSYS;
+      return -1;
+   }
+
+   /* dumb BOs can only utilize non-planar formats */
+   if (!bo->image) {
+      errno = EINVAL;
+      return -1;
+   }
+
+   if (plane >= get_number_planes(dri, bo->image)) {
+      errno = EINVAL;
+      return -1;
+   }
+
+   __DRIimage *image = dri->image->fromPlanar(bo->image, plane, NULL);
+   if (image) {
+      dri->image->queryImage(image, __DRI_IMAGE_ATTRIB_FD, &fd);
+      dri->image->destroyImage(image);
+   } else {
+      assert(plane == 0);
+      dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_FD, &fd);
+   }
+
+   return fd;
+}
+
 static uint32_t
 gbm_dri_bo_get_stride(struct gbm_bo *_bo, int plane)
 {
@@ -1382,6 +1421,7 @@ dri_device_create(int fd)
    dri->base.bo_get_fd = gbm_dri_bo_get_fd;
    dri->base.bo_get_planes = gbm_dri_bo_get_planes;
    dri->base.bo_get_handle = gbm_dri_bo_get_handle_for_plane;
+   dri->base.bo_get_plane_fd = gbm_dri_bo_get_plane_fd;
    dri->base.bo_get_stride = gbm_dri_bo_get_stride;
    dri->base.bo_get_offset = gbm_dri_bo_get_offset;
    dri->base.bo_get_modifier = gbm_dri_bo_get_modifier;
index d17e8f1..8cdbc21 100644 (file)
@@ -4,6 +4,7 @@ gbm_bo_destroy
 gbm_bo_get_bpp
 gbm_bo_get_device
 gbm_bo_get_fd
+gbm_bo_get_fd_for_plane
 gbm_bo_get_format
 gbm_bo_get_handle
 gbm_bo_get_handle_for_plane
index 954b3c3..e4c7d95 100644 (file)
@@ -363,6 +363,26 @@ gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane)
    return bo->gbm->bo_get_handle(bo, plane);
 }
 
+/** Get a DMA-BUF file descriptor for the specified plane of the buffer object
+ *
+ * This function creates a DMA-BUF (also known as PRIME) file descriptor
+ * handle for the specified plane of the buffer object.  Each call to
+ * gbm_bo_get_fd_for_plane() returns a new file descriptor and the caller is
+ * responsible for closing the file descriptor.
+
+ * \param bo The buffer object
+ * \param plane The plane to get a DMA-BUF for
+ * \return Returns a file descriptor referring to the underlying buffer or -1
+ * if an error occurs.
+ *
+ * \sa gbm_bo_get_fd()
+ */
+GBM_EXPORT int
+gbm_bo_get_fd_for_plane(struct gbm_bo *bo, int plane)
+{
+   return bo->gbm->bo_get_plane_fd(bo, plane);
+}
+
 /**
  * Get the chosen modifier for the buffer object
  *
index 5801cd5..3a0fe73 100644 (file)
@@ -383,6 +383,9 @@ union gbm_bo_handle
 gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane);
 
 int
+gbm_bo_get_fd_for_plane(struct gbm_bo *bo, int plane);
+
+int
 gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count);
 
 void
index 1925774..ded7679 100644 (file)
@@ -83,6 +83,7 @@ struct gbm_device {
    int (*bo_get_fd)(struct gbm_bo *bo);
    int (*bo_get_planes)(struct gbm_bo *bo);
    union gbm_bo_handle (*bo_get_handle)(struct gbm_bo *bo, int plane);
+   int (*bo_get_plane_fd)(struct gbm_bo *bo, int plane);
    uint32_t (*bo_get_stride)(struct gbm_bo *bo, int plane);
    uint32_t (*bo_get_offset)(struct gbm_bo *bo, int plane);
    uint64_t (*bo_get_modifier)(struct gbm_bo *bo);