From: Owen Lin Date: Mon, 5 Jun 2017 06:33:08 +0000 (+0800) Subject: minigbm: Ensure DRM_FORMAT_YVU420_ANDROID meets Android requirements. X-Git-Url: http://git.osdn.net/view?p=android-x86%2Fexternal-minigbm.git;a=commitdiff_plain;h=bbb69fd4ab3dc87428451b218643419a7d273790 minigbm: Ensure DRM_FORMAT_YVU420_ANDROID meets Android requirements. For HAL_PIXEL_FORMAT_YV12 (mapped to DRM_FORMAT_YVU420_ANDROID), it needs to meet the following requirements: - The vertical stride must equal to the buffer's height. - The chroma stride is 16-byte aligned. As a result, stop mapping DRM_FORMAT_FLEX_YCbCr_420_888 to DRM_FORMAT_YVU420_ANDROID. The format is used for hardware decoding, It has more restrictions on the alignments of the width or height. Bug: b:31479749 Test: Run the testOtherVP8ImageReader and testGoogH264ImageReader of android.media.cts.ImageReaderDecoderTest. Change-Id: Id37f51115ed8b1937ca7d6e48abd809235b43fe4 Reviewed-on: https://chromium-review.googlesource.com/526758 Commit-Ready: Owen Lin Tested-by: Owen Lin Reviewed-by: Gurchetan Singh --- diff --git a/cros_gralloc/cros_gralloc_module.cc b/cros_gralloc/cros_gralloc_module.cc index 7123da2..bbe3c6f 100644 --- a/cros_gralloc/cros_gralloc_module.cc +++ b/cros_gralloc/cros_gralloc_module.cc @@ -331,6 +331,7 @@ static int cros_gralloc_lock_ycbcr(struct gralloc_module_t const *module, buffer ycbcr->chroma_step = 2; break; case DRM_FORMAT_YVU420_ANDROID: + case DRM_FORMAT_YVU420: ycbcr->y = addr; ycbcr->cb = addr + offsets[2]; ycbcr->cr = addr + offsets[1]; diff --git a/helpers.c b/helpers.c index 19ee646..806c152 100644 --- a/helpers.c +++ b/helpers.c @@ -140,16 +140,26 @@ int drv_bo_from_format(struct bo *bo, uint32_t stride, uint32_t aligned_height, num_planes = drv_num_planes_from_format(format); assert(num_planes); - bo->total_size = 0; + + /* + * HAL_PIXEL_FORMAT_YV12 requires that (see ): + * - the aligned height is same as the buffer's height. + * - the chroma stride is 16 bytes aligned, i.e., the luma's strides + * is 32 bytes aligned. + */ + if (bo->format == DRM_FORMAT_YVU420_ANDROID) { + assert(aligned_height == bo->height); + assert(stride == ALIGN(stride, 32)); + } for (p = 0; p < num_planes; p++) { bo->strides[p] = subsample_stride(stride, format, p); - bo->sizes[p] = drv_size_from_format(format, bo->strides[p], bo->height, p); + bo->sizes[p] = drv_size_from_format(format, bo->strides[p], aligned_height, p); bo->offsets[p] = offset; offset += bo->sizes[p]; - bo->total_size += drv_size_from_format(format, bo->strides[p], aligned_height, p); } + bo->total_size = offset; return 0; } @@ -169,6 +179,9 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t * Android requires. */ aligned_width = ALIGN(width, 32); + } + + if (format == DRM_FORMAT_YVU420_ANDROID || format == DRM_FORMAT_YVU420) { aligned_height = 3 * DIV_ROUND_UP(height, 2); } diff --git a/i915.c b/i915.c index d1a1731..87bb438 100644 --- a/i915.c +++ b/i915.c @@ -271,19 +271,27 @@ static int i915_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32 else bo->tiling = I915_TILING_Y; + if (format == DRM_FORMAT_YVU420 || format == DRM_FORMAT_YVU420_ANDROID) + bo->tiling = I915_TILING_NONE; + stride = drv_stride_from_format(format, width, 0); + + ret = i915_align_dimensions(bo, bo->tiling, &stride, &height); + if (ret) + return ret; + /* * Align the Y plane to 128 bytes so the chroma planes would be aligned * to 64 byte boundaries. This is an Intel HW requirement. */ - if (format == DRM_FORMAT_YVU420 || format == DRM_FORMAT_YVU420_ANDROID) { + if (format == DRM_FORMAT_YVU420) stride = ALIGN(stride, 128); - bo->tiling = I915_TILING_NONE; - } - ret = i915_align_dimensions(bo, bo->tiling, &stride, &height); - if (ret) - return ret; + /* + * HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. + */ + if (format == DRM_FORMAT_YVU420_ANDROID) + height = bo->height; drv_bo_from_format(bo, stride, height, format); @@ -424,7 +432,7 @@ static uint32_t i915_resolve_format(uint32_t format) /*HACK: See b/28671744 */ return DRM_FORMAT_XBGR8888; case DRM_FORMAT_FLEX_YCbCr_420_888: - return DRM_FORMAT_YVU420_ANDROID; + return DRM_FORMAT_YVU420; default: return format; } diff --git a/mediatek.c b/mediatek.c index 0078cf0..d2e9f53 100644 --- a/mediatek.c +++ b/mediatek.c @@ -100,7 +100,7 @@ static uint32_t mediatek_resolve_format(uint32_t format) /*HACK: See b/28671744 */ return DRM_FORMAT_XBGR8888; case DRM_FORMAT_FLEX_YCbCr_420_888: - return DRM_FORMAT_YVU420_ANDROID; + return DRM_FORMAT_YVU420; default: return format; } diff --git a/vgem.c b/vgem.c index 95aee0a..9bf5b87 100644 --- a/vgem.c +++ b/vgem.c @@ -37,9 +37,14 @@ static int vgem_init(struct driver *drv) static int vgem_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) { - int ret = drv_dumb_bo_create(bo, ALIGN(width, MESA_LLVMPIPE_TILE_SIZE), - ALIGN(height, MESA_LLVMPIPE_TILE_SIZE), format, flags); - return ret; + width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); + height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); + + /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ + if (bo->format == DRM_FORMAT_YVU420_ANDROID) + height = bo->height; + + return drv_dumb_bo_create(bo, width, height, format, flags); } static uint32_t vgem_resolve_format(uint32_t format) @@ -49,7 +54,7 @@ static uint32_t vgem_resolve_format(uint32_t format) /*HACK: See b/28671744 */ return DRM_FORMAT_XBGR8888; case DRM_FORMAT_FLEX_YCbCr_420_888: - return DRM_FORMAT_YVU420_ANDROID; + return DRM_FORMAT_YVU420; default: return format; } diff --git a/virtio_gpu.c b/virtio_gpu.c index 5780600..ab1d8f1 100644 --- a/virtio_gpu.c +++ b/virtio_gpu.c @@ -37,9 +37,14 @@ static int virtio_gpu_init(struct driver *drv) static int virtio_gpu_bo_create(struct bo *bo, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) { - int ret = drv_dumb_bo_create(bo, ALIGN(width, MESA_LLVMPIPE_TILE_SIZE), - ALIGN(height, MESA_LLVMPIPE_TILE_SIZE), format, flags); - return ret; + width = ALIGN(width, MESA_LLVMPIPE_TILE_SIZE); + height = ALIGN(height, MESA_LLVMPIPE_TILE_SIZE); + + /* HAL_PIXEL_FORMAT_YV12 requires that the buffer's height not be aligned. */ + if (bo->format == DRM_FORMAT_YVU420_ANDROID) + height = bo->height; + + return drv_dumb_bo_create(bo, width, height, format, flags); } static uint32_t virtio_gpu_resolve_format(uint32_t format) @@ -49,7 +54,7 @@ static uint32_t virtio_gpu_resolve_format(uint32_t format) /*HACK: See b/28671744 */ return DRM_FORMAT_XBGR8888; case DRM_FORMAT_FLEX_YCbCr_420_888: - return DRM_FORMAT_YVU420_ANDROID; + return DRM_FORMAT_YVU420; default: return format; }