diff options
-rw-r--r-- | gralloc.cpp | 45 | ||||
-rw-r--r-- | gralloc_drm.h | 2 | ||||
-rw-r--r-- | gralloc_drm_rockchip.c | 22 |
3 files changed, 63 insertions, 6 deletions
diff --git a/gralloc.cpp b/gralloc.cpp index 521d6cb..421aeb5 100644 --- a/gralloc.cpp +++ b/gralloc.cpp @@ -62,7 +62,7 @@ static int drm_mod_perform(const struct gralloc_module_t *mod, int op, ...) va_start(args, op); switch (op) { - case GRALLOC_MODULE_PERFORM_GET_DRM_FD: + case static_cast<int>(GRALLOC_MODULE_PERFORM_GET_DRM_FD): { int *fd = va_arg(args, int *); *fd = gralloc_drm_get_fd(dmod->drm); @@ -110,6 +110,46 @@ static int drm_mod_lock(const gralloc_module_t *mod, buffer_handle_t handle, return gralloc_drm_bo_lock(bo, usage, x, y, w, h, ptr); } +static int drm_mod_lock_ycbcr(const gralloc_module_t *mod, buffer_handle_t bhandle, + int usage, int x, int y, int w, int h, struct android_ycbcr *ycbcr) +{ + struct gralloc_drm_handle_t *handle; + struct gralloc_drm_bo_t *bo; + void *ptr; + int err; + + bo = gralloc_drm_bo_from_handle(bhandle); + if (!bo) + return -EINVAL; + handle = bo->handle; + + switch(handle->format) { + case HAL_PIXEL_FORMAT_YCbCr_420_888: + break; + default: + return -EINVAL; + } + + err = gralloc_drm_bo_lock(bo, usage, x, y, w, h, &ptr); + if (err) + return err; + + switch(handle->format) { + case HAL_PIXEL_FORMAT_YCbCr_420_888: + ycbcr->y = ptr; + ycbcr->cb = (uint8_t *)ptr + handle->stride * handle->height; + ycbcr->cr = (uint8_t *)ycbcr->cb + 1; + ycbcr->ystride = handle->stride; + ycbcr->cstride = handle->stride; + ycbcr->chroma_step = 2; + break; + default: + break; + } + + return 0; +} + static int drm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle) { struct drm_module_t *dmod = (struct drm_module_t *) mod; @@ -231,7 +271,8 @@ struct drm_module_t HAL_MODULE_INFO_SYM = { .unregisterBuffer = drm_mod_unregister_buffer, .lock = drm_mod_lock, .unlock = drm_mod_unlock, - .perform = drm_mod_perform + .perform = drm_mod_perform, + .lock_ycbcr = drm_mod_lock_ycbcr, }, .mutex = PTHREAD_MUTEX_INITIALIZER, diff --git a/gralloc_drm.h b/gralloc_drm.h index 3ad818f..f92ba5e 100644 --- a/gralloc_drm.h +++ b/gralloc_drm.h @@ -66,6 +66,7 @@ static inline int gralloc_drm_get_bpp(int format) case HAL_PIXEL_FORMAT_YV12: case HAL_PIXEL_FORMAT_YCbCr_422_SP: case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_888: bpp = 1; break; default: @@ -91,6 +92,7 @@ static inline void gralloc_drm_align_geometry(int format, int *width, int *heigh extra_height_div = 1; break; case HAL_PIXEL_FORMAT_YCrCb_420_SP: + case HAL_PIXEL_FORMAT_YCbCr_420_888: align_w = 2; align_h = 2; extra_height_div = 2; diff --git a/gralloc_drm_rockchip.c b/gralloc_drm_rockchip.c index b383208..f9dcb0e 100644 --- a/gralloc_drm_rockchip.c +++ b/gralloc_drm_rockchip.c @@ -40,7 +40,7 @@ static struct gralloc_drm_bo_t *drm_gem_rockchip_alloc( struct rockchip_info *info = (struct rockchip_info *)drv; struct rockchip_buffer *buf; struct drm_gem_close args; - int ret, cpp, pitch; + int ret, cpp, pitch, aligned_width, aligned_height; uint32_t size, gem_handle; buf = calloc(1, sizeof(*buf)); @@ -55,12 +55,26 @@ static struct gralloc_drm_bo_t *drm_gem_rockchip_alloc( return NULL; } + aligned_width = handle->width; + aligned_height = handle->height; gralloc_drm_align_geometry(handle->format, - &handle->width, &handle->height); + &aligned_width, &aligned_height); /* TODO: We need to sort out alignment */ - pitch = ALIGN(handle->width * cpp, 64); - size = handle->height * pitch; + pitch = ALIGN(aligned_width * cpp, 64); + size = aligned_height * pitch; + + if (handle->format == HAL_PIXEL_FORMAT_YCbCr_420_888) { + /* + * WAR for H264 decoder requiring additional space + * at the end of destination buffers. + */ + uint32_t w_mbs, h_mbs; + + w_mbs = ALIGN(handle->width, 16) / 16; + h_mbs = ALIGN(handle->height, 16) / 16; + size += 64 * w_mbs * h_mbs; + } if (handle->prime_fd >= 0) { ret = drmPrimeFDToHandle(info->fd, handle->prime_fd, |