From 7f6209e46f8de409f182931e0ca23bb64f1a8e39 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Wed, 26 Oct 2016 13:36:42 -0700 Subject: [PATCH] gbm: Export a per plane getter for stride v2: Preserve legacy behavior when plane is 0 (Jason Ekstrand) EINVAL when input plane is greater than total planes (Jason Ekstrand) Don't leak the image after fromPlanar (Daniel) Move bo->image check below plane count preventing bad index succeeding (Daniel) v3: Fix DRIimage leak (using Jason's recommended change) Make plane 0 return planar stride. This might break legacy behavior (Jason) v4: Move bogus hunk for get_handle_for_plane to the right patch (Jason) Fix error handling path to be cleaner (Jason) v5: Add assert for dumb BOs to make sure plane == 0 (Jason) Signed-off-by: Ben Widawsky Reviewed-by: Eric Engestrom (v1) Reviewed-by: Jason Ekstrand Acked-by: Daniel Stone --- src/gbm/backends/dri/gbm_dri.c | 35 +++++++++++++++++++++++++++++++++- src/gbm/gbm-symbols-check | 1 + src/gbm/main/gbm.c | 15 ++++++++++++++- src/gbm/main/gbm.h | 3 +++ 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index 6a834182b5b..5a98b6aba68 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -665,7 +665,40 @@ gbm_dri_bo_get_handle_for_plane(struct gbm_bo *_bo, int plane) static uint32_t gbm_dri_bo_get_stride(struct gbm_bo *_bo, int plane) { - return _bo->stride; + struct gbm_dri_device *dri = gbm_dri_device(_bo->gbm); + struct gbm_dri_bo *bo = gbm_dri_bo(_bo); + __DRIimage *image; + int stride = 0; + + if (!dri->image || dri->image->base.version < 11 || !dri->image->fromPlanar) { + /* Preserve legacy behavior if plane is 0 */ + if (plane == 0) + return _bo->stride; + + errno = ENOSYS; + return 0; + } + + if (plane >= get_number_planes(dri, bo->image)) { + errno = EINVAL; + return 0; + } + + if (bo->image == NULL) { + assert(plane == 0); + return _bo->stride; + } + + image = dri->image->fromPlanar(bo->image, plane, NULL); + if (image) { + dri->image->queryImage(image, __DRI_IMAGE_ATTRIB_STRIDE, &stride); + dri->image->destroyImage(image); + } else { + assert(plane == 0); + dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, &stride); + } + + return (uint32_t)stride; } static void diff --git a/src/gbm/gbm-symbols-check b/src/gbm/gbm-symbols-check index 1e6dd4d3ec0..459006a63fe 100755 --- a/src/gbm/gbm-symbols-check +++ b/src/gbm/gbm-symbols-check @@ -14,6 +14,7 @@ gbm_bo_unmap gbm_bo_get_width gbm_bo_get_height gbm_bo_get_stride +gbm_bo_get_stride_for_plane gbm_bo_get_format gbm_bo_get_device gbm_bo_get_handle diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c index 7462e90c4c5..0a9f0bef7ee 100644 --- a/src/gbm/main/gbm.c +++ b/src/gbm/main/gbm.c @@ -165,7 +165,20 @@ gbm_bo_get_height(struct gbm_bo *bo) GBM_EXPORT uint32_t gbm_bo_get_stride(struct gbm_bo *bo) { - return bo->gbm->bo_get_stride(bo, 0); + return gbm_bo_get_stride_for_plane(bo, 0); +} + +/** Get the stride for the given plane + * + * \param bo The buffer object + * \param plane for which you want the stride + * + * \sa gbm_bo_get_stride() + */ +GBM_EXPORT uint32_t +gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane) +{ + return bo->gbm->bo_get_stride(bo, plane); } /** Get the format of the buffer object diff --git a/src/gbm/main/gbm.h b/src/gbm/main/gbm.h index 67548206c40..1719c5312a5 100644 --- a/src/gbm/main/gbm.h +++ b/src/gbm/main/gbm.h @@ -303,6 +303,9 @@ gbm_bo_get_height(struct gbm_bo *bo); uint32_t gbm_bo_get_stride(struct gbm_bo *bo); +uint32_t +gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane); + uint32_t gbm_bo_get_format(struct gbm_bo *bo); -- 2.30.2