/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>

#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/ioctl.h>

#include <hardware/exynos/ion.h>
#include <linux/ion.h>
#include <exynos_ion.h>
#include <log/log.h>
#include <cutils/atomic.h>

#include <hardware/hardware.h>
#include <hardware/gralloc.h>

#include "gralloc_priv.h"
#include "exynos_format.h"
#include "gr.h"

#include "VendorVideoAPI.h"
#define PRIV_SIZE sizeof(ExynosVideoMeta)

#define MSCL_EXT_SIZE 512
#define MSCL_ALIGN 128

#if MALI_AFBC_GRALLOC == 1 /* It's for AFBC support on GPU DDK*/
#include "format_chooser.h"
#define GRALLOC_ARM_INTFMT_EXTENSION_BIT_START     32
/* This format will be use AFBC */
#define GRALLOC_ARM_INTFMT_AFBC                 (1ULL << (GRALLOC_ARM_INTFMT_EXTENSION_BIT_START+0))

#define AFBC_PIXELS_PER_BLOCK                    16
#define AFBC_BODY_BUFFER_BYTE_ALIGNMENT          1024
#define AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY  16
#endif

/*****************************************************************************/

struct gralloc_context_t {
    alloc_device_t  device;
    /* our private data here */
};

/*****************************************************************************/

int fb_device_open(const hw_module_t* module, const char* name,
                   hw_device_t** device);

static int gralloc_device_open(const hw_module_t* module, const char* name,
                               hw_device_t** device);

extern int gralloc_lock(gralloc_module_t const* module,
                        buffer_handle_t handle, int usage,
                        int l, int t, int w, int h,
                        void** vaddr);

extern int gralloc_unlock(gralloc_module_t const* module,
                          buffer_handle_t handle);

extern int gralloc_lock_ycbcr(gralloc_module_t const* module,
                        buffer_handle_t handle, int usage,
                        int l, int t, int w, int h,
                        android_ycbcr *ycbcr);

extern int gralloc_register_buffer(gralloc_module_t const* module,
                                   buffer_handle_t handle);

extern int gralloc_unregister_buffer(gralloc_module_t const* module,
                                     buffer_handle_t handle);

/*****************************************************************************/

static struct hw_module_methods_t gralloc_module_methods = {
    gralloc_device_open
};

/* version_major is for module_api_verison
 * lock_ycbcr is for MODULE_API_VERSION_0_2
 */
struct private_module_t HAL_MODULE_INFO_SYM = {
.base = {
    .common = {
        .tag = HARDWARE_MODULE_TAG,
        .module_api_version = GRALLOC_MODULE_API_VERSION_0_2,
        .hal_api_version = 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,
    .perform = NULL,
    .lock_ycbcr = gralloc_lock_ycbcr,
},
.framebuffer = 0,
.flags = 0,
.numBuffers = 0,
.bufferMask = 0,
.lock = PTHREAD_MUTEX_INITIALIZER,
.currentBuffer = 0,
.ionfd = -1,
};

/*****************************************************************************/

static unsigned int _select_heap(int usage)
{
    unsigned int heap_mask;
#ifdef USES_EXYNOS_COMMON_GRALLOC
    if (usage & GRALLOC_USAGE_PROTECTED) {
        if (usage & GRALLOC_USAGE_PRIVATE_NONSECURE && !(usage & GRALLOC_USAGE_PHYSICALLY_LINEAR))
            heap_mask = ION_HEAP_SYSTEM_MASK;
        else
            heap_mask = ION_HEAP_EXYNOS_CONTIG_MASK;
    } else if (usage & GRALLOC_USAGE_CAMERA_RESERVED) {
        heap_mask = EXYNOS_ION_HEAP_CAMERA;
    } else if ((usage & GRALLOC_USAGE_PRIVATE_NONSECURE) && (usage & GRALLOC_USAGE_PHYSICALLY_LINEAR)) {
        heap_mask = EXYNOS_ION_HEAP_CRYPTO_MASK;
    } else if (usage & GRALLOC_USAGE_SECURE_CAMERA_RESERVED) {
        heap_mask = EXYNOS_ION_HEAP_SECURE_CAMERA;
    } else {
        heap_mask = ION_HEAP_SYSTEM_MASK;
    }
#else
	if (usage & GRALLOC_USAGE_PROTECTED)
		heap_mask = ION_HEAP_EXYNOS_CONTIG_MASK;
	else
		heap_mask = ION_HEAP_SYSTEM_MASK;
#endif

    return heap_mask;
}

/*
 * Define GRALLOC_ARM_FORMAT_SELECTION_DISABLE to disable the format selection completely
 */
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 bpr = 0, ext_size=256, size = 0, size1 = 0;
    int bpp = 0, vstride = 0;
    int fd = -1, fd1 = -1;

