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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user