From b72badb6c83a497b299873136e37435261b174ad Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 19 Aug 2016 16:26:46 -0700 Subject: [PATCH] minigbm: Added support for multiplane import MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gralloc requires flexible YUV formats (YV12, NV12) to be importable. This change modifies our internal import API to support this. TEST=ran graphics_Gbm BUG=chromium:616275 CQ-DEPEND=CL:373048 Change-Id: I4100e1c1639828e4adf08764b45fe5a44b7078a3 Reviewed-on: https://chromium-review.googlesource.com/374162 Commit-Ready: Gurchetan Singh Tested-by: Gurchetan Singh Reviewed-by: Stéphane Marchesin --- drv.c | 56 +++++++++++++++++++++++++++++++++----------------------- drv.h | 22 ++++++++++++---------- gbm.c | 13 +++++++++++-- 3 files changed, 56 insertions(+), 35 deletions(-) diff --git a/drv.c b/drv.c index 90a59d5..6fcdab7 100644 --- a/drv.c +++ b/drv.c @@ -274,37 +274,47 @@ drv_bo_unmap(struct bo *bo) struct bo *drv_bo_import(struct driver *drv, struct drv_import_fd_data *data) { int ret; + size_t plane; struct bo *bo; struct drm_prime_handle prime_handle; - memset(&prime_handle, 0, sizeof(prime_handle)); - prime_handle.fd = data->fd; - - /* This function can support only single plane formats. */ - /* If multi-plane import is desired, new function should be added. */ - if (drv_num_planes_from_format(data->format) != 1) - return NULL; - bo = drv_bo_new(drv, data->width, data->height, data->format); - ret = drmIoctl(drv->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, - &prime_handle); - - if (ret) { - fprintf(stderr, "drv: DRM_IOCTL_PRIME_FD_TO_HANDLE failed " - "(fd=%u)\n", prime_handle.fd); - free(bo); + if (!bo) return NULL; + + for (plane = 0; plane < bo->num_planes; plane++) { + + memset(&prime_handle, 0, sizeof(prime_handle)); + prime_handle.fd = data->fds[plane]; + + ret = drmIoctl(drv->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, + &prime_handle); + + if (ret) { + fprintf(stderr, "drv: DRM_IOCTL_PRIME_FD_TO_HANDLE failed " + "(fd=%u)\n", prime_handle.fd); + + if (plane > 0) { + bo->num_planes = plane; + drv_bo_destroy(bo); + } else { + free(bo); + } + + return NULL; + } + + bo->handles[plane].u32 = prime_handle.handle; + bo->strides[plane] = data->strides[plane]; + bo->offsets[plane] = data->offsets[plane]; + bo->sizes[plane] = data->sizes[plane]; + + pthread_mutex_lock(&drv->table_lock); + drv_increment_reference_count(drv, bo, plane); + pthread_mutex_unlock(&drv->table_lock); } - bo->strides[0] = data->stride; - bo->sizes[0] = data->height * data->stride; - bo->handles[0].u32 = prime_handle.handle; - - pthread_mutex_lock(&drv->table_lock); - drv_increment_reference_count(drv, bo, 0); - pthread_mutex_unlock(&drv->table_lock); - return bo; } diff --git a/drv.h b/drv.h index 6fc83cf..cc7752a 100644 --- a/drv.h +++ b/drv.h @@ -123,19 +123,21 @@ struct driver; struct bo; union bo_handle { - void *ptr; - int32_t s32; - uint32_t u32; - int64_t s64; - uint64_t u64; + void *ptr; + int32_t s32; + uint32_t u32; + int64_t s64; + uint64_t u64; }; struct drv_import_fd_data { - int fd; - uint32_t width; - uint32_t height; - uint32_t stride; - drv_format_t format; + int fds[DRV_MAX_PLANES]; + uint32_t strides[DRV_MAX_PLANES]; + uint32_t offsets[DRV_MAX_PLANES]; + uint32_t sizes[DRV_MAX_PLANES]; + uint32_t width; + uint32_t height; + drv_format_t format; }; struct driver * diff --git a/gbm.c b/gbm.c index 077ff23..c5acc00 100644 --- a/gbm.c +++ b/gbm.c @@ -170,11 +170,20 @@ gbm_bo_import(struct gbm_device *gbm, uint32_t type, if (!bo) return NULL; - drv_data.fd = fd_data->fd; + /* + * Minigbm only supports importing single-plane formats at moment. + * If multi-plane import is desired, the interface will have to be + * modified. + */ + + memset(&drv_data, 0, sizeof(drv_data)); + drv_data.fds[0] = fd_data->fd; + drv_data.strides[0] = fd_data->stride; + drv_data.offsets[0] = 0; + drv_data.sizes[0] = fd_data->height * fd_data->stride; drv_data.width = fd_data->width; drv_data.height = fd_data->height; drv_data.format = gbm_convert_format(fd_data->format); - drv_data.stride = fd_data->stride; bo->bo = drv_bo_import(gbm->drv, &drv_data);