    unsigned int heap_mask = _select_heap(usage);
    int is_compressible = check_for_compression(w, h, format, usage);

    switch (format) {
        case HAL_PIXEL_FORMAT_RGBA_FP16:
            bpp = 8;
            break;
        case HAL_PIXEL_FORMAT_EXYNOS_ARGB_8888:
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
        case HAL_PIXEL_FORMAT_BGRA_8888:
        case HAL_PIXEL_FORMAT_RGBA_1010102:
            bpp = 4;
            break;
        case HAL_PIXEL_FORMAT_RGB_888:
            bpp = 3;
            break;
        case HAL_PIXEL_FORMAT_RGB_565:
        case HAL_PIXEL_FORMAT_RAW16:
        case HAL_PIXEL_FORMAT_RAW_OPAQUE:
            bpp = 2;
            break;
        case HAL_PIXEL_FORMAT_BLOB:
            *stride = w;
            vstride = h;
            size = w * h;
            break;
        default:
            return -EINVAL;
    }

    if (format != HAL_PIXEL_FORMAT_BLOB) {
        bpr = ALIGN(w, 16)* bpp;
        vstride = ALIGN(h, 16);

        if (vstride < h + 2)
            size = bpr * (h + 2);
        else
            size = bpr * vstride;

        *stride = bpr / bpp;
        size = size + ext_size;
        if (is_compressible)
        {
            /* if is_compressible = 1, width is alread 16 align so we can use width instead of w_aligned*/
            int h_aligned = ALIGN( h, AFBC_PIXELS_PER_BLOCK );
            int nblocks = *stride / AFBC_PIXELS_PER_BLOCK * h_aligned / AFBC_PIXELS_PER_BLOCK;

            size = *stride * h_aligned * bpp +
                ALIGN( nblocks * AFBC_HEADER_BUFFER_BYTES_PER_BLOCKENTRY, AFBC_BODY_BUFFER_BYTE_ALIGNMENT ) + ext_size;
        }
#ifdef GRALLOC_MSCL_ALIGN_RESTRICTION
        if (w % MSCL_ALIGN)
            size += MSCL_EXT_SIZE;
#endif
    }

    if (usage & GRALLOC_USAGE_PROTECTED) {
        if ((usage & GRALLOC_USAGE_PRIVATE_NONSECURE) && (usage & GRALLOC_USAGE_PHYSICALLY_LINEAR))
            ion_flags |= ION_EXYNOS_G2D_WFD_MASK;
        else if (usage & GRALLOC_USAGE_VIDEO_EXT)
            ion_flags |= (ION_EXYNOS_VIDEO_EXT_MASK | ION_FLAG_PROTECTED);
        else if ((usage & GRALLOC_USAGE_HW_COMPOSER) &&
            !(usage & GRALLOC_USAGE_HW_TEXTURE) && !(usage & GRALLOC_USAGE_HW_RENDER)) {
            // For DRM Playback
            ion_flags |= (ION_EXYNOS_FIMD_VIDEO_MASK | ION_FLAG_PROTECTED);
        }
        else
            ion_flags |= (ION_EXYNOS_MFC_OUTPUT_MASK | ION_FLAG_PROTECTED);
    } else if ((usage & GRALLOC_USAGE_PRIVATE_NONSECURE) && (usage & GRALLOC_USAGE_PHYSICALLY_LINEAR)) {
        ion_flags |= ION_FLAG_PROTECTED;
    }

