OSDN Git Service

minigbm: Ensure DRM_FORMAT_YVU420_ANDROID meets Android requirements.
authorOwen Lin <owenlin@google.com>
Mon, 5 Jun 2017 06:33:08 +0000 (14:33 +0800)
committerchrome-bot <chrome-bot@chromium.org>
Thu, 22 Jun 2017 10:34:49 +0000 (03:34 -0700)
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 <owenlin@chromium.org>
Tested-by: Owen Lin <owenlin@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
cros_gralloc/cros_gralloc_module.cc
helpers.c
i915.c
mediatek.c
vgem.c
virtio_gpu.c

index 7123da2..bbe3c6f 100644 (file)
@@ -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];
index 19ee646..806c152 100644 (file)
--- 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 <system/graphics.h>):
+        *  - 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 (file)
--- 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;
        }
index 0078cf0..d2e9f53 100644 (file)
@@ -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 (file)
--- 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;
        }
index 5780600..ab1d8f1 100644 (file)
@@ -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;
        }