diff --git a/cros_gralloc/cros_alloc_device.cc b/cros_gralloc/cros_alloc_device.cc index ddfb448..7a8dff6 100644 --- a/cros_gralloc/cros_alloc_device.cc +++ b/cros_gralloc/cros_alloc_device.cc @@ -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(mod >> 32); + hnd->format_modifiers[p+1] = static_cast(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(format); + hnd->droid_format = static_cast(format); hnd->usage = static_cast(usage); hnd->bo = reinterpret_cast(bo); diff --git a/cros_gralloc/cros_gralloc_handle.h b/cros_gralloc/cros_gralloc_handle.h index a173aee..1920df3 100644 --- a/cros_gralloc/cros_gralloc_handle.h +++ b/cros_gralloc/cros_gralloc_handle.h @@ -10,19 +10,32 @@ #include #include -#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 diff --git a/cros_gralloc/cros_gralloc_helpers.h b/cros_gralloc/cros_gralloc_helpers.h index 4fbe8c2..fe88891 100644 --- a/cros_gralloc/cros_gralloc_helpers.h +++ b/cros_gralloc/cros_gralloc_helpers.h @@ -7,6 +7,7 @@ #ifndef CROS_GRALLOC_HELPERS_H #define CROS_GRALLOC_HELPERS_H +#include "../drv.h" #include "cros_gralloc_handle.h" #include @@ -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) diff --git a/cros_gralloc/cros_gralloc_module.cc b/cros_gralloc/cros_gralloc_module.cc index b7ce03b..db30f95 100644 --- a/cros_gralloc/cros_gralloc_module.cc +++ b/cros_gralloc/cros_gralloc_module.cc @@ -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(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 + (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];