    fd = exynos_ion_alloc(ionfd, size, heap_mask, ion_flags);
    if (fd < 0)
    {
        ALOGE("failed to get fd from exynos_ion_alloc, %s, %d\n", __func__, __LINE__);
        return -EINVAL;
    }
    else
    {
        // Alloc for AFBC data
        if (is_compressible)
        {
            size1 = AFBC_INFO_SIZE;
            fd1 = exynos_ion_alloc(ionfd, size1, EXYNOS_ION_HEAP_SYSTEM_MASK, 0);
            if (fd1 < 0)
            {
                ALOGE("failed to get fd1 from exynos_ion_alloc, %s, %d\n", __func__, __LINE__);
                close(fd);
                return -EINVAL;
            }
        }
    }

    *hnd = new private_handle_t(fd, fd1, -1, size, size1, 0,
                    usage, w, h, format, format, format, *stride,
                    vstride, is_compressible);

    return 0;
}

static int gralloc_alloc_framework_yuv(int ionfd, int w, int h, int format, int frameworkFormat,
                                       int usage, unsigned int ion_flags,
                                       private_handle_t **hnd, int *stride)
{
    size_t size=0, ext_size=256;
    int fd = -1;
    unsigned int heap_mask = _select_heap(usage);
    int is_compressible = 0;

    switch (format) {
        case HAL_PIXEL_FORMAT_YV12:
        case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
            *stride = ALIGN(w, 16);
            size = (*stride * h) + (ALIGN(*stride / 2, 16) * h) + ext_size;
            break;
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
            *stride = w;
            size = *stride * h * 3 / 2 + ext_size;
            break;
        case HAL_PIXEL_FORMAT_Y8:
            *stride = ALIGN(w, 16);
            size = *stride * h;
            break;
        case HAL_PIXEL_FORMAT_Y16:
            *stride = ALIGN(w, 16);
            size = (*stride * h) * 2;
            break;
        default:
            ALOGE("invalid yuv format %d\n", format);
            return -EINVAL;
    }

#ifdef GRALLOC_MSCL_ALIGN_RESTRICTION
    if (w % MSCL_ALIGN)
        size += MSCL_EXT_SIZE;
#endif

    if (frameworkFormat == HAL_PIXEL_FORMAT_YCbCr_420_888)
        *stride = 0;

    fd = exynos_ion_alloc(ionfd, size, heap_mask, ion_flags);
    if (fd < 0)
    {
        ALOGE("failed to get fd from exynos_ion_alloc, %s, %d\n", __func__, __LINE__);
        return -EINVAL;
    }

    *hnd = new private_handle_t(fd, -1, -1, size, 0, 0,
                    usage, w, h, format, format, frameworkFormat, *stride, h, is_compressible);
    return 0;
}

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=0, chroma_size=0, ext_size=256;
    int planes = 0, fd = -1, fd1 = -1, fd2 = -1;
    size_t luma_vstride = 0;
    unsigned int heap_mask = _select_heap(usage);
    // Keep around original requested format for later validation
    int frameworkFormat = format;
    int is_compressible = 0;
    uint64_t internal_format = 0;
    int size = 0, size1 = 0, size2 = 0;

    *stride = ALIGN(w, 16);
    luma_vstride = ALIGN(h, 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) || (usage & GRALLOC_USAGE_HW_COMPOSER)) {
            if (usage & GRALLOC_USAGE_YUV_RANGE_FULL)
                format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL; // NV21M Full
            else
                format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M;	//NV21M narrow
        } else if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
            format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M;	//NV21M narrow
        } else {
            format = HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M;	//NV21M narrow
        }
    }
    else if (format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
        if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
            format = HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M;
        } else {
            // Flexible framework-accessible YUV format; map to NV21 for now
            format = HAL_PIXEL_FORMAT_YCrCb_420_SP;
        }
    }

    if (usage & GRALLOC_USAGE_PROTECTED) {
        ion_flags |= ION_FLAG_PROTECTED;
        if (usage & GRALLOC_USAGE_VIDEO_EXT)
            ion_flags |= ION_EXYNOS_VIDEO_EXT_MASK;
        else if ((usage & GRALLOC_USAGE_HW_COMPOSER) &&
            !(usage & GRALLOC_USAGE_HW_TEXTURE) && !(usage & GRALLOC_USAGE_HW_RENDER)) {
            // For DRM Playback
            ion_flags |= ION_EXYNOS_FIMD_VIDEO_MASK;
        }
        else
            ion_flags |= ION_EXYNOS_MFC_OUTPUT_MASK;
    } else if (usage & GRALLOC_USAGE_CAMERA_RESERVED)
        ion_flags |= ION_EXYNOS_MFC_OUTPUT_MASK;

    // Sync iinternal_format with format
    internal_format = format;

    switch (format) {
        case HAL_PIXEL_FORMAT_EXYNOS_YV12_M:
        case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P_M:
            {
                *stride = ALIGN(w, 32);
                luma_size = luma_vstride * *stride + ext_size;
#ifdef EXYNOS_CHROMA_VSTRIDE_ALIGN
                chroma_size = ALIGN(luma_vstride / 2, CHROMA_VALIGN) * ALIGN(*stride / 2, 16) + ext_size;
#else
                chroma_size = (luma_vstride / 2) * ALIGN(*stride / 2, 16) + ext_size;
#endif
                planes = 3;
                break;
            }
        case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_TILED:
            {
                size_t chroma_vstride = ALIGN(h / 2, 32);
                luma_vstride = ALIGN(h, 32);
                luma_size = luma_vstride * *stride + ext_size;
                chroma_size = chroma_vstride * *stride + ext_size;
                planes = 2;
                break;
            }
        case HAL_PIXEL_FORMAT_YV12:
        case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_P:
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
        case HAL_PIXEL_FORMAT_Y8:
        case HAL_PIXEL_FORMAT_Y16:
            return gralloc_alloc_framework_yuv(ionfd, w, h, format, frameworkFormat, usage,
                                               ion_flags, hnd, stride);
        case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M:
        case HAL_PIXEL_FORMAT_EXYNOS_YCrCb_420_SP_M_FULL:
        case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M:
            {
                luma_size = *stride * luma_vstride+ext_size;
#ifdef EXYNOS_CHROMA_VSTRIDE_ALIGN
                chroma_size = *stride * ALIGN(luma_vstride / 2, CHROMA_VALIGN)+ext_size;
#else
                chroma_size = *stride * ALIGN(luma_vstride / 2, 8)+ext_size;
#endif
                planes = 2;
                break;
            }
        case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV:
            {
                luma_vstride = ALIGN(h, 32);
                luma_size = *stride * luma_vstride+ext_size;
                chroma_size = *stride * ALIGN(luma_vstride / 2, 8)+ext_size;
                planes = 3;
                break;
            }
        case HAL_PIXEL_FORMAT_YCbCr_422_I:
            {
                luma_vstride = h;
                luma_size = luma_vstride * *stride * 2+ext_size;
                planes = 1;
                break;
            }
        case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN:
            {
#ifdef EXYNOS_CHROMA_VSTRIDE_ALIGN
                chroma_size = ALIGN((*stride * ALIGN(luma_vstride / 2, CHROMA_VALIGN)) + ext_size, 16);
#else
                chroma_size = ALIGN((*stride * luma_vstride / 2) + ext_size, 16);
#endif
                luma_size = (*stride * luma_vstride) + ext_size + chroma_size;
                planes = 1;
                break;
            }
        case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B:
            {
#ifdef GRALLOC_10B_ALIGN_RESTRICTION
                luma_size = (*stride * luma_vstride + ext_size) + ((ALIGN(w / 4, 16) * luma_vstride) + ext_size);
                chroma_size = (*stride * luma_vstride / 2 + ext_size) + ((ALIGN(w / 4, 16) * (luma_vstride / 2)) + ext_size);
#else
                luma_size = (*stride * luma_vstride + ext_size) + ((ALIGN(w / 4, 16) * h) + ext_size);
                chroma_size = (*stride * luma_vstride / 2 + ext_size) + ((ALIGN(w / 4, 16) * (h / 2)) + ext_size);
#endif
                planes = 3;
                break;
            }
        case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SPN_S10B:
            {
                chroma_size = ALIGN((*stride * luma_vstride / 2) + ext_size, 16) + (ALIGN(w / 4, 16) * (luma_vstride / 2)) + 64;
                luma_size = (*stride * luma_vstride) + ext_size + (ALIGN(w / 4, 16) * luma_vstride) + 64 + chroma_size;
                planes = 1;
                break;
            }
        case HAL_PIXEL_FORMAT_EXYNOS_YCbCr_P010_M:
            {
                chroma_size = ((*stride * 2) * luma_vstride / 2) + ext_size;
                luma_size = ((*stride * 2) * luma_vstride) + ext_size;
                planes = 3;
                break;
            }
        default:
            ALOGE("invalid yuv format %d\n", format);
            return -EINVAL;
    }

