#include "exynos_format.h"
#include "gr.h"
+#define ION_HEAP_EXYNOS_CONTIG_MASK (1 << 4)
+#define ION_EXYNOS_FIMD_VIDEO_MASK (1 << 28)
+#define ION_EXYNOS_MFC_OUTPUT_MASK (1 << 26)
+#define ION_EXYNOS_MFC_INPUT_MASK (1 << 25)
+#define MB_1 (1024*1024)
+
+
/*****************************************************************************/
struct gralloc_context_t {
struct private_module_t HAL_MODULE_INFO_SYM = {
base: {
-common: {
-tag: HARDWARE_MODULE_TAG,
- version_major: 1,
- version_minor: 0,
- id: GRALLOC_HARDWARE_MODULE_ID,
- name: "Graphics Memory Allocator Module",
- author: "The Android Open Source Project",
- methods: &gralloc_module_methods
- },
+ common: {
+ tag: HARDWARE_MODULE_TAG,
+ version_major: 1,
+ version_minor: 0,
+ id: GRALLOC_HARDWARE_MODULE_ID,
+ name: "Graphics Memory Allocator Module",
+ author: "The Android Open Source Project",
+ methods: &gralloc_module_methods
+ },
registerBuffer: gralloc_register_buffer,
unregisterBuffer: gralloc_unregister_buffer,
lock: gralloc_lock,
unlock: gralloc_unlock,
- },
- framebuffer: 0,
- flags: 0,
- numBuffers: 0,
- bufferMask: 0,
- lock: PTHREAD_MUTEX_INITIALIZER,
- currentBuffer: 0,
- ionfd: -1,
+},
+framebuffer: 0,
+flags: 0,
+numBuffers: 0,
+bufferMask: 0,
+lock: PTHREAD_MUTEX_INITIALIZER,
+currentBuffer: 0,
+ionfd: -1,
};
/*****************************************************************************/
-#define ALIGN(x, a) (((x) + (a - 1)) & ~(a - 1))
+static unsigned int _select_heap(int usage)
+{
+ unsigned int heap_mask;
+
+ if (usage & GRALLOC_USAGE_PROTECTED)
+ heap_mask = ION_HEAP_EXYNOS_CONTIG_MASK;
+ else
+ heap_mask = ION_HEAP_SYSTEM_MASK;
+
+ return heap_mask;
+}
static int gralloc_alloc_rgb(int ionfd, int w, int h, int format, int usage,
unsigned int ion_flags, private_handle_t **hnd, int *stride)
{
- size_t size, bpr;
+ size_t size, bpr, alignment = 0;
int bpp = 0, vstride, fd, err;
+ unsigned int heap_mask = _select_heap(usage);
+
switch (format) {
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
bpp = 2;
break;
case HAL_PIXEL_FORMAT_BLOB:
- bpp = 1;
+ *stride = w;
+ vstride = h;
+ size = w * h;
break;
default:
return -EINVAL;
}
- bpr = ALIGN(w*bpp, 16);
- vstride = ALIGN(h, 16);
- size = bpr * vstride;
- *stride = bpr / bpp;
- size = ALIGN(size, PAGE_SIZE);
- err = ion_alloc_fd(ionfd, size, 0, 1 << ION_HEAP_TYPE_SYSTEM, ion_flags,
+ if (format != HAL_PIXEL_FORMAT_BLOB) {
+ bpr = ALIGN(w*bpp, 16);
+ vstride = ALIGN(h, 16);
+ if (vstride < h + 2)
+ size = bpr * (h + 2);
+ else
+ size = bpr * vstride;
+ *stride = bpr / bpp;
+ size = ALIGN(size, PAGE_SIZE);
+ }
+
+ if (usage & GRALLOC_USAGE_PROTECTED) {
+ alignment = MB_1;
+ ion_flags |= ION_EXYNOS_FIMD_VIDEO_MASK;
+ }
+
+ err = ion_alloc_fd(ionfd, size, alignment, heap_mask, ion_flags,
&fd);
*hnd = new private_handle_t(fd, size, usage, w, h, format, *stride,
vstride);
return err;
}
-static int gralloc_alloc_yuv(int ionfd, int w, int h, int format, int usage,
- unsigned int ion_flags, private_handle_t **hnd, int *stride)
+static int gralloc_alloc_framework_yuv(int ionfd, int w, int h, int format,
+ int usage, unsigned int ion_flags,
+ private_handle_t **hnd, int *stride)
+{
+ size_t size;
+ int err, fd;
+
+ switch (format) {
+ case HAL_PIXEL_FORMAT_YV12:
+ *stride = ALIGN(w, 16);
+ break;
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ *stride = w;
+ break;
+ default:
+ ALOGE("invalid yuv format %d\n", format);
+ return -EINVAL;
+ }
+
+ size = *stride * h * 3 / 2;
+ err = ion_alloc_fd(ionfd, size, 0, 1 << ION_HEAP_TYPE_SYSTEM,
+ ion_flags, &fd);
+ if (err)
+ return err;
+
+ *hnd = new private_handle_t(fd, size, usage, w, h, format, *stride, h);
+ return err;
+}
+
+static int gralloc_alloc_yuv(int ionfd, int w, int h, int format,
+ int usage, unsigned int ion_flags,
+ private_handle_t **hnd, int *stride)
{
size_t luma_size, chroma_size;
int err, planes, fd, fd1, fd2 = 0;
size_t luma_vstride;
+ unsigned int heap_mask = _select_heap(usage);
+
*stride = ALIGN(w, 16);
+ if (format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+ ALOGV("HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED : usage(%x), flags(%x)\n", usage, ion_flags);
+ if ((usage & GRALLOC_USAGE_HW_CAMERA_ZSL) == GRALLOC_USAGE_HW_CAMERA_ZSL) {
+ format = HAL_PIXEL_FORMAT_YCbCr_422_I; // YUYV
+ } else if (usage & GRALLOC_USAGE_HW_TEXTURE) {
+ format = HAL_PIXEL_FORMAT_EXYNOS_YV12;
+ } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
+ format = HAL_PIXEL_FORMAT_YCbCr_420_SP; // NV12M
+ }
+ }
switch (format) {
- ALOGE("invalid yuv format %d\n", format);
case HAL_PIXEL_FORMAT_EXYNOS_YV12:
- {
- luma_vstride = ALIGN(h, 16);
- luma_size = luma_vstride * *stride;
- chroma_size = (luma_vstride / 2) * ALIGN(*stride / 2, 16);
- planes = 3;
- break;
- }
+ {
+ *stride = ALIGN(w, 32);
+ luma_vstride = ALIGN(h, 16);
+ luma_size = luma_vstride * *stride;
+ chroma_size = (luma_vstride / 2) * ALIGN(*stride / 2, 16);
+ planes = 3;
+ break;
+ }
case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP:
case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED:
- {
- size_t chroma_vstride = ALIGN(h / 2, 32);
- luma_vstride = ALIGN(h, 32);
- luma_size = luma_vstride * *stride;
- chroma_size = chroma_vstride * *stride;
- planes = 2;
- break;
- }
+ {
+ size_t chroma_vstride = ALIGN(h / 2, 32);
+ luma_vstride = ALIGN(h, 32);
+ luma_size = luma_vstride * *stride;
+ chroma_size = chroma_vstride * *stride;
+ planes = 2;
+ break;
+ }
+ case HAL_PIXEL_FORMAT_YV12:
+ case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+ return gralloc_alloc_framework_yuv(ionfd, w, h, format, usage,
+ ion_flags, hnd, stride);
+ case HAL_PIXEL_FORMAT_YCbCr_422_I:
+ {
+ luma_vstride = h;
+ luma_size = luma_vstride * *stride * 2;
+ chroma_size = 0;
+ planes = 1;
+ break;
+ }
default:
- ALOGE("invalid yuv format %d\n", format);
- return -EINVAL;
+ ALOGE("invalid yuv format %d\n", format);
+ return -EINVAL;
}
- err = ion_alloc_fd(ionfd, luma_size, 0, 1 << ION_HEAP_TYPE_SYSTEM,
- ion_flags, &fd);
+ if (usage & GRALLOC_USAGE_PROTECTED)
+ ion_flags |= ION_EXYNOS_MFC_OUTPUT_MASK;
+
+ err = ion_alloc_fd(ionfd, luma_size, 0, heap_mask, ion_flags, &fd);
if (err)
return err;
- err = ion_alloc_fd(ionfd, chroma_size, 0, 1 << ION_HEAP_TYPE_SYSTEM,
- ion_flags,
- &fd1);
- if (err)
- goto err1;
- if (planes == 3) {
- err = ion_alloc_fd(ionfd, chroma_size, 0, 1 << ION_HEAP_TYPE_SYSTEM,
- ion_flags, &fd2);
- if (err)
- goto err2;
-
- *hnd = new private_handle_t(fd, fd1, fd2, luma_size, usage, w, h,
+ if (planes == 1) {
+ *hnd = new private_handle_t(fd, luma_size, usage, w, h,
format, *stride, luma_vstride);
} else {
- *hnd = new private_handle_t(fd, fd1, luma_size, usage, w, h, format,
- *stride, luma_vstride);
+ err = ion_alloc_fd(ionfd, chroma_size, 0, heap_mask, ion_flags, &fd1);
+ if (err)
+ goto err1;
+ if (planes == 3) {
+ err = ion_alloc_fd(ionfd, chroma_size, 0, heap_mask, ion_flags, &fd2);
+ if (err)
+ goto err2;
+
+ *hnd = new private_handle_t(fd, fd1, fd2, luma_size, usage, w, h,
+ format, *stride, luma_vstride);
+ } else {
+ *hnd = new private_handle_t(fd, fd1, luma_size, usage, w, h, format,
+ *stride, luma_vstride);
+ }
}
return err;
int stride;
int err;
unsigned int ion_flags = 0;
- private_handle_t *hnd;
+ private_handle_t *hnd = NULL;
if (!pHandle || !pStride)
return -EINVAL;
if( (usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN )
- ion_flags = ION_FLAG_CACHED;
+ ion_flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
private_module_t* m = reinterpret_cast<private_module_t*>
(dev->common.module);
if (err)
return err;
- err = grallocMap(module, hnd);
-
if (err != 0)
goto err;
*pStride = stride;
return 0;
err:
+ if (!hnd)
+ return err;
close(hnd->fd);
if (hnd->fd1 >= 0)
close(hnd->fd1);
private_handle_t const* hnd = reinterpret_cast<private_handle_t const*>(handle);
gralloc_module_t* module = reinterpret_cast<gralloc_module_t*>(
dev->common.module);
+ if (hnd->base)
+ grallocUnmap(module, const_cast<private_handle_t*>(hnd));
- grallocUnmap(module, const_cast<private_handle_t*>(hnd));
close(hnd->fd);
if (hnd->fd1 >= 0)
close(hnd->fd1);