summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2016-09-08 17:45:03 -0500
committerRob Herring <robh@kernel.org>2016-12-13 09:43:50 -0600
commitff66db2e495ee96a82aaf55dfbb058ebb7df2c95 (patch)
tree7431dee62790b965e7751fa7e71def03cd91cce7
parent2a8002bfd571d989158389e4c3b2275943be55ea (diff)
Add YV12 pixel format support
GBM doesn't support YV12 and we need a single buffer, so request GR88 from GBM instead and adjust the width and height. GR88 also ensures (hopefully) that the GPU texture alignment requirements are met. Signed-off-by: Rob Herring <robh@kernel.org>
-rw-r--r--gralloc_gbm.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/gralloc_gbm.cpp b/gralloc_gbm.cpp
index a0bc34d..7e0dbda 100644
--- a/gralloc_gbm.cpp
+++ b/gralloc_gbm.cpp
@@ -83,6 +83,9 @@ static uint32_t get_gbm_format(int format)
fmt = GBM_FORMAT_ARGB8888;
break;
case HAL_PIXEL_FORMAT_YV12:
+ /* YV12 is planar, but must be a single buffer so ask for GR88 */
+ fmt = GBM_FORMAT_GR88;
+ break;
case HAL_PIXEL_FORMAT_YCbCr_422_SP:
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
default:
@@ -131,6 +134,12 @@ static struct gralloc_gbm_bo_t *gbm_import(struct gbm_device *gbm,
data.stride = handle->stride;
data.format = format;
+ /* Adjust the width and height for a GBM GR88 buffer */
+ if (handle->format == HAL_PIXEL_FORMAT_YV12) {
+ data.width /= 2;
+ data.height += handle->height / 2;
+ }
+
buf->bo = gbm_bo_import(gbm, GBM_BO_IMPORT_FD, &data, 0);
if (!buf->bo) {
delete buf;
@@ -162,6 +171,15 @@ static struct gralloc_gbm_bo_t *gbm_alloc(struct gbm_device *gbm,
height = 64;
}
+ /*
+ * For YV12, we request GR88, so halve the width since we're getting
+ * 16bpp. Then increase the height by 1.5 for the U and V planes.
+ */
+ if (handle->format == HAL_PIXEL_FORMAT_YV12) {
+ width /= 2;
+ height += handle->height / 2;
+ }
+
ALOGD("create BO, size=%dx%d, fmt=%d, usage=%x",
handle->width, handle->height, handle->format, usage);
buf->bo = gbm_bo_create(gbm, width, height, format, usage);
@@ -199,6 +217,13 @@ static int gbm_map(struct gralloc_gbm_bo_t *bo, int x, int y, int w, int h,
if (bo->map_data)
return -EINVAL;
+ if (bo->handle->format == HAL_PIXEL_FORMAT_YV12) {
+ if (x || y)
+ ALOGE("can't map with offset for planar %p - fmt %x", bo, bo->handle->format);
+ w /= 2;
+ h += h / 2;
+ }
+
if (enable_write)
flags |= GBM_BO_TRANSFER_WRITE;