#ifdef GRALLOC_MSCL_ALIGN_RESTRICTION
    if (w % MSCL_ALIGN) {
        luma_size += MSCL_EXT_SIZE;
        chroma_size += MSCL_EXT_SIZE/2;
    }
#endif

    size = luma_size;
    fd = exynos_ion_alloc(ionfd, size, heap_mask, ion_flags);
    if (fd < 0) {
		ALOGE("failed to get fd from exynos_ion_alloc, %s, %d\n", __func__, __LINE__);
		return -EINVAL;
    }

    if (planes == 1) {
        *hnd = new private_handle_t(fd, -1, -1, size, 0, 0, usage, w, h,
                                    format, internal_format, frameworkFormat, *stride, luma_vstride, is_compressible);
    } else {
        size1 = chroma_size;
        fd1 = exynos_ion_alloc(ionfd, size1, heap_mask, ion_flags);
        if (fd1 < 0)
        {
            ALOGE("failed to get fd from exynos_ion_alloc, %s, %d\n", __func__, __LINE__);
            close(fd);
            return -EINVAL;
        }

        if (planes == 3) {
            if ((format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_PRIV) ||
                (format == HAL_PIXEL_FORMAT_EXYNOS_YCbCr_420_SP_M_S10B)) {
                size2 = PRIV_SIZE;
                fd2 = exynos_ion_alloc(ionfd, size2, ION_HEAP_SYSTEM_MASK, 0);
            } else {
                size2 = chroma_size;
                fd2 = exynos_ion_alloc(ionfd, size2, heap_mask, ion_flags);
            }
            if (fd2 < 0)
            {
                ALOGE("failed to get fd2 from exynos_ion_alloc, %s, %d\n", __func__, __LINE__);
                close(fd);
                close(fd1);
                return -EINVAL;
            }

            *hnd = new private_handle_t(fd, fd1, fd2, size, size1, size2, usage, w, h,
                                        format, internal_format, frameworkFormat, *stride, luma_vstride, is_compressible);
        } else {
            *hnd = new private_handle_t(fd, fd1, -1, size, size1, 0, usage, w, h,
                                        format, internal_format, frameworkFormat, *stride, luma_vstride, is_compressible);
        }
    }

    return 0;
}

