summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gralloc.cpp45
-rw-r--r--gralloc_drm.h2
-rw-r--r--gralloc_drm_rockchip.c22
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,