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
This commit is contained in:
Naseer Ahmed
2013-05-08 12:28:37 -04:00
parent 3684b9577a
commit 34d33bc907
3 changed files with 83 additions and 40 deletions

View File

@@ -265,7 +265,8 @@ int gpu_context_t::alloc_impl(int w, int h, int format, int usage,
//If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
//the usage bits, gralloc assigns a format.
if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12
else if((usage & GRALLOC_USAGE_HW_CAMERA_MASK)

View File

@@ -44,6 +44,11 @@ extern int gralloc_lock(gralloc_module_t const* module,
int l, int t, int w, int h,
void** vaddr);
extern 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);
extern int gralloc_unlock(gralloc_module_t const* module,
buffer_handle_t handle);
@@ -58,12 +63,12 @@ extern int gralloc_perform(struct gralloc_module_t const* module,
// HAL module methods
static struct hw_module_methods_t gralloc_module_methods = {
open: gralloc_device_open
open: gralloc_device_open
};
// HAL module initialize
struct private_module_t HAL_MODULE_INFO_SYM = {
base: {
base: {
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 1,
@@ -80,14 +85,15 @@ base: {
lock: gralloc_lock,
unlock: gralloc_unlock,
perform: gralloc_perform,
lock_ycbcr: gralloc_lock_ycbcr,
},
framebuffer: 0,
fbFormat: 0,
flags: 0,
numBuffers: 0,
bufferMask: 0,
lock: PTHREAD_MUTEX_INITIALIZER,
currentBuffer: 0,
framebuffer: 0,
fbFormat: 0,
flags: 0,
numBuffers: 0,
bufferMask: 0,
lock: PTHREAD_MUTEX_INITIALIZER,
currentBuffer: 0,
};
// Open Gralloc device

View File

@@ -56,8 +56,7 @@ static IMemAlloc* getAllocator(int flags)
}
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 @@ static int gralloc_map(gralloc_module_t const* module,
}
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 @@ static int gralloc_map(gralloc_module_t const* module,
}
hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata;
}
*vaddr = (void*)hnd->base;
return 0;
}
@@ -152,8 +148,7 @@ int gralloc_register_buffer(gralloc_module_t const* module,
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 @@ int terminateBuffer(gralloc_module_t const* module,
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 @@ int gralloc_lock(gralloc_module_t const* module,
// 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 @@ int gralloc_lock(gralloc_module_t const* module,
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)
{