static int gralloc_alloc(alloc_device_t* dev,
                         int w, int h, int format, int usage,
                         buffer_handle_t* pHandle, int* pStride)
{
    int stride;
    int err;
    unsigned int ion_flags = 0;
    private_handle_t *hnd = NULL;

    if (!pHandle || !pStride || w <= 0 || h <= 0)
        return -EINVAL;

    if ((usage & GRALLOC_USAGE_SW_READ_MASK) == GRALLOC_USAGE_SW_READ_OFTEN) {
        ion_flags = ION_FLAG_CACHED | ION_FLAG_CACHED_NEEDS_SYNC;
        if (usage & GRALLOC_USAGE_HW_RENDER)
            ion_flags |= ION_FLAG_SYNC_FORCE;
    }

    if (usage & GRALLOC_USAGE_HW_RENDER)
        ion_flags |= ION_FLAG_MAY_HWRENDER;

    if (usage & GRALLOC_USAGE_NOZEROED)
        ion_flags |= ION_FLAG_NOZEROED;

    private_module_t* m = reinterpret_cast<private_module_t*>
        (dev->common.module);

    err = gralloc_alloc_rgb(m->ionfd, w, h, format, usage, ion_flags, &hnd,
                            &stride);
    if (err)
        err = gralloc_alloc_yuv(m->ionfd, w, h, format, usage, ion_flags,
                                &hnd, &stride);
    if (err)
        goto err;

    *pHandle = hnd;
    *pStride = stride;
    return 0;
err:
    if (!hnd)
        return err;
    close(hnd->fd);
    if (hnd->fd1 >= 0)
        close(hnd->fd1);
    if (hnd->fd2 >= 0)
        close(hnd->fd2);
    delete hnd;
    return err;
}

