OSDN Git Service

minigbm: flatten gralloc handle
authorGurchetan Singh <gurchetansingh@chromium.org>
Mon, 28 Nov 2016 23:25:26 +0000 (15:25 -0800)
committerchrome-bot <chrome-bot@chromium.org>
Fri, 9 Dec 2016 11:30:16 +0000 (03:30 -0800)
Many GL drivers assume that first value in the native_handle data
array is the fd associated with the graphics buffer, i.e,

int prime_fd = handle->data[0];

This in our case until 4bfc7401. We added 64-bit modifiers in
our import data, so all values in the drv_import_fd_data struct get
8-byte aligned. In our cros_gralloc_handle, 4 bytes of padding
are added between native_handle_t and drv_import_fd_data to make
the alignment work. To counter-act this, we can stop embedding
drv_import_fd_data in cros_gralloc_handle.

BUG=chromium:616275
TEST=Mali driver doesn't return an error when running cros_gralloc
CQ-DEPEND=CL:414585

Change-Id: Ib6c165e98126468b96fa7119d5ca13eebee1655c
Reviewed-on: https://chromium-review.googlesource.com/414536
Commit-Ready: Gurchetan Singh <gurchetansingh@chromium.org>
Tested-by: Gurchetan Singh <gurchetansingh@chromium.org>
Reviewed-by: Stéphane Marchesin <marcheu@chromium.org>
cros_gralloc/cros_alloc_device.cc
cros_gralloc/cros_gralloc_handle.h
cros_gralloc/cros_gralloc_helpers.h
cros_gralloc/cros_gralloc_module.cc

index ddfb448..7a8dff6 100644 (file)
@@ -37,6 +37,11 @@ static struct cros_gralloc_bo *cros_gralloc_bo_create(struct driver *drv,
                return NULL;
        }
 
