diff --git a/gralloc.cpp b/gralloc.cpp index 538f908..1cc9f55 100644 --- a/gralloc.cpp +++ b/gralloc.cpp @@ -150,6 +150,19 @@ static int gbm_mod_unlock(const gralloc_module_t *mod, buffer_handle_t handle) return err; } +static int gbm_mod_lock_ycbcr(gralloc_module_t const *mod, buffer_handle_t handle, + int usage, int x, int y, int w, int h, struct android_ycbcr *ycbcr) +{ + struct gbm_module_t *dmod = (struct gbm_module_t *) mod; + int err; + + pthread_mutex_lock(&dmod->mutex); + err = gralloc_gbm_bo_lock_ycbcr(handle, usage, x, y, w, h, ycbcr); + pthread_mutex_unlock(&dmod->mutex); + + return err; +} + static int gbm_mod_close_gpu0(struct hw_device_t *dev) { struct gbm_module_t *dmod = (struct gbm_module_t *)dev->module; @@ -251,6 +264,7 @@ struct gbm_module_t HAL_MODULE_INFO_SYM = { .unregisterBuffer = gbm_mod_unregister_buffer, .lock = gbm_mod_lock, .unlock = gbm_mod_unlock, + .lock_ycbcr = gbm_mod_lock_ycbcr, .perform = gbm_mod_perform }, diff --git a/gralloc_gbm.cpp b/gralloc_gbm.cpp index 52ca974..f5729b9 100644 --- a/gralloc_gbm.cpp +++ b/gralloc_gbm.cpp @@ -482,3 +482,50 @@ int gralloc_gbm_bo_unlock(buffer_handle_t handle) return 0; } + +#define GRALLOC_ALIGN(value, base) (((value) + ((base)-1)) & ~((base)-1)) + +int gralloc_gbm_bo_lock_ycbcr(buffer_handle_t handle, + int usage, int x, int y, int w, int h, + struct android_ycbcr *ycbcr) +{ + struct gralloc_handle_t *hnd = gralloc_handle(handle); + int ystride, cstride; + void *addr; + int err; + + ALOGD("handle %p, hnd %p, usage 0x%x", handle, hnd, usage); + + err = gralloc_gbm_bo_lock(handle, usage, x, y, w, h, &addr); + if (err) + return err; + + memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved)); + + switch (hnd->format) { + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + ystride = cstride = GRALLOC_ALIGN(hnd->width, 16); + ycbcr->y = addr; + ycbcr->cr = (unsigned char *)addr + ystride * hnd->height; + ycbcr->cb = (unsigned char *)addr + ystride * hnd->height + 1; + ycbcr->ystride = ystride; + ycbcr->cstride = cstride; + ycbcr->chroma_step = 2; + break; + case HAL_PIXEL_FORMAT_YV12: + ystride = hnd->width; + cstride = GRALLOC_ALIGN(ystride / 2, 16); + ycbcr->y = addr; + ycbcr->cr = (unsigned char *)addr + ystride * hnd->height; + ycbcr->cb = (unsigned char *)addr + ystride * hnd->height + cstride * hnd->height / 2; + ycbcr->ystride = ystride; + ycbcr->cstride = cstride; + ycbcr->chroma_step = 1; + break; + default: + ALOGE("Can not lock buffer, invalid format: 0x%x", hnd->format); + return -EINVAL; + } + + return 0; +} diff --git a/gralloc_gbm_priv.h b/gralloc_gbm_priv.h index d0326c5..cbe9256 100644 --- a/gralloc_gbm_priv.h +++ b/gralloc_gbm_priv.h @@ -45,6 +45,8 @@ int gralloc_gbm_get_gem_handle(buffer_handle_t handle); int gralloc_gbm_bo_lock(buffer_handle_t handle, int usage, int x, int y, int w, int h, void **addr); int gralloc_gbm_bo_unlock(buffer_handle_t handle); +int gralloc_gbm_bo_lock_ycbcr(buffer_handle_t handle, int usage, + int x, int y, int w, int h, struct android_ycbcr *ycbcr); struct gbm_device *gbm_dev_create(void); void gbm_dev_destroy(struct gbm_device *gbm);