static int gralloc_free(alloc_device_t* dev,
                        buffer_handle_t handle)
{
    if (private_handle_t::validate(handle) < 0)
        return -EINVAL;

    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(const_cast<private_handle_t*>(hnd));

    if (hnd->handle)
        exynos_ion_free_handle(getIonFd(module), hnd->handle);
    if (hnd->handle1)
        exynos_ion_free_handle(getIonFd(module), hnd->handle1);
    if (hnd->handle2)
        exynos_ion_free_handle(getIonFd(module), hnd->handle2);

    close(hnd->fd);
    if (hnd->fd1 >= 0)
        close(hnd->fd1);
    if (hnd->fd2 >= 0)
        close(hnd->fd2);

    delete hnd;
    return 0;
}

/*****************************************************************************/

static int gralloc_close(struct hw_device_t *dev)
{
    gralloc_context_t* ctx = reinterpret_cast<gralloc_context_t*>(dev);
    if (ctx) {
        /* TODO: keep a list of all buffer_handle_t created, and free them
         * all here.
         */
        free(ctx);
    }
    return 0;
}

int gralloc_device_open(const hw_module_t* module, const char* name,
                        hw_device_t** device)
{
    int status = -EINVAL;
    if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
        gralloc_context_t *dev;
        dev = (gralloc_context_t*)malloc(sizeof(*dev));

        /* initialize our state here */
        memset(dev, 0, sizeof(*dev));

        /* initialize the procs */
        dev->device.common.tag = HARDWARE_DEVICE_TAG;
        dev->device.common.version = 0;
        dev->device.common.module = const_cast<hw_module_t*>(module);
        dev->device.common.close = gralloc_close;

        dev->device.alloc = gralloc_alloc;
        dev->device.free = gralloc_free;

        private_module_t *p = reinterpret_cast<private_module_t*>(dev->device.common.module);
        if (p->ionfd == -1)
            p->ionfd = exynos_ion_open();

        *device = &dev->device.common;
        status = 0;
    } else {
        status = fb_device_open(module, name, device);
    }
    return status;
}
