gbm: Export a getter for per plane handles
authorBen Widawsky <ben@bwidawsk.net>
Fri, 2 Dec 2016 19:00:00 +0000 (11:00 -0800)
committerBen Widawsky <ben@bwidawsk.net>
Thu, 9 Mar 2017 23:35:44 +0000 (15:35 -0800)
v2: Make the error return be -1 instead of 0 because I think 0 is
actually valid.

v3: Set errno to EINVAL when the specified plane is above the total
planes. (Jason Ekstrand)
Return the bo's handle if there is no image ie. for dumb images like cursor (Daniel)

v4:
- Add assertions about plane == 0 (Jason)
- Add a comment about new restriction on planar dumb bo which is not an
earlier patch in the series.
- Correctly refactor from v2 in this patch; it ended up rebased into the
wrong patch.

Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Acked-by: Daniel Stone <daniels@collabora.com>
src/gbm/backends/dri/gbm_dri.c
src/gbm/gbm-symbols-check
src/gbm/main/gbm.c
src/gbm/main/gbm.h
src/gbm/main/gbmint.h

index 9bd647fa19f9b91c4f6ad53d6b2f4071ab32bfc8..e058361e4d108ccec707db363e8c1eb2c3df8f78 100644 (file)
@@ -625,6 +625,43 @@ gbm_dri_bo_get_planes(struct gbm_bo *_bo)
    return get_number_planes(dri, bo->image);
 }
 
+static union gbm_bo_handle
+gbm_dri_bo_get_handle_for_plane(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);
+   union gbm_bo_handle ret;
+   ret.s32 = -1;
+
+   if (!dri->image || dri->image->base.version < 13 || !dri->image->fromPlanar) {
+      errno = ENOSYS;
+      return ret;
+   }
+
+   if (plane >= get_number_planes(dri, bo->image)) {
+      errno = EINVAL;
+      return ret;
+   }
+
+   /* dumb BOs can only utilize non-planar formats */
+   if (!bo->image) {
+      assert(plane == 0);
+      ret.s32 = bo->handle;
+      return ret;
+   }
+
+   __DRIimage *image = dri->image->fromPlanar(bo->image, plane, NULL);
+   if (image) {
+      dri->image->queryImage(image, __DRI_IMAGE_ATTRIB_HANDLE, &ret.s32);
+      dri->image->destroyImage(image);
+   } else {
+      assert(plane == 0);
+      dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, &ret.s32);
+   }
+
+   return ret;
+}
+
 static void
 gbm_dri_bo_destroy(struct gbm_bo *_bo)
 {
@@ -1118,6 +1155,7 @@ dri_device_create(int fd)
    dri->base.base.bo_write = gbm_dri_bo_write;
    dri->base.base.bo_get_fd = gbm_dri_bo_get_fd;
    dri->base.base.bo_get_planes = gbm_dri_bo_get_planes;
+   dri->base.base.bo_get_handle = gbm_dri_bo_get_handle_for_plane;
    dri->base.base.bo_destroy = gbm_dri_bo_destroy;
    dri->base.base.destroy = dri_destroy;
    dri->base.base.surface_create = gbm_dri_surface_create;
index 8c4da1b7ea2e7b8ceb801f372833474534e8f8ea..1e6dd4d3ec0f164999d71fb90d78d19f51b00743 100755 (executable)
@@ -19,6 +19,7 @@ gbm_bo_get_device
 gbm_bo_get_handle
 gbm_bo_get_fd
 gbm_bo_get_plane_count
+gbm_bo_get_handle_for_plane
 gbm_bo_write
 gbm_bo_set_user_data
 gbm_bo_get_user_data
index 377951756443c107ee6a5e40fe689806e9fc2a46..066ceffc0a377e48248215d806606739c692a36a 100644 (file)
@@ -234,6 +234,24 @@ gbm_bo_get_plane_count(struct gbm_bo *bo)
    return bo->gbm->bo_get_planes(bo);
 }
 
+/** Get the handle for the specified plane of the buffer object
+ *
+ * This function gets the handle for any plane associated with the BO. When
+ * dealing with multi-planar formats, or formats which might have implicit
+ * planes based on different underlying hardware it is necessary for the client
+ * to be able to get this information to pass to the DRM.
+ *
+ * \param bo The buffer object
+ * \param plane the plane to get a handle for
+ *
+ * \sa gbm_bo_get_handle()
+ */
+GBM_EXPORT union gbm_bo_handle
+gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane)
+{
+   return bo->gbm->bo_get_handle(bo, plane);
+}
+
 /** Write data into the buffer object
  *
  * If the buffer object was created with the GBM_BO_USE_WRITE flag,
index 203a23635791d14d9fade133c648502629050d6e..67548206c40373e9c89395032cb0881713f5f64d 100644 (file)
@@ -318,6 +318,9 @@ gbm_bo_get_fd(struct gbm_bo *bo);
 int
 gbm_bo_get_plane_count(struct gbm_bo *bo);
 
+union gbm_bo_handle
+gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane);
+
 int
 gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count);
 
index c6a6701464a4aeb32ddd0d22512204aa8b3f4409..0ec531d09916fc4ad627b87da6b644dfd2ee0242 100644 (file)
@@ -77,6 +77,7 @@ struct gbm_device {
    int (*bo_write)(struct gbm_bo *bo, const void *buf, size_t data);
    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);
    void (*bo_destroy)(struct gbm_bo *bo);
 
    struct gbm_surface *(*surface_create)(struct gbm_device *gbm,