gbm: Export a per plane getter for offset

Unlike stride, there was no previous offset getter, so it can be right
on the first try.

v2: Return EINVAL when plane is greater than total planes to make it
match the similar APIs.
Avoid leak after fromPlanar (Daniel)
Make sure when getting offsets we consider dumb images (Daniel)

v3: Use Jason's recommendation for handling the non-planar case.

v4: Return int64_t so we can get real errors

v5: Add an assertion for dumb BOs (Jason)

Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Reviewed-by: Eric Engestrom <eric.engestrom@imgtec.com>
Reviewed-by: Jason Ekstrand <jason@jlekstrand.net>
Acked-by: Daniel Stone <daniels@collabora.com>
This commit is contained in:
Ben Widawsky 2016-10-26 16:02:23 -07:00
parent 7f6209e46f
commit 2ee34bd5dc
5 changed files with 55 additions and 0 deletions

View File

@ -701,6 +701,40 @@ gbm_dri_bo_get_stride(struct gbm_bo *_bo, int plane)
return (uint32_t)stride;
}
static int64_t
gbm_dri_bo_get_offset(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 offset = 0;
if (!dri->image || dri->image->base.version < 13 || !dri->image->fromPlanar) {
errno = ENOSYS;
return -1;
}
if (plane >= get_number_planes(dri, bo->image)) {
errno = EINVAL;
return -2;
}
/* Dumb images have no offset */
if (bo->image == NULL) {
assert(plane == 0);
return 0;
}
__DRIimage *image = dri->image->fromPlanar(bo->image, plane, NULL);
if (image) {
dri->image->queryImage(image, __DRI_IMAGE_ATTRIB_OFFSET, &offset);
dri->image->destroyImage(image);
} else {
dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_OFFSET, &offset);
}
return (uint32_t)offset;
}
static void
gbm_dri_bo_destroy(struct gbm_bo *_bo)
{
@ -1196,6 +1230,7 @@ dri_device_create(int 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_get_stride = gbm_dri_bo_get_stride;
dri->base.base.bo_get_offset = gbm_dri_bo_get_offset;
dri->base.base.bo_destroy = gbm_dri_bo_destroy;
dri->base.base.destroy = dri_destroy;
dri->base.base.surface_create = gbm_dri_surface_create;

View File

@ -16,6 +16,7 @@ gbm_bo_get_height
gbm_bo_get_stride
gbm_bo_get_stride_for_plane
gbm_bo_get_format
gbm_bo_get_offset
gbm_bo_get_device
gbm_bo_get_handle
gbm_bo_get_fd

View File

@ -194,6 +194,21 @@ gbm_bo_get_format(struct gbm_bo *bo)
return bo->format;
}
/** Get the offset for the data of the specified plane
*
* Extra planes, and even the first plane, may have an offset from the start of
* the buffer object. This function will provide the offset for the given plane
* to be used in various KMS APIs.
*
* \param bo The buffer object
* \return The offset
*/
GBM_EXPORT int64_t
gbm_bo_get_offset(struct gbm_bo *bo, int plane)
{
return bo->gbm->bo_get_offset(bo, plane);
}
/** Get the gbm device used to create the buffer object
*
* \param bo The buffer object

View File

@ -309,6 +309,9 @@ gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane);
uint32_t
gbm_bo_get_format(struct gbm_bo *bo);
int64_t
gbm_bo_get_offset(struct gbm_bo *bo, int plane);
struct gbm_device *
gbm_bo_get_device(struct gbm_bo *bo);

View File

@ -79,6 +79,7 @@ struct gbm_device {
int (*bo_get_planes)(struct gbm_bo *bo);
union gbm_bo_handle (*bo_get_handle)(struct gbm_bo *bo, int plane);
uint32_t (*bo_get_stride)(struct gbm_bo *bo, int plane);
int64_t (*bo_get_offset)(struct gbm_bo *bo, int plane);
void (*bo_destroy)(struct gbm_bo *bo);
struct gbm_surface *(*surface_create)(struct gbm_device *gbm,