OSDN Git Service

vgem: support DRM_FORMAT_YVU420_ANDROID
authorGurchetan Singh <gurchetansingh@chromium.org>
Thu, 16 Mar 2017 20:05:45 +0000 (13:05 -0700)
committerchrome-bot <chrome-bot@chromium.org>
Tue, 21 Mar 2017 23:47:39 +0000 (16:47 -0700)
drv_dumb_bo_create function only allocates single-plane formats at the
moment, even though the vgem driver has a resolve format hook that
leads to DRM_FORMAT_YVU420_ANDROID. Let's allocate a single buffer
that's big enough to support DRM_FORMAT_YVU420_ANDROID, as drm_gralloc
does. Note videos don't work with Android emulation, but they never
did with drm_gralloc and that's a separate problem.

BUG=chromium:616275
TEST=no regressions with gbmtest when running qemu + trybots

Change-Id: I9b081dbe553fe1159feaa7eed104ac340c59e41b
Reviewed-on: https://chromium-review.googlesource.com/456404
Commit-Ready: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Gurchetan Singh <gurchetansingh@chromium.org>
helpers.c
vgem.c

index 1a838b8..8e76929 100644 (file)
--- a/helpers.c
+++ b/helpers.c
@@ -138,15 +138,26 @@ int drv_bo_from_format(struct bo *bo, uint32_t aligned_width,
 int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height,
                       uint32_t format, uint32_t flags)
 {
-       struct drm_mode_create_dumb create_dumb;
        int ret;
+       size_t plane;
+       uint32_t aligned_width, aligned_height, bytes_per_pixel;
+       struct drm_mode_create_dumb create_dumb;
 
-       /* Only single-plane formats are supported */
-       assert(drv_num_planes_from_format(format) == 1);
+       aligned_width = width;
+       aligned_height = height;
+       bytes_per_pixel = DIV_ROUND_UP(drv_bpp_from_format(format, 0), 8);
+       if (format == DRM_FORMAT_YVU420_ANDROID) {
+               /*
+                * Align width to 16 pixels, so chroma strides are 16 bytes as
+                * Android requires.
+                */
+               aligned_width = ALIGN(width, 32);
+               aligned_height = 3 * DIV_ROUND_UP(height, 2);
+       }
 
        memset(&create_dumb, 0, sizeof(create_dumb));
-       create_dumb.height = height;
-       create_dumb.width = width;
+       create_dumb.height = aligned_height;
+       create_dumb.width = aligned_width;
        create_dumb.bpp = drv_bpp_from_format(format, 0);
        create_dumb.flags = 0;
 
@@ -156,13 +167,13 @@ int drv_dumb_bo_create(struct bo *bo, uint32_t width, uint32_t height,
                return ret;
        }
 
-       bo->width = width;
-       bo->height = height;
-       bo->handles[0].u32 = create_dumb.handle;
-       bo->offsets[0] = 0;
-       bo->total_size = bo->sizes[0] = create_dumb.size;
-       bo->strides[0] = create_dumb.pitch;
+       drv_bo_from_format(bo, DIV_ROUND_UP(create_dumb.pitch, bytes_per_pixel),
+                          height, format);
+
+       for (plane = 0; plane < bo->num_planes; plane++)
+               bo->handles[plane].u32 = create_dumb.handle;
 
+       bo->total_size = create_dumb.size;
        return 0;
 }
 
diff --git a/vgem.c b/vgem.c
index e7fcc66..4139989 100644 (file)
--- a/vgem.c
+++ b/vgem.c
@@ -12,7 +12,8 @@
 #define MESA_LLVMPIPE_TILE_SIZE (1 << MESA_LLVMPIPE_TILE_ORDER)
 
 static const uint32_t supported_formats[] = {
-       DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888
+       DRM_FORMAT_ARGB8888, DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
+       DRM_FORMAT_YVU420_ANDROID
 };
 
 static int vgem_init(struct driver *drv)
@@ -27,9 +28,6 @@ static int vgem_bo_create(struct bo *bo, uint32_t width, uint32_t height,
        int ret = drv_dumb_bo_create(bo, ALIGN(width, MESA_LLVMPIPE_TILE_SIZE),
                                     ALIGN(height, MESA_LLVMPIPE_TILE_SIZE),
                                     format, flags);
-       bo->width = width;
-       bo->height = height;
-
        return ret;
 }
 
@@ -40,7 +38,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;
+               return DRM_FORMAT_YVU420_ANDROID;
        default:
                return format;
        }