summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLajos Molnar <lajos@google.com>2015-01-27 18:47:28 -0800
committerLajos Molnar <lajos@google.com>2015-01-28 16:13:47 -0800
commit25ffbfe5e8b51f392fafc1bffb16b6633a8ba3df (patch)
tree16550c644702a55ee4a2e4bfd94bde5ea80a80ea
parentf2eb959463914d0928d20fda3fb860365e57ea9f (diff)
downloadexynos5-25ffbfe5e8b51f392fafc1bffb16b6633a8ba3df.tar.gz
exynos: gralloc: implement gralloc_lock_ycbcr
Support only NV12 TILED format used by video decoder for surface output. Bug: 19179288 Change-Id: Iac345ca76cb856a39031d82ee1bbb6177c09a30d
-rw-r--r--gralloc/gralloc.cpp10
-rw-r--r--gralloc/mapper.cpp102
2 files changed, 107 insertions, 5 deletions
diff --git a/gralloc/gralloc.cpp b/gralloc/gralloc.cpp
index b5f269b..8e26ced 100644
--- a/gralloc/gralloc.cpp
+++ b/gralloc/gralloc.cpp
@@ -71,6 +71,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);
@@ -80,6 +85,9 @@ extern int gralloc_register_buffer(gralloc_module_t const* module,
extern int gralloc_unregister_buffer(gralloc_module_t const* module,
buffer_handle_t handle);
+extern int gralloc_perform(struct gralloc_module_t const* module,
+ int operation, ... );
+
/*****************************************************************************/
static struct hw_module_methods_t gralloc_module_methods = {
@@ -101,6 +109,8 @@ base: {
unregisterBuffer: gralloc_unregister_buffer,
lock: gralloc_lock,
unlock: gralloc_unlock,
+ perform: gralloc_perform,
+ lock_ycbcr: gralloc_lock_ycbcr,
},
framebuffer: 0,
flags: 0,
diff --git a/gralloc/mapper.cpp b/gralloc/mapper.cpp
index 1a70973..190a7a7 100644
--- a/gralloc/mapper.cpp
+++ b/gralloc/mapper.cpp
@@ -31,6 +31,7 @@
#include <hardware/gralloc.h>
#include "gralloc_priv.h"
+#include "exynos_format.h"
#include <ion/ion.h>
#include <linux/ion.h>
@@ -57,16 +58,59 @@ static int gralloc_unmap(gralloc_module_t const* module, buffer_handle_t handle)
{
private_handle_t* hnd = (private_handle_t*)handle;
- if (!hnd->base)
- return 0;
-
- if (munmap(hnd->base, hnd->size) < 0) {
+ if (hnd->base != NULL && munmap(hnd->base, hnd->size) < 0) {
ALOGE("%s :could not unmap %s %p %d", __func__, strerror(errno),
hnd->base, hnd->size);
}
+ hnd->base = NULL;
+ if (hnd->base1 != NULL && hnd->format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
+ // unmap plane-2 of mapped NV12 TILED format
+ size_t chroma_vstride = ALIGN(hnd->height / 2, 32);
+ size_t chroma_size = chroma_vstride * hnd->stride;
+ if (munmap(hnd->base1, chroma_size) < 0) {
+ ALOGE("%s :could not unmap %s %p %zd", __func__, strerror(errno),
+ hnd->base1, chroma_size);
+ }
+ hnd->base1 = NULL;
+ }
ALOGV("%s: base %p %d %d %d %d\n", __func__, hnd->base, hnd->size,
hnd->width, hnd->height, hnd->stride);
- hnd->base = 0;
+ return 0;
+}
+
+
+static int gralloc_map_yuv(gralloc_module_t const* module, buffer_handle_t handle)
+{
+ private_handle_t* hnd = (private_handle_t*)handle;
+
+ // only support NV12 TILED format
+ if (hnd->format != HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
+ return -EINVAL;
+ }
+
+ size_t chroma_vstride = ALIGN(hnd->height / 2, 32);
+ size_t chroma_size = chroma_vstride * hnd->stride;
+ ALOGI("map_yuv: size=%d/%zu", hnd->size, chroma_size);
+
+ if (hnd->base == NULL) {
+ int err = gralloc_map(module, handle);
+ if (err != 0) {
+ return err;
+ }
+ }
+
+ // map plane-2 for NV12 TILED format
+ void* mappedAddress = mmap(0, chroma_size, PROT_READ|PROT_WRITE, MAP_SHARED,
+ hnd->fd1, 0);
+ if (mappedAddress == MAP_FAILED) {
+ ALOGE("%s: could not mmap %s", __func__, strerror(errno));
+ gralloc_unmap(module, handle);
+ return -errno;
+ }
+
+ ALOGV("%s: chroma %p %d %d %d %d\n", __func__, mappedAddress, hnd->size,
+ hnd->width, hnd->height, hnd->stride);
+ hnd->base1 = mappedAddress;
return 0;
}
@@ -157,6 +201,54 @@ int gralloc_lock(gralloc_module_t const* module,
return 0;
}
+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)
+{
+ // This is called when a YUV buffer is being locked for software
+ // access. In this implementation we have nothing to do since
+ // no synchronization with the HW is needed.
+ // Typically this is used to wait for the h/w to finish with
+ // this buffer if relevant. The data cache may need to be
+ // flushed or invalidated depending on the usage bits and the
+ // hardware.
+
+ if (private_handle_t::validate(handle) < 0)
+ return -EINVAL;
+
+ private_handle_t* hnd = (private_handle_t*)handle;
+ ALOGV("lock_ycbcr for fmt=%d %dx%d %dx%d %d", hnd->format, hnd->width, hnd->height,
+ hnd->stride, hnd->vstride, hnd->size);
+ switch (hnd->format) {
+ case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
+ {
+ int err = 0;
+ if (hnd->base1 == NULL || hnd->base == NULL) {
+ err = gralloc_map_yuv(module, hnd);
+ }
+ if (err == 0) {
+ ycbcr->y = (void*)hnd->base;
+ ycbcr->cb = (void*)hnd->base1;
+ ycbcr->cr = (void*)((uint8_t *)hnd->base + 1);
+ ycbcr->ystride = hnd->stride;
+ ycbcr->cstride = hnd->stride;
+ ycbcr->chroma_step = 2;
+ memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
+ }
+ return err;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+int gralloc_perform(struct gralloc_module_t const* module, int operation, ... )
+{
+ // dummy implementation required to implement lock_ycbcr
+ return -EINVAL;
+}
+
int gralloc_unlock(gralloc_module_t const* module,
buffer_handle_t handle)
{