gralloc: Add support for lock_ycbcr
Fill the android_ycbcr struct for HAL_PIXEL_FORMAT_YCbCr_*_888
formats.
This is a flexible YUV format that allows gralloc to set a
hardware specific YUV format based on the usage flags passed in.
Here we set the format similar to how we set the implementation
defined format and set the android_ycbcr structure to point to
the appropriate plane offsets.
Reference: HAL_PIXEL_FORMAT_YCbCr_420_888 definition in
system/core/include/system/graphics.h
Change-Id: If0c7abf5e206bf982ad333da2dae57cbac302733
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index c3ae070..d475fb8 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -56,8 +56,7 @@
}
static int gralloc_map(gralloc_module_t const* module,
- buffer_handle_t handle,
- void** vaddr)
+ buffer_handle_t handle)
{
if(!module)
return -EINVAL;
@@ -78,8 +77,6 @@
}
hnd->base = intptr_t(mappedAddress) + hnd->offset;
- //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
- // hnd->fd, hnd->offset, hnd->size, mappedAddress);
mappedAddress = MAP_FAILED;
size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
err = memalloc->map_buffer(&mappedAddress, size,
@@ -92,7 +89,6 @@
}
hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata;
}
- *vaddr = (void*)hnd->base;
return 0;
}
@@ -152,8 +148,7 @@
private_handle_t* hnd = (private_handle_t*)handle;
hnd->base = 0;
hnd->base_metadata = 0;
- void *vaddr;
- int err = gralloc_map(module, handle, &vaddr);
+ int err = gralloc_map(module, handle);
if (err) {
ALOGE("%s: gralloc_map failed", __FUNCTION__);
return err;
@@ -212,10 +207,8 @@
return 0;
}
-int gralloc_lock(gralloc_module_t const* module,
- buffer_handle_t handle, int usage,
- int /*l*/, int /*t*/, int /*w*/, int /*h*/,
- void** vaddr)
+static int gralloc_map_and_invalidate (gralloc_module_t const* module,
+ buffer_handle_t handle, int usage)
{
if (!module || private_handle_t::validate(handle) < 0)
return -EINVAL;
@@ -227,10 +220,9 @@
// we need to map for real
pthread_mutex_t* const lock = &sMapLock;
pthread_mutex_lock(lock);
- err = gralloc_map(module, handle, vaddr);
+ err = gralloc_map(module, handle);
pthread_mutex_unlock(lock);
}
- *vaddr = (void*)hnd->base;
if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
//Invalidate if reading in software. No need to do this for the
//metadata buffer as it is only read/written in software.
@@ -249,6 +241,50 @@
return err;
}
+int gralloc_lock(gralloc_module_t const* module,
+ buffer_handle_t handle, int usage,
+ int /*l*/, int /*t*/, int /*w*/, int /*h*/,
+ void** vaddr)
+{
+ private_handle_t* hnd = (private_handle_t*)handle;
+ int err = gralloc_map_and_invalidate(module, handle, usage);
+ if(!err)
+ *vaddr = (void*)hnd->base;
+ return err;
+}
+
+int gralloc_lock_ycbcr(gralloc_module_t const* module,
+ buffer_handle_t handle, int usage,
+ int /*l*/, int /*t*/, int /*w*/, int /*h*/,
+ struct android_ycbcr *ycbcr)
+{
+ private_handle_t* hnd = (private_handle_t*)handle;
+ int err = gralloc_map_and_invalidate(module, handle, usage);
+ size_t ystride, cstride;
+ if(!err) {
+ //hnd->format holds our implementation defined format
+ //HAL_PIXEL_FORMAT_YCrCb_420_SP is the only one set right now.
+ switch (hnd->format) {
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ ystride = ALIGN(hnd->width, 16);
+ cstride = ALIGN(hnd->width, 16)/2;
+ ycbcr->y = (void*)hnd->base;
+ ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
+ ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1);
+ ycbcr->ystride = ystride;
+ ycbcr->cstride = cstride;
+ ycbcr->chroma_step = 2;
+ memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
+ break;
+ default:
+ ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
+ hnd->format);
+ err = -EINVAL;
+ }
+ }
+ return err;
+}
+
int gralloc_unlock(gralloc_module_t const* module,
buffer_handle_t handle)
{