+       /*
+        * If there is a desire for more than one kernel buffer, this can be
+        * removed once the ArcCodec and Wayland service have the ability to
+        * send more than one fd. GL/Vulkan drivers may also have to modified.
+        */
        if (drv_num_buffers_per_bo(bo->bo) != 1) {
                drv_bo_destroy(bo->bo);
                delete bo;
@@ -51,31 +56,39 @@ static struct cros_gralloc_bo *cros_gralloc_bo_create(struct driver *drv,
 
 static struct cros_gralloc_handle *cros_gralloc_handle_from_bo(struct bo *bo)
 {
+       uint64_t mod;
+       size_t num_planes;
        struct cros_gralloc_handle *hnd;
 
        hnd = new cros_gralloc_handle();
        memset(hnd, 0, sizeof(*hnd));
 
-       hnd->base.version = sizeof(hnd->base);
-       hnd->base.numFds = 1;
-       hnd->base.numInts = num_ints();
+       num_planes = drv_bo_get_num_planes(bo);
 
-       for (size_t p = 0; p < drv_bo_get_num_planes(bo); p++) {
-               hnd->data.strides[p] = drv_bo_get_plane_stride(bo, p);
-               hnd->data.offsets[p] = drv_bo_get_plane_offset(bo, p);
-               hnd->data.sizes[p] = drv_bo_get_plane_size(bo, p);
+       hnd->base.version = sizeof(hnd->base);
+       hnd->base.numFds = num_planes;
+       hnd->base.numInts = num_ints_handle() - num_planes;
+
+       for (size_t p = 0; p < num_planes; p++) {
+               hnd->fds[p] = drv_bo_get_plane_fd(bo, p);
+               hnd->strides[p] = drv_bo_get_plane_stride(bo, p);
+               hnd->offsets[p] = drv_bo_get_plane_offset(bo, p);
+               hnd->sizes[p] = drv_bo_get_plane_size(bo, p);
+
+               mod = drv_bo_get_plane_format_modifier(bo, p);
+               hnd->format_modifiers[p] = static_cast<uint32_t>(mod >> 32);
+               hnd->format_modifiers[p+1] = static_cast<uint32_t>(mod);
        }
 
-       hnd->data.fds[0] = drv_bo_get_plane_fd(bo, 0);
-       hnd->data.width = drv_bo_get_width(bo);
-       hnd->data.height = drv_bo_get_height(bo);
-       hnd->data.format = drv_bo_get_format(bo);
+       hnd->width = drv_bo_get_width(bo);
+       hnd->height = drv_bo_get_height(bo);
+       hnd->format = drv_bo_get_format(bo);
 
        hnd->magic = cros_gralloc_magic();
        hnd->registrations = 0;
 
-       hnd->pixel_stride = hnd->data.strides[0];
-       hnd->pixel_stride /= drv_stride_from_format(hnd->data.format, 1, 0);
+       hnd->pixel_stride = hnd->strides[0];
+       hnd->pixel_stride /= drv_stride_from_format(hnd->format, 1, 0);
 
        return hnd;
 }
@@ -91,7 +104,7 @@ static int cros_gralloc_alloc(alloc_device_t *dev, int w, int h, int format,
                return CROS_GRALLOC_ERROR_NO_RESOURCES;
 
        auto hnd = cros_gralloc_handle_from_bo(bo->bo);
-       hnd->format = static_cast<int32_t>(format);
+       hnd->droid_format = static_cast<int32_t>(format);
        hnd->usage = static_cast<int32_t>(usage);
 
        hnd->bo = reinterpret_cast<uint64_t>(bo);
index a173aee..1920df3 100644 (file)
 #include <cutils/native_handle.h>
 #include <cstdint>
 
-#include "../drv.h"
+#define DRV_MAX_PLANES 4
+
+/*
+ * Only use 32-bit integers in the handle. This guarantees that the handle is
+ * densely packed (i.e, the compiler does not insert any padding).
+ */
 
 struct cros_gralloc_handle {
        native_handle_t base;
-       drv_import_fd_data data;
+       int32_t fds[DRV_MAX_PLANES];
+       uint32_t strides[DRV_MAX_PLANES];
+       uint32_t offsets[DRV_MAX_PLANES];
+       uint32_t sizes[DRV_MAX_PLANES];
+       uint32_t format_modifiers[2 * DRV_MAX_PLANES];
+       uint32_t width;
+       uint32_t height;
+       uint32_t format;            /* DRM format */
        uint32_t magic;
        uint32_t pixel_stride;
-       int32_t format, usage;     /* Android format and usage. */
-       uint64_t bo;               /* Pointer to cros_gralloc_bo. */
-       int32_t registrations;     /*
-                                   * Number of times (*register)() has been
-                                   * called on this handle.
-                                   */
+       int32_t droid_format;
+       int32_t usage;              /* Android usage. */
+       uint64_t bo;                /* Pointer to cros_gralloc_bo. */
+       int32_t registrations;      /*
+                                    * Number of times (*register)() has been
+                                    * called on this handle.
+                                    */
 };
 
 #endif
index 4fbe8c2..fe88891 100644 (file)
@@ -7,6 +7,7 @@
 #ifndef CROS_GRALLOC_HELPERS_H
 #define CROS_GRALLOC_HELPERS_H
 
+#include "../drv.h"
 #include "cros_gralloc_handle.h"
 
 #include <hardware/gralloc.h>
@@ -44,14 +45,9 @@ constexpr uint32_t cros_gralloc_magic(void)
        return 0xABCDDCBA;
 }
 
-constexpr uint32_t num_ints(void)
+constexpr uint32_t num_ints_handle()
 {
-       /*
-        * numFds in our case is one. Subtract that from our numInts
-        * calculation.
-        */
-       return ((sizeof(struct cros_gralloc_handle)
-               - offsetof(cros_gralloc_handle, data)) / sizeof(int)) - 1;
+       return ((sizeof(struct cros_gralloc_handle)) / sizeof(int));
 }
 
 constexpr uint32_t sw_access(void)
index b7ce03b..db30f95 100644 (file)
@@ -72,7 +72,7 @@ static int cros_gralloc_register_buffer(struct gralloc_module_t const* module,
                return CROS_GRALLOC_ERROR_NONE;
        }
 
-       if (drmPrimeFDToHandle(drv_get_fd(mod->drv), hnd->data.fds[0], &id)) {
+       if (drmPrimeFDToHandle(drv_get_fd(mod->drv), hnd->fds[0], &id)) {
                cros_gralloc_error("drmPrimeFDToHandle failed.");
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
        }
@@ -82,11 +82,25 @@ static int cros_gralloc_register_buffer(struct gralloc_module_t const* module,
                bo->refcount++;
                hnd->bo = reinterpret_cast<uint64_t>(bo);
        } else {
-               hnd->data.fds[1] = hnd->data.fds[2] = hnd->data.fds[3]
-                                = hnd->data.fds[0];
+               struct drv_import_fd_data data;
+               size_t num_planes = drv_num_planes_from_format(hnd->format);
+
+               data.format = hnd->format;
+               data.width = hnd->width;
+               data.height = hnd->height;
+               for (size_t p = 0; p < num_planes; p++) {
+                       data.fds[p] = hnd->fds[p];
+                       data.strides[p] = hnd->strides[p];
+                       data.offsets[p] = hnd->offsets[p];
+                       data.sizes[p] = hnd->sizes[p];
+                       data.format_modifiers[p] = static_cast<uint64_t>
+                               (hnd->format_modifiers[p]) << 32;
+                       data.format_modifiers[p] |= hnd->format_modifiers[p+1];
+               }
+
                bo = new cros_gralloc_bo();
 
-               bo->bo = drv_bo_import(mod->drv, &hnd->data);
+               bo->bo = drv_bo_import(mod->drv, &data);
                if (!bo->bo) {
                        delete bo;
                        return CROS_GRALLOC_ERROR_NO_RESOURCES;
@@ -155,7 +169,7 @@ static int cros_gralloc_lock(struct gralloc_module_t const* module,
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
        }
 
-       if (hnd->format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
+       if (hnd->droid_format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
                cros_gralloc_error("YUV format not compatible.");
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
        }
@@ -241,13 +255,13 @@ static int cros_gralloc_perform(struct gralloc_module_t const* module,
                break;
        case GRALLOC_DRM_GET_FORMAT:
                out_format = va_arg(args, int32_t *);
-               *out_format = hnd->format;
+               *out_format = hnd->droid_format;
                break;
        case GRALLOC_DRM_GET_DIMENSIONS:
                out_width = va_arg(args, uint32_t *);
                out_height = va_arg(args, uint32_t *);
-               *out_width = hnd->data.width;
-               *out_height = hnd->data.height;
+               *out_width = hnd->width;
+               *out_height = hnd->height;
                break;
        case GRALLOC_DRM_GET_BACKING_STORE:
                out_store = va_arg(args, uint64_t *);
@@ -284,7 +298,7 @@ static int cros_gralloc_lock_ycbcr(struct gralloc_module_t const* module,
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
        }
 
-       if ((hnd->format != HAL_PIXEL_FORMAT_YCbCr_420_888)) {
+       if ((hnd->droid_format != HAL_PIXEL_FORMAT_YCbCr_420_888)) {
                cros_gralloc_error("Non-YUV format not compatible.");
                return CROS_GRALLOC_ERROR_BAD_HANDLE;
        }
@@ -305,7 +319,7 @@ static int cros_gralloc_lock_ycbcr(struct gralloc_module_t const* module,
        for (size_t p = 0; p < drv_bo_get_num_planes(bo->bo); p++)
                offsets[p] = drv_bo_get_plane_offset(bo->bo, p);
 
-       switch (hnd->data.format) {
+       switch (hnd->format) {
        case DRM_FORMAT_NV12:
                ycbcr->y = addr;
                ycbcr->cb = addr + offsets[1];