OSDN Git Service

rockchip: add NV12 bo creation support
authorZach Reizner <zachr@google.com>
Wed, 27 Apr 2016 18:14:41 +0000 (11:14 -0700)
committerchrome-bot <chrome-bot@chromium.org>
Wed, 11 May 2016 23:51:59 +0000 (16:51 -0700)
This patch does alignment if needed on the width and height, but does
not expose this change to the public facing gbm_bo. It is expected that
framebuffer creation in the kernel with do alignment such that
applications don't have to have platform specific knowledge of alignment
requirements.

TEST=nv12_test
BUG=chromium:607241

Change-Id: I6138afb56537f516fac038ff4db39593c623fccd
Reviewed-on: https://chromium-review.googlesource.com/341010
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Zach Reizner <zachr@chromium.org>
rockchip.c

index 1b10db6..0c0e0a8 100644 (file)
@@ -6,6 +6,8 @@
 
 #ifdef GBM_ROCKCHIP
 
+#include <assert.h>
+#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 #include <xf86drm.h>
 
 #include "gbm_priv.h"
 #include "helpers.h"
+#include "util.h"
 
 static int gbm_rockchip_bo_create(struct gbm_bo *bo,
                                  uint32_t width, uint32_t height,
                                  uint32_t format, uint32_t flags)
 {
-       size_t size;
-       struct drm_rockchip_gem_create gem_create;
+       size_t plane;
+
+       switch (format) {
+       case GBM_FORMAT_NV12:
+               width = ALIGN(width, 4);
+               height = ALIGN(height, 4);
+               bo->strides[0] = bo->strides[1] = width;
+               bo->sizes[0] = height * bo->strides[0];
+               bo->sizes[1] = height * bo->strides[1] / 2;
+               bo->offsets[0] = bo->offsets[1] = 0;
+               break;
+       case GBM_FORMAT_XRGB8888:
+       case GBM_FORMAT_ARGB8888:
+       case GBM_FORMAT_ABGR8888:
+               bo->strides[0] = gbm_stride_from_format(format, width);
+               bo->sizes[0] = height * bo->strides[0];
+               bo->offsets[0] = 0;
+               break;
+       default:
+               fprintf(stderr, "minigbm: rockchip: unsupported format %4.4s\n",
+                       (char*)&format);
+               assert(0);
+               return -EINVAL;
+       }
+
        int ret;
+       for (plane = 0; plane < bo->num_planes; plane++) {
+               size_t size = bo->sizes[plane];
+               struct drm_rockchip_gem_create gem_create;
 
-       bo->strides[0] = gbm_stride_from_format(format, width);
-       size = height * bo->strides[0];
+               memset(&gem_create, 0, sizeof(gem_create));
+               gem_create.size = size;
 
-       memset(&gem_create, 0, sizeof(gem_create));
-       gem_create.size = size;
+               ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE,
+                              &gem_create);
+               if (ret) {
+                       fprintf(stderr, "minigbm: DRM_IOCTL_ROCKCHIP_GEM_CREATE failed "
+                                       "(size=%zu)\n", size);
+                       goto cleanup_planes;
+               }
 
-       ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, &gem_create);
-       if (ret) {
-               fprintf(stderr, "minigbm: DRM_IOCTL_ROCKCHIP_GEM_CREATE failed "
-                               "(size=%zu)\n", size);
-               return ret;
+               bo->handles[plane].u32 = gem_create.handle;
        }
 
-       bo->handles[0].u32 = gem_create.handle;
-       bo->sizes[0] = size;
-       bo->offsets[0] = 0;
-
        return 0;
+
+cleanup_planes:
+       for ( ; plane != 0; plane--) {
+               struct drm_gem_close gem_close;
+               memset(&gem_close, 0, sizeof(gem_close));
+               gem_close.handle = bo->handles[plane - 1].u32;
+               int gem_close_ret = drmIoctl(bo->gbm->fd, DRM_IOCTL_GEM_CLOSE,
+                                            &gem_close);
+               if (gem_close_ret) {
+                       fprintf(stderr,
+                               "minigbm: DRM_IOCTL_GEM_CLOSE failed: %d\n",
+                               gem_close_ret);
+               }
+       }
+
+       return ret;
 }
 
 const struct gbm_driver gbm_driver_rockchip =
@@ -53,6 +95,8 @@ const struct gbm_driver gbm_driver_rockchip =
                {GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING},
                {GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_LINEAR},
                {GBM_FORMAT_ABGR8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_CURSOR | GBM_BO_USE_RENDERING},
+               {GBM_FORMAT_NV12, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING},
+               {GBM_FORMAT_NV12, GBM_BO_USE_SCANOUT | GBM_BO_USE_LINEAR},
        }
 };