/*
 * Copyright (C) 2008 The Android Open Source Project
 * Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
 *
 * Not a Contribution, Apache license notifications and license are retained
 * for attribution purposes only.
 *
 * 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 <cutils/log.h>
#include <sys/resource.h>
#include <sys/prctl.h>

#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>

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

#include <linux/msm_kgsl.h>

#include <EGL/eglplatform.h>
#include <cutils/native_handle.h>
#include <gralloc_priv.h>

#include <copybit.h>
#include <alloc_controller.h>
#include <memalloc.h>

#include "c2d2.h"
#include "software_converter.h"

#include <dlfcn.h>

using gralloc::IMemAlloc;
using gralloc::IonController;
using gralloc::alloc_data;

C2D_STATUS (*LINK_c2dCreateSurface)( uint32 *surface_id,
                                     uint32 surface_bits,
                                     C2D_SURFACE_TYPE surface_type,
                                     void *surface_definition );

C2D_STATUS (*LINK_c2dUpdateSurface)( uint32 surface_id,
                                     uint32 surface_bits,
                                     C2D_SURFACE_TYPE surface_type,
                                     void *surface_definition );

C2D_STATUS (*LINK_c2dReadSurface)( uint32 surface_id,
                                   C2D_SURFACE_TYPE surface_type,
                                   void *surface_definition,
                                   int32 x, int32 y );

C2D_STATUS (*LINK_c2dDraw)( uint32 target_id,
                            uint32 target_config, C2D_RECT *target_scissor,
                            uint32 target_mask_id, uint32 target_color_key,
                            C2D_OBJECT *objects_list, uint32 num_objects );

C2D_STATUS (*LINK_c2dFinish)( uint32 target_id);

C2D_STATUS (*LINK_c2dFlush)( uint32 target_id, c2d_ts_handle *timestamp);

C2D_STATUS (*LINK_c2dWaitTimestamp)( c2d_ts_handle timestamp );

C2D_STATUS (*LINK_c2dDestroySurface)( uint32 surface_id );

C2D_STATUS (*LINK_c2dMapAddr) ( int mem_fd, void * hostptr, size_t len,
                                size_t offset, uint32 flags, void ** gpuaddr);

C2D_STATUS (*LINK_c2dUnMapAddr) ( void * gpuaddr);

C2D_STATUS (*LINK_c2dGetDriverCapabilities) ( C2D_DRIVER_INFO * driver_info);

/* create a fence fd for the timestamp */
C2D_STATUS (*LINK_c2dCreateFenceFD) ( uint32 target_id, c2d_ts_handle timestamp,
                                                            int32 *fd);

C2D_STATUS (*LINK_c2dFillSurface) ( uint32 surface_id, uint32 fill_color,
                                    C2D_RECT * fill_rect);

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

#if defined(COPYBIT_Z180)
#define MAX_SCALE_FACTOR    (4096)
#define MAX_DIMENSION       (4096)
#else
#error "Unsupported HW version"
#endif

// The following defines can be changed as required i.e. as we encounter
// complex use cases.
#define MAX_RGB_SURFACES 32       // Max. RGB layers currently supported per draw
#define MAX_YUV_2_PLANE_SURFACES 4// Max. 2-plane YUV layers currently supported per draw
#define MAX_YUV_3_PLANE_SURFACES 1// Max. 3-plane YUV layers currently supported per draw
// +1 for the destination surface. We cannot have multiple destination surfaces.
#define MAX_SURFACES (MAX_RGB_SURFACES + MAX_YUV_2_PLANE_SURFACES + MAX_YUV_3_PLANE_SURFACES + 1)
#define NUM_SURFACE_TYPES 3      // RGB_SURFACE + YUV_SURFACE_2_PLANES + YUV_SURFACE_3_PLANES
#define MAX_BLIT_OBJECT_COUNT 50 // Max. blit objects that can be passed per draw

enum {
    RGB_SURFACE,
    YUV_SURFACE_2_PLANES,
    YUV_SURFACE_3_PLANES
};

enum eConversionType {
    CONVERT_TO_ANDROID_FORMAT,
    CONVERT_TO_C2D_FORMAT
};

enum eC2DFlags {
    FLAGS_PREMULTIPLIED_ALPHA  = 1<<0,
    FLAGS_YUV_DESTINATION      = 1<<1,
    FLAGS_TEMP_SRC_DST         = 1<<2
};

static gralloc::IAllocController* sAlloc = 0;
/******************************************************************************/

/** State information for each device instance */
struct copybit_context_t {
    struct copybit_device_t device;
    // Templates for the various source surfaces. These templates are created
    // to avoid the expensive create/destroy C2D Surfaces
    C2D_OBJECT_STR blit_rgb_object[MAX_RGB_SURFACES];
    C2D_OBJECT_STR blit_yuv_2_plane_object[MAX_YUV_2_PLANE_SURFACES];
    C2D_OBJECT_STR blit_yuv_3_plane_object[MAX_YUV_3_PLANE_SURFACES];
    C2D_OBJECT_STR blit_list[MAX_BLIT_OBJECT_COUNT]; // Z-ordered list of blit objects
    C2D_DRIVER_INFO c2d_driver_info;
    void *libc2d2;
    alloc_data temp_src_buffer;
    alloc_data temp_dst_buffer;
    unsigned int dst[NUM_SURFACE_TYPES]; // dst surfaces
    uintptr_t mapped_gpu_addr[MAX_SURFACES]; // GPU addresses mapped inside copybit
    int blit_rgb_count;         // Total RGB surfaces being blit
    int blit_yuv_2_plane_count; // Total 2 plane YUV surfaces being
    int blit_yuv_3_plane_count; // Total 3 plane YUV  surfaces being blit
    int blit_count;             // Total blit objects.
    unsigned int trg_transform;      /* target transform */
    int fb_width;
    int fb_height;
    int src_global_alpha;
    int config_mask;
    int dst_surface_type;
    bool is_premultiplied_alpha;
    void* time_stamp;
    bool dst_surface_mapped; // Set when dst surface is mapped to GPU addr
    void* dst_surface_base; // Stores the dst surface addr

    // used for signaling the wait thread
    bool wait_timestamp;
    pthread_t wait_thread_id;
    bool stop_thread;
    pthread_mutex_t wait_cleanup_lock;
    pthread_cond_t wait_cleanup_cond;

};

struct bufferInfo {
    int width;
    int height;
    int format;
};

struct yuvPlaneInfo {
    int yStride;       //luma stride
    int plane1_stride;
    int plane2_stride;
    size_t plane1_offset;
    size_t plane2_offset;
};

/**
 * Common hardware methods
 */

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

static struct hw_module_methods_t copybit_module_methods = {
open:  open_copybit
};

/*
 * The COPYBIT Module
 */
struct copybit_module_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG,
     version_major: 1,
     version_minor: 0,
     id: COPYBIT_HARDWARE_MODULE_ID,
     name: "QCT COPYBIT C2D 2.0 Module",
     author: "Qualcomm",
     methods: &copybit_module_methods
        }
};


/* thread function which waits on the timeStamp and cleans up the surfaces */
static void* c2d_wait_loop(void* ptr) {
    copybit_context_t* ctx = (copybit_context_t*)(ptr);
    char thread_name[64] = "copybitWaitThr";
    prctl(PR_SET_NAME, (unsigned long) &thread_name, 0, 0, 0);
    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);

    while(ctx->stop_thread == false) {
        pthread_mutex_lock(&ctx->wait_cleanup_lock);
        while(ctx->wait_timestamp == false && !ctx->stop_thread) {
            pthread_cond_wait(&(ctx->wait_cleanup_cond),
                              &(ctx->wait_cleanup_lock));
        }
        if(ctx->wait_timestamp) {
            if(LINK_c2dWaitTimestamp(ctx->time_stamp)) {
                ALOGE("%s: LINK_c2dWaitTimeStamp ERROR!!", __FUNCTION__);
            }
            ctx->wait_timestamp = false;
            // Unmap any mapped addresses.
            for (int i = 0; i < MAX_SURFACES; i++) {
                if (ctx->mapped_gpu_addr[i]) {
                    LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
                    ctx->mapped_gpu_addr[i] = 0;
                }
            }
            // Reset the counts after the draw.
            ctx->blit_rgb_count = 0;
            ctx->blit_yuv_2_plane_count = 0;
            ctx->blit_yuv_3_plane_count = 0;
            ctx->blit_count = 0;
            ctx->dst_surface_mapped = false;
            ctx->dst_surface_base = 0;
        }
        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
        if(ctx->stop_thread)
            break;
    }
    pthread_exit(NULL);
    return NULL;
}


/* convert COPYBIT_FORMAT to C2D format */
static int get_format(int format) {
    switch (format) {
        case HAL_PIXEL_FORMAT_RGB_565:        return C2D_COLOR_FORMAT_565_RGB;
        case HAL_PIXEL_FORMAT_RGB_888:        return C2D_COLOR_FORMAT_888_RGB |
                                              C2D_FORMAT_SWAP_RB;
        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
                                              C2D_FORMAT_SWAP_RB |
                                                  C2D_FORMAT_DISABLE_ALPHA;
        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
                                              C2D_FORMAT_SWAP_RB;
        case HAL_PIXEL_FORMAT_BGRA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV12;
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: return C2D_COLOR_FORMAT_420_NV12 |
                                                  C2D_FORMAT_MACROTILED;
        default:                              ALOGE("%s: invalid format (0x%x",
                                                     __FUNCTION__, format);
                                              return -EINVAL;
    }
    return -EINVAL;
}

/* Get the C2D formats needed for conversion to YUV */
static int get_c2d_format_for_yuv_destination(int halFormat) {
    switch (halFormat) {
        // We do not swap the RB when the target is YUV
        case HAL_PIXEL_FORMAT_RGBX_8888:      return C2D_COLOR_FORMAT_8888_ARGB |
                                              C2D_FORMAT_DISABLE_ALPHA;
        case HAL_PIXEL_FORMAT_RGBA_8888:      return C2D_COLOR_FORMAT_8888_ARGB;
        // The U and V need to be interchanged when the target is YUV
        case HAL_PIXEL_FORMAT_YCbCr_420_SP:   return C2D_COLOR_FORMAT_420_NV21;
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:return C2D_COLOR_FORMAT_420_NV21;
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:   return C2D_COLOR_FORMAT_420_NV12;
        default:                              return get_format(halFormat);
    }
    return -EINVAL;
}

/* ------------------------------------------------------------------- *//*!
 * \internal
 * \brief Get the bpp for a particular color format
 * \param color format
 * \return bits per pixel
 *//* ------------------------------------------------------------------- */
int c2diGetBpp(int32 colorformat)
{

    int c2dBpp = 0;

    switch(colorformat&0xFF)
    {
        case C2D_COLOR_FORMAT_4444_RGBA:
        case C2D_COLOR_FORMAT_4444_ARGB:
        case C2D_COLOR_FORMAT_1555_ARGB:
        case C2D_COLOR_FORMAT_565_RGB:
        case C2D_COLOR_FORMAT_5551_RGBA:
            c2dBpp = 16;
            break;
        case C2D_COLOR_FORMAT_8888_RGBA:
        case C2D_COLOR_FORMAT_8888_ARGB:
            c2dBpp = 32;
            break;
        case C2D_COLOR_FORMAT_888_RGB:
            c2dBpp = 24;
            break;
        case C2D_COLOR_FORMAT_8_L:
        case C2D_COLOR_FORMAT_8_A:
            c2dBpp = 8;
            break;
        case C2D_COLOR_FORMAT_4_A:
            c2dBpp = 4;
            break;
        case C2D_COLOR_FORMAT_1:
            c2dBpp = 1;
            break;
        default:
            ALOGE("%s ERROR", __func__);
            break;
    }
    return c2dBpp;
}

static size_t c2d_get_gpuaddr(copybit_context_t* ctx,
                              struct private_handle_t *handle, int &mapped_idx)
{
    uint32 memtype;
    size_t *gpuaddr = 0;
    C2D_STATUS rc;
    int freeindex = 0;
    bool mapaddr = false;

    if(!handle)
        return 0;

    if (handle->flags & (private_handle_t::PRIV_FLAGS_USES_PMEM |
                         private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP))
        memtype = KGSL_USER_MEM_TYPE_PMEM;
    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ASHMEM)
        memtype = KGSL_USER_MEM_TYPE_ASHMEM;
    else if (handle->flags & private_handle_t::PRIV_FLAGS_USES_ION)
        memtype = KGSL_USER_MEM_TYPE_ION;
    else {
        ALOGE("Invalid handle flags: 0x%x", handle->flags);
        return 0;
    }

    // Check for a freeindex in the mapped_gpu_addr list
    for (freeindex = 0; freeindex < MAX_SURFACES; freeindex++) {
        if (ctx->mapped_gpu_addr[freeindex] == 0) {
            // free index is available
            // map GPU addr and use this as mapped_idx
            mapaddr = true;
            break;
        }
    }

    if(mapaddr) {
        rc = LINK_c2dMapAddr(handle->fd, (void*)handle->base, handle->size,
                             handle->offset, memtype, (void**)&gpuaddr);

        if (rc == C2D_STATUS_OK) {
            // We have mapped the GPU address inside copybit. We need to unmap
            // this address after the blit. Store this address
            ctx->mapped_gpu_addr[freeindex] = (size_t)gpuaddr;
            mapped_idx = freeindex;
        }
    }
    return (size_t)gpuaddr;
}

static void unmap_gpuaddr(copybit_context_t* ctx, int mapped_idx)
{
    if (!ctx || (mapped_idx == -1))
        return;

    if (ctx->mapped_gpu_addr[mapped_idx]) {
        LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[mapped_idx]);
        ctx->mapped_gpu_addr[mapped_idx] = 0;
    }
}

static int is_supported_rgb_format(int format)
{
    switch(format) {
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_RGBX_8888:
        case HAL_PIXEL_FORMAT_RGB_888:
        case HAL_PIXEL_FORMAT_RGB_565:
        case HAL_PIXEL_FORMAT_BGRA_8888: {
            return COPYBIT_SUCCESS;
        }
        default:
            return COPYBIT_FAILURE;
    }
}

static int get_num_planes(int format)
{
    switch(format) {
        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
            return 2;
        }
        case HAL_PIXEL_FORMAT_YV12: {
            return 3;
        }
        default:
            return COPYBIT_FAILURE;
    }
}

static int is_supported_yuv_format(int format)
{
    switch(format) {
        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
            return COPYBIT_SUCCESS;
        }
        default:
            return COPYBIT_FAILURE;
    }
}

static int is_valid_destination_format(int format)
{
    if (format == HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED) {
        // C2D does not support NV12Tile as a destination format.
        return COPYBIT_FAILURE;
    }
    return COPYBIT_SUCCESS;
}

static int calculate_yuv_offset_and_stride(const bufferInfo& info,
                                           yuvPlaneInfo& yuvInfo)
{
    int width  = info.width;
    int height = info.height;
    int format = info.format;

    int aligned_height = 0;
    int aligned_width = 0, size = 0;

    switch (format) {
        case HAL_PIXEL_FORMAT_YCbCr_420_SP_TILED: {
            /* NV12 Tile buffers have their luma height aligned to 32bytes and width
             * aligned to 128 bytes. The chroma offset starts at an 8K boundary
             */
            aligned_height = ALIGN(height, 32);
            aligned_width  = ALIGN(width, 128);
            size = aligned_width * aligned_height;
            yuvInfo.plane1_offset = ALIGN(size,8192);
            yuvInfo.yStride = aligned_width;
            yuvInfo.plane1_stride = aligned_width;
            break;
        }
        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
        case HAL_PIXEL_FORMAT_YCrCb_420_SP: {
            aligned_width = ALIGN(width, 32);
            yuvInfo.yStride = aligned_width;
            yuvInfo.plane1_stride = aligned_width;
            if (HAL_PIXEL_FORMAT_NV12_ENCODEABLE == format) {
                // The encoder requires a 2K aligned chroma offset
                yuvInfo.plane1_offset = ALIGN(aligned_width * height, 2048);
            } else
                yuvInfo.plane1_offset = aligned_width * height;

            break;
        }
        default: {
            return COPYBIT_FAILURE;
        }
    }
    return COPYBIT_SUCCESS;
}

/** create C2D surface from copybit image */
static int set_image(copybit_context_t* ctx, uint32 surfaceId,
                      const struct copybit_image_t *rhs,
                      const eC2DFlags flags, int &mapped_idx)
{
    struct private_handle_t* handle = (struct private_handle_t*)rhs->handle;
    C2D_SURFACE_TYPE surfaceType;
    int status = COPYBIT_SUCCESS;
    uintptr_t gpuaddr = 0;
    int c2d_format;
    mapped_idx = -1;

    if (flags & FLAGS_YUV_DESTINATION) {
        c2d_format = get_c2d_format_for_yuv_destination(rhs->format);
    } else {
        c2d_format = get_format(rhs->format);
    }

    if(c2d_format == -EINVAL) {
        ALOGE("%s: invalid format", __FUNCTION__);
        return -EINVAL;
    }

    if(handle == NULL) {
        ALOGE("%s: invalid handle", __func__);
        return -EINVAL;
    }

    if (handle->gpuaddr == 0) {
        gpuaddr = c2d_get_gpuaddr(ctx, handle, mapped_idx);
        if(!gpuaddr) {
            ALOGE("%s: c2d_get_gpuaddr failed", __FUNCTION__);
            return COPYBIT_FAILURE;
        }
    } else {
        gpuaddr = handle->gpuaddr;
    }

    /* create C2D surface */
    if(is_supported_rgb_format(rhs->format) == COPYBIT_SUCCESS) {
        /* RGB */
        C2D_RGB_SURFACE_DEF surfaceDef;

        surfaceType = (C2D_SURFACE_TYPE) (C2D_SURFACE_RGB_HOST | C2D_SURFACE_WITH_PHYS);

        surfaceDef.phys = (void*) gpuaddr;
        surfaceDef.buffer = (void*) (handle->base);

        surfaceDef.format = c2d_format |
            ((flags & FLAGS_PREMULTIPLIED_ALPHA) ? C2D_FORMAT_PREMULTIPLIED : 0);
        surfaceDef.width = rhs->w;
        surfaceDef.height = rhs->h;
        int aligned_width = ALIGN((int)surfaceDef.width,32);
        surfaceDef.stride = (aligned_width * c2diGetBpp(surfaceDef.format))>>3;

        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
                                  &surfaceDef)) {
            ALOGE("%s: RGB Surface c2dUpdateSurface ERROR", __FUNCTION__);
            unmap_gpuaddr(ctx, mapped_idx);
            status = COPYBIT_FAILURE;
        }
    } else if (is_supported_yuv_format(rhs->format) == COPYBIT_SUCCESS) {
        C2D_YUV_SURFACE_DEF surfaceDef;
        memset(&surfaceDef, 0, sizeof(surfaceDef));
        surfaceType = (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST | C2D_SURFACE_WITH_PHYS);
        surfaceDef.format = c2d_format;

        bufferInfo info;
        info.width = rhs->w;
        info.height = rhs->h;
        info.format = rhs->format;

        yuvPlaneInfo yuvInfo = {0};
        status = calculate_yuv_offset_and_stride(info, yuvInfo);
        if(status != COPYBIT_SUCCESS) {
            ALOGE("%s: calculate_yuv_offset_and_stride error", __FUNCTION__);
            unmap_gpuaddr(ctx, mapped_idx);
        }

        surfaceDef.width = rhs->w;
        surfaceDef.height = rhs->h;
        surfaceDef.plane0 = (void*) (handle->base);
        surfaceDef.phys0 = (void*) (gpuaddr);
        surfaceDef.stride0 = yuvInfo.yStride;

        surfaceDef.plane1 = (void*) (handle->base + yuvInfo.plane1_offset);
        surfaceDef.phys1 = (void*) (gpuaddr + yuvInfo.plane1_offset);
        surfaceDef.stride1 = yuvInfo.plane1_stride;
        if (3 == get_num_planes(rhs->format)) {
            surfaceDef.plane2 = (void*) (handle->base + yuvInfo.plane2_offset);
            surfaceDef.phys2 = (void*) (gpuaddr + yuvInfo.plane2_offset);
            surfaceDef.stride2 = yuvInfo.plane2_stride;
        }

        if(LINK_c2dUpdateSurface( surfaceId,C2D_TARGET | C2D_SOURCE, surfaceType,
                                  &surfaceDef)) {
            ALOGE("%s: YUV Surface c2dUpdateSurface ERROR", __FUNCTION__);
            unmap_gpuaddr(ctx, mapped_idx);
            status = COPYBIT_FAILURE;
        }
    } else {
        ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
        unmap_gpuaddr(ctx, mapped_idx);
        status = COPYBIT_FAILURE;
    }

    return status;
}

/** copy the bits */
static int msm_copybit(struct copybit_context_t *ctx, unsigned int target)
{
    if (ctx->blit_count == 0) {
        return COPYBIT_SUCCESS;
    }

    for (int i = 0; i < ctx->blit_count; i++)
    {
        ctx->blit_list[i].next = &(ctx->blit_list[i+1]);
    }
    ctx->blit_list[ctx->blit_count-1].next = NULL;
    uint32_t target_transform = ctx->trg_transform;
    if (ctx->c2d_driver_info.capabilities_mask &
        C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
        // For A3xx - set 0x0 as the transform is set in the config_mask
        target_transform = 0x0;
    }
    if(LINK_c2dDraw(target, target_transform, 0x0, 0, 0, ctx->blit_list,
                    ctx->blit_count)) {
        ALOGE("%s: LINK_c2dDraw ERROR", __FUNCTION__);
        return COPYBIT_FAILURE;
    }
    return COPYBIT_SUCCESS;
}



static int flush_get_fence_copybit (struct copybit_device_t *dev, int* fd)
{
    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    int status = COPYBIT_FAILURE;
    if (!ctx)
        return COPYBIT_FAILURE;
    pthread_mutex_lock(&ctx->wait_cleanup_lock);
    status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);

    if(LINK_c2dFlush(ctx->dst[ctx->dst_surface_type], &ctx->time_stamp)) {
        ALOGE("%s: LINK_c2dFlush ERROR", __FUNCTION__);
        // unlock the mutex and return failure
        pthread_mutex_unlock(&ctx->wait_cleanup_lock);
        return COPYBIT_FAILURE;
    }
    if(LINK_c2dCreateFenceFD(ctx->dst[ctx->dst_surface_type], ctx->time_stamp,
                                                                        fd)) {
        ALOGE("%s: LINK_c2dCreateFenceFD ERROR", __FUNCTION__);
        status = COPYBIT_FAILURE;
    }
    if(status == COPYBIT_SUCCESS) {
        //signal the wait_thread
        ctx->wait_timestamp = true;
        pthread_cond_signal(&ctx->wait_cleanup_cond);
    }
    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
    return status;
}

static int finish_copybit(struct copybit_device_t *dev)
{
    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    if (!ctx)
        return COPYBIT_FAILURE;

   int status = msm_copybit(ctx, ctx->dst[ctx->dst_surface_type]);

   if(LINK_c2dFinish(ctx->dst[ctx->dst_surface_type])) {
        ALOGE("%s: LINK_c2dFinish ERROR", __FUNCTION__);
        return COPYBIT_FAILURE;
    }

    // Unmap any mapped addresses.
    for (int i = 0; i < MAX_SURFACES; i++) {
        if (ctx->mapped_gpu_addr[i]) {
            LINK_c2dUnMapAddr( (void*)ctx->mapped_gpu_addr[i]);
            ctx->mapped_gpu_addr[i] = 0;
        }
    }

    // Reset the counts after the draw.
    ctx->blit_rgb_count = 0;
    ctx->blit_yuv_2_plane_count = 0;
    ctx->blit_yuv_3_plane_count = 0;
    ctx->blit_count = 0;
    ctx->dst_surface_mapped = false;
    ctx->dst_surface_base = 0;

    return status;
}

static int clear_copybit(struct copybit_device_t *dev,
                         struct copybit_image_t const *buf,
                         struct copybit_rect_t *rect)
{
    int ret = COPYBIT_SUCCESS;
    int flags = FLAGS_PREMULTIPLIED_ALPHA;
    int mapped_dst_idx = -1;
    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    C2D_RECT c2drect = {rect->l, rect->t, rect->r - rect->l, rect->b - rect->t};
    pthread_mutex_lock(&ctx->wait_cleanup_lock);
    if(!ctx->dst_surface_mapped) {
        ret = set_image(ctx, ctx->dst[RGB_SURFACE], buf,
                        (eC2DFlags)flags, mapped_dst_idx);
        if(ret) {
            ALOGE("%s: set_image error", __FUNCTION__);
            unmap_gpuaddr(ctx, mapped_dst_idx);
            pthread_mutex_unlock(&ctx->wait_cleanup_lock);
            return COPYBIT_FAILURE;
        }
        //clear_copybit is the first call made by HWC for each composition
        //with the dest surface, hence set dst_surface_mapped.
        ctx->dst_surface_mapped = true;
        ctx->dst_surface_base = buf->base;
        ret = LINK_c2dFillSurface(ctx->dst[RGB_SURFACE], 0x0, &c2drect);
    }
    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
    return ret;
}


/** setup rectangles */
static void set_rects(struct copybit_context_t *ctx,
                      C2D_OBJECT *c2dObject,
                      const struct copybit_rect_t *dst,
                      const struct copybit_rect_t *src,
                      const struct copybit_rect_t *scissor)
{
    // Set the target rect.
    if((ctx->trg_transform & C2D_TARGET_ROTATE_90) &&
       (ctx->trg_transform & C2D_TARGET_ROTATE_180)) {
        /* target rotation is 270 */
        c2dObject->target_rect.x        = (dst->t)<<16;
        c2dObject->target_rect.y        = ctx->fb_width?
                (ALIGN(ctx->fb_width,32)- dst->r):dst->r;
        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_90) {
        c2dObject->target_rect.x        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
        c2dObject->target_rect.y        = (dst->l)<<16;
        c2dObject->target_rect.height   = ((dst->r) - (dst->l))<<16;
        c2dObject->target_rect.width    = ((dst->b) - (dst->t))<<16;
    } else if(ctx->trg_transform & C2D_TARGET_ROTATE_180) {
        c2dObject->target_rect.y        = ctx->fb_height?(ctx->fb_height - dst->b):dst->b;
        c2dObject->target_rect.y        = c2dObject->target_rect.y<<16;
        c2dObject->target_rect.x        = ctx->fb_width?
                (ALIGN(ctx->fb_width,32) - dst->r):dst->r;
        c2dObject->target_rect.x        = c2dObject->target_rect.x<<16;
        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
    } else {
        c2dObject->target_rect.x        = (dst->l)<<16;
        c2dObject->target_rect.y        = (dst->t)<<16;
        c2dObject->target_rect.height   = ((dst->b) - (dst->t))<<16;
        c2dObject->target_rect.width    = ((dst->r) - (dst->l))<<16;
    }
    c2dObject->config_mask |= C2D_TARGET_RECT_BIT;

    // Set the source rect
    c2dObject->source_rect.x        = (src->l)<<16;
    c2dObject->source_rect.y        = (src->t)<<16;
    c2dObject->source_rect.height   = ((src->b) - (src->t))<<16;
    c2dObject->source_rect.width    = ((src->r) - (src->l))<<16;
    c2dObject->config_mask |= C2D_SOURCE_RECT_BIT;

    // Set the scissor rect
    c2dObject->scissor_rect.x       = scissor->l;
    c2dObject->scissor_rect.y       = scissor->t;
    c2dObject->scissor_rect.height  = (scissor->b) - (scissor->t);
    c2dObject->scissor_rect.width   = (scissor->r) - (scissor->l);
    c2dObject->config_mask |= C2D_SCISSOR_RECT_BIT;
}

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

/** Set a parameter to value */
static int set_parameter_copybit(
    struct copybit_device_t *dev,
    int name,
    int value)
{
    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    int status = COPYBIT_SUCCESS;
    if (!ctx) {
        ALOGE("%s: null context", __FUNCTION__);
        return -EINVAL;
    }

    pthread_mutex_lock(&ctx->wait_cleanup_lock);
    switch(name) {
        case COPYBIT_PLANE_ALPHA:
        {
            if (value < 0)      value = 0;
            if (value >= 256)   value = 255;

            ctx->src_global_alpha = value;
            if (value < 255)
                ctx->config_mask |= C2D_GLOBAL_ALPHA_BIT;
            else
                ctx->config_mask &= ~C2D_GLOBAL_ALPHA_BIT;
        }
        break;
        case COPYBIT_BLEND_MODE:
        {
            if (value == COPYBIT_BLENDING_NONE) {
                ctx->config_mask |= C2D_ALPHA_BLEND_NONE;
                ctx->is_premultiplied_alpha = true;
            } else if (value == COPYBIT_BLENDING_PREMULT) {
                ctx->is_premultiplied_alpha = true;
            } else {
                ctx->config_mask &= ~C2D_ALPHA_BLEND_NONE;
            }
        }
        break;
        case COPYBIT_TRANSFORM:
        {
            unsigned int transform = 0;
            uint32 config_mask = 0;
            config_mask |= C2D_OVERRIDE_GLOBAL_TARGET_ROTATE_CONFIG;
            if((value & 0x7) == COPYBIT_TRANSFORM_ROT_180) {
                transform = C2D_TARGET_ROTATE_180;
                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_180;
            } else if((value & 0x7) == COPYBIT_TRANSFORM_ROT_270) {
                transform = C2D_TARGET_ROTATE_90;
                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_90;
            } else if(value == COPYBIT_TRANSFORM_ROT_90) {
                transform = C2D_TARGET_ROTATE_270;
                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_270;
            } else {
                config_mask |= C2D_OVERRIDE_TARGET_ROTATE_0;
                if(value & COPYBIT_TRANSFORM_FLIP_H) {
                    config_mask |= C2D_MIRROR_H_BIT;
                } else if(value & COPYBIT_TRANSFORM_FLIP_V) {
                    config_mask |= C2D_MIRROR_V_BIT;
                }
            }

            if (ctx->c2d_driver_info.capabilities_mask &
                C2D_DRIVER_SUPPORTS_OVERRIDE_TARGET_ROTATE_OP) {
                ctx->config_mask |= config_mask;
            } else {
                // The transform for this surface does not match the current
                // target transform. Draw all previous surfaces. This will be
                // changed once we have a new mechanism to send different
                // target rotations to c2d.
                finish_copybit(dev);
            }
            ctx->trg_transform = transform;
        }
        break;
        case COPYBIT_FRAMEBUFFER_WIDTH:
            ctx->fb_width = value;
            break;
        case COPYBIT_FRAMEBUFFER_HEIGHT:
            ctx->fb_height = value;
            break;
        case COPYBIT_ROTATION_DEG:
        case COPYBIT_DITHER:
        case COPYBIT_BLUR:
        case COPYBIT_BLIT_TO_FRAMEBUFFER:
            // Do nothing
            break;
        default:
            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
            status = -EINVAL;
            break;
    }
    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
    return status;
}

/** Get a static info value */
static int get(struct copybit_device_t *dev, int name)
{
    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    int value;

    if (!ctx) {
        ALOGE("%s: null context error", __FUNCTION__);
        return -EINVAL;
    }

    switch(name) {
        case COPYBIT_MINIFICATION_LIMIT:
            value = MAX_SCALE_FACTOR;
            break;
        case COPYBIT_MAGNIFICATION_LIMIT:
            value = MAX_SCALE_FACTOR;
            break;
        case COPYBIT_SCALING_FRAC_BITS:
            value = 32;
            break;
        case COPYBIT_ROTATION_STEP_DEG:
            value = 1;
            break;
        default:
            ALOGE("%s: default case param=0x%x", __FUNCTION__, name);
            value = -EINVAL;
    }
    return value;
}

static int is_alpha(int cformat)
{
    int alpha = 0;
    switch (cformat & 0xFF) {
        case C2D_COLOR_FORMAT_8888_ARGB:
        case C2D_COLOR_FORMAT_8888_RGBA:
        case C2D_COLOR_FORMAT_5551_RGBA:
        case C2D_COLOR_FORMAT_4444_ARGB:
            alpha = 1;
            break;
        default:
            alpha = 0;
            break;
    }

    if(alpha && (cformat&C2D_FORMAT_DISABLE_ALPHA))
        alpha = 0;

    return alpha;
}

/* Function to check if we need a temporary buffer for the blit.
 * This would happen if the requested destination stride and the
 * C2D stride do not match. We ignore RGB buffers, since their
 * stride is always aligned to 32.
 */
static bool need_temp_buffer(struct copybit_image_t const *img)
{
    if (COPYBIT_SUCCESS == is_supported_rgb_format(img->format))
        return false;

    struct private_handle_t* handle = (struct private_handle_t*)img->handle;

    // The width parameter in the handle contains the aligned_w. We check if we
    // need to convert based on this param. YUV formats have bpp=1, so checking
    // if the requested stride is aligned should suffice.
    if (0 == (handle->width)%32) {
        return false;
    }

    return true;
}

/* Function to extract the information from the copybit image and set the corresponding
 * values in the bufferInfo struct.
 */
static void populate_buffer_info(struct copybit_image_t const *img, bufferInfo& info)
{
    info.width = img->w;
    info.height = img->h;
    info.format = img->format;
}

/* Function to get the required size for a particular format, inorder for C2D to perform
 * the blit operation.
 */
static int get_size(const bufferInfo& info)
{
    int size = 0;
    int w = info.width;
    int h = info.height;
    int aligned_w = ALIGN(w, 32);
    switch(info.format) {
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
            {
                // Chroma for this format is aligned to 2K.
                size = ALIGN((aligned_w*h), 2048) +
                        ALIGN(aligned_w/2, 32) * (h/2) *2;
                size = ALIGN(size, 4096);
            } break;
        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
            {
                size = aligned_w * h +
                       ALIGN(aligned_w/2, 32) * (h/2) * 2;
                size = ALIGN(size, 4096);
            } break;
        default: break;
    }
    return size;
}

/* Function to allocate memory for the temporary buffer. This memory is
 * allocated from Ashmem. It is the caller's responsibility to free this
 * memory.
 */
static int get_temp_buffer(const bufferInfo& info, alloc_data& data)
{
    ALOGD("%s E", __FUNCTION__);
    // Alloc memory from system heap
    data.base = 0;
    data.fd = -1;
    data.offset = 0;
    data.size = get_size(info);
    data.align = getpagesize();
    data.uncached = true;
    int allocFlags = GRALLOC_USAGE_PRIVATE_SYSTEM_HEAP;

    if (sAlloc == 0) {
        sAlloc = gralloc::IAllocController::getInstance();
    }

    if (sAlloc == 0) {
        ALOGE("%s: sAlloc is still NULL", __FUNCTION__);
        return COPYBIT_FAILURE;
    }

    int err = sAlloc->allocate(data, allocFlags);
    if (0 != err) {
        ALOGE("%s: allocate failed", __FUNCTION__);
        return COPYBIT_FAILURE;
    }

    ALOGD("%s X", __FUNCTION__);
    return err;
}

/* Function to free the temporary allocated memory.*/
static void free_temp_buffer(alloc_data &data)
{
    if (-1 != data.fd) {
        IMemAlloc* memalloc = sAlloc->getAllocator(data.allocType);
        memalloc->free_buffer(data.base, data.size, 0, data.fd);
    }
}

/* Function to perform the software color conversion. Convert the
 * C2D compatible format to the Android compatible format
 */
static int copy_image(private_handle_t *src_handle,
                      struct copybit_image_t const *rhs,
                      eConversionType conversionType)
{
    if (src_handle->fd == -1) {
        ALOGE("%s: src_handle fd is invalid", __FUNCTION__);
        return COPYBIT_FAILURE;
    }

    // Copy the info.
    int ret = COPYBIT_SUCCESS;
    switch(rhs->format) {
        case HAL_PIXEL_FORMAT_NV12_ENCODEABLE:
        case HAL_PIXEL_FORMAT_YCbCr_420_SP:
        case HAL_PIXEL_FORMAT_YCrCb_420_SP:
            {
                if (CONVERT_TO_ANDROID_FORMAT == conversionType) {
                    return convert_yuv_c2d_to_yuv_android(src_handle, rhs);
                } else {
                    return convert_yuv_android_to_yuv_c2d(src_handle, rhs);
                }

            } break;
        default: {
            ALOGE("%s: invalid format 0x%x", __FUNCTION__, rhs->format);
            ret = COPYBIT_FAILURE;
        } break;
    }
    return ret;
}

static void delete_handle(private_handle_t *handle)
{
    if (handle) {
        delete handle;
        handle = 0;
    }
}

static bool need_to_execute_draw(eC2DFlags flags)
{
    if (flags & FLAGS_TEMP_SRC_DST) {
        return true;
    }
    if (flags & FLAGS_YUV_DESTINATION) {
        return true;
    }
    return false;
}

/** do a stretch blit type operation */
static int stretch_copybit_internal(
    struct copybit_device_t *dev,
    struct copybit_image_t const *dst,
    struct copybit_image_t const *src,
    struct copybit_rect_t const *dst_rect,
    struct copybit_rect_t const *src_rect,
    struct copybit_region_t const *region,
    bool enableBlend)
{
    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    int status = COPYBIT_SUCCESS;
    int flags = 0;
    int src_surface_type;
    int mapped_src_idx = -1, mapped_dst_idx = -1;
    C2D_OBJECT_STR src_surface;

    if (!ctx) {
        ALOGE("%s: null context error", __FUNCTION__);
        return -EINVAL;
    }

    if (src->w > MAX_DIMENSION || src->h > MAX_DIMENSION) {
        ALOGE("%s: src dimension error", __FUNCTION__);
        return -EINVAL;
    }

    if (dst->w > MAX_DIMENSION || dst->h > MAX_DIMENSION) {
        ALOGE("%s : dst dimension error dst w %d h %d",  __FUNCTION__, dst->w,
                                                         dst->h);
        return -EINVAL;
    }

    if (is_valid_destination_format(dst->format) == COPYBIT_FAILURE) {
        ALOGE("%s: Invalid destination format format = 0x%x", __FUNCTION__,
                                                              dst->format);
        return COPYBIT_FAILURE;
    }

    int dst_surface_type;
    if (is_supported_rgb_format(dst->format) == COPYBIT_SUCCESS) {
        dst_surface_type = RGB_SURFACE;
        flags |= FLAGS_PREMULTIPLIED_ALPHA;
    } else if (is_supported_yuv_format(dst->format) == COPYBIT_SUCCESS) {
        int num_planes = get_num_planes(dst->format);
        flags |= FLAGS_YUV_DESTINATION;
        if (num_planes == 2) {
            dst_surface_type = YUV_SURFACE_2_PLANES;
        } else if (num_planes == 3) {
            dst_surface_type = YUV_SURFACE_3_PLANES;
        } else {
            ALOGE("%s: dst number of YUV planes is invalid dst format = 0x%x",
                  __FUNCTION__, dst->format);
            return COPYBIT_FAILURE;
        }
    } else {
        ALOGE("%s: Invalid dst surface format 0x%x", __FUNCTION__,
                                                     dst->format);
        return COPYBIT_FAILURE;
    }

    if (ctx->blit_rgb_count == MAX_RGB_SURFACES ||
        ctx->blit_yuv_2_plane_count == MAX_YUV_2_PLANE_SURFACES ||
        ctx->blit_yuv_3_plane_count == MAX_YUV_2_PLANE_SURFACES ||
        ctx->blit_count == MAX_BLIT_OBJECT_COUNT ||
        ctx->dst_surface_type != dst_surface_type) {
        // we have reached the max. limits of our internal structures or
        // changed the target.
        // Draw the remaining surfaces. We need to do the finish here since
        // we need to free up the surface templates.
        finish_copybit(dev);
    }

    ctx->dst_surface_type = dst_surface_type;

    // Update the destination
    copybit_image_t dst_image;
    dst_image.w = dst->w;
    dst_image.h = dst->h;
    dst_image.format = dst->format;
    dst_image.handle = dst->handle;
    // Check if we need a temp. copy for the destination. We'd need this the destination
    // width is not aligned to 32. This case occurs for YUV formats. RGB formats are
    // aligned to 32.
    bool need_temp_dst = need_temp_buffer(dst);
    bufferInfo dst_info;
    populate_buffer_info(dst, dst_info);
    private_handle_t* dst_hnd = new private_handle_t(-1, 0, 0, 0, dst_info.format,
                                                     dst_info.width, dst_info.height);
    if (dst_hnd == NULL) {
        ALOGE("%s: dst_hnd is null", __FUNCTION__);
        return COPYBIT_FAILURE;
    }
    if (need_temp_dst) {
        if (get_size(dst_info) != ctx->temp_dst_buffer.size) {
            free_temp_buffer(ctx->temp_dst_buffer);
            // Create a temp buffer and set that as the destination.
            if (COPYBIT_FAILURE == get_temp_buffer(dst_info, ctx->temp_dst_buffer)) {
                ALOGE("%s: get_temp_buffer(dst) failed", __FUNCTION__);
                delete_handle(dst_hnd);
                return COPYBIT_FAILURE;
            }
        }
        dst_hnd->fd = ctx->temp_dst_buffer.fd;
        dst_hnd->size = ctx->temp_dst_buffer.size;
        dst_hnd->flags = ctx->temp_dst_buffer.allocType;
        dst_hnd->base = (uintptr_t)(ctx->temp_dst_buffer.base);
        dst_hnd->offset = ctx->temp_dst_buffer.offset;
        dst_hnd->gpuaddr = 0;
        dst_image.handle = dst_hnd;
    }
    if(!ctx->dst_surface_mapped) {
        //map the destination surface to GPU address
        status = set_image(ctx, ctx->dst[ctx->dst_surface_type], &dst_image,
                           (eC2DFlags)flags, mapped_dst_idx);
        if(status) {
            ALOGE("%s: dst: set_image error", __FUNCTION__);
            delete_handle(dst_hnd);
            unmap_gpuaddr(ctx, mapped_dst_idx);
            return COPYBIT_FAILURE;
        }
        ctx->dst_surface_mapped = true;
        ctx->dst_surface_base = dst->base;
    } else if(ctx->dst_surface_mapped && ctx->dst_surface_base != dst->base) {
        // Destination surface for the operation should be same for multiple
        // requests, this check is catch if there is any case when the
        // destination changes
        ALOGE("%s: a different destination surface!!", __FUNCTION__);
    }

    // Update the source
    flags = 0;
    if(is_supported_rgb_format(src->format) == COPYBIT_SUCCESS) {
        src_surface_type = RGB_SURFACE;
        src_surface = ctx->blit_rgb_object[ctx->blit_rgb_count];
    } else if (is_supported_yuv_format(src->format) == COPYBIT_SUCCESS) {
        int num_planes = get_num_planes(src->format);
        if (num_planes == 2) {
            src_surface_type = YUV_SURFACE_2_PLANES;
            src_surface = ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count];
        } else if (num_planes == 3) {
            src_surface_type = YUV_SURFACE_3_PLANES;
            src_surface = ctx->blit_yuv_3_plane_object[ctx->blit_yuv_2_plane_count];
        } else {
            ALOGE("%s: src number of YUV planes is invalid src format = 0x%x",
                  __FUNCTION__, src->format);
            delete_handle(dst_hnd);
            unmap_gpuaddr(ctx, mapped_dst_idx);
            return -EINVAL;
        }
    } else {
        ALOGE("%s: Invalid source surface format 0x%x", __FUNCTION__,
                                                        src->format);
        delete_handle(dst_hnd);
        unmap_gpuaddr(ctx, mapped_dst_idx);
        return -EINVAL;
    }

    copybit_image_t src_image;
    src_image.w = src->w;
    src_image.h = src->h;
    src_image.format = src->format;
    src_image.handle = src->handle;

    bool need_temp_src = need_temp_buffer(src);
    bufferInfo src_info;
    populate_buffer_info(src, src_info);
    private_handle_t* src_hnd = new private_handle_t(-1, 0, 0, 0, src_info.format,
                                                 src_info.width, src_info.height);
    if (NULL == src_hnd) {
        ALOGE("%s: src_hnd is null", __FUNCTION__);
        delete_handle(dst_hnd);
        unmap_gpuaddr(ctx, mapped_dst_idx);
        return COPYBIT_FAILURE;
    }
    if (need_temp_src) {
        if (get_size(src_info) != ctx->temp_src_buffer.size) {
            free_temp_buffer(ctx->temp_src_buffer);
            // Create a temp buffer and set that as the destination.
            if (COPYBIT_SUCCESS != get_temp_buffer(src_info,
                                               ctx->temp_src_buffer)) {
                ALOGE("%s: get_temp_buffer(src) failed", __FUNCTION__);
                delete_handle(dst_hnd);
                delete_handle(src_hnd);
                unmap_gpuaddr(ctx, mapped_dst_idx);
                return COPYBIT_FAILURE;
            }
        }
        src_hnd->fd = ctx->temp_src_buffer.fd;
        src_hnd->size = ctx->temp_src_buffer.size;
        src_hnd->flags = ctx->temp_src_buffer.allocType;
        src_hnd->base = (uintptr_t)(ctx->temp_src_buffer.base);
        src_hnd->offset = ctx->temp_src_buffer.offset;
        src_hnd->gpuaddr = 0;
        src_image.handle = src_hnd;

        // Copy the source.
        status = copy_image((private_handle_t *)src->handle, &src_image,
                                CONVERT_TO_C2D_FORMAT);
        if (status == COPYBIT_FAILURE) {
            ALOGE("%s:copy_image failed in temp source",__FUNCTION__);
            delete_handle(dst_hnd);
            delete_handle(src_hnd);
            unmap_gpuaddr(ctx, mapped_dst_idx);
            return status;
        }

        // Clean the cache
        IMemAlloc* memalloc = sAlloc->getAllocator(src_hnd->flags);
        if (memalloc->clean_buffer((void *)(src_hnd->base), src_hnd->size,
                                   src_hnd->offset, src_hnd->fd,
                                   gralloc::CACHE_CLEAN)) {
            ALOGE("%s: clean_buffer failed", __FUNCTION__);
            delete_handle(dst_hnd);
            delete_handle(src_hnd);
            unmap_gpuaddr(ctx, mapped_dst_idx);
            return COPYBIT_FAILURE;
        }
    }

    flags |= (ctx->is_premultiplied_alpha) ? FLAGS_PREMULTIPLIED_ALPHA : 0;
    flags |= (ctx->dst_surface_type != RGB_SURFACE) ? FLAGS_YUV_DESTINATION : 0;
    status = set_image(ctx, src_surface.surface_id, &src_image,
                       (eC2DFlags)flags, mapped_src_idx);
    if(status) {
        ALOGE("%s: set_image (src) error", __FUNCTION__);
        delete_handle(dst_hnd);
        delete_handle(src_hnd);
        unmap_gpuaddr(ctx, mapped_dst_idx);
        unmap_gpuaddr(ctx, mapped_src_idx);
        return COPYBIT_FAILURE;
    }

    src_surface.config_mask = C2D_NO_ANTIALIASING_BIT | ctx->config_mask;
    src_surface.global_alpha = ctx->src_global_alpha;
    if (enableBlend) {
        if(src_surface.config_mask & C2D_GLOBAL_ALPHA_BIT) {
            src_surface.config_mask &= ~C2D_ALPHA_BLEND_NONE;
            if(!(src_surface.global_alpha)) {
                // src alpha is zero
                delete_handle(dst_hnd);
                delete_handle(src_hnd);
                unmap_gpuaddr(ctx, mapped_dst_idx);
                unmap_gpuaddr(ctx, mapped_src_idx);
                return COPYBIT_FAILURE;
            }
        }
    } else {
        src_surface.config_mask |= C2D_ALPHA_BLEND_NONE;
    }

    if (src_surface_type == RGB_SURFACE) {
        ctx->blit_rgb_object[ctx->blit_rgb_count] = src_surface;
        ctx->blit_rgb_count++;
    } else if (src_surface_type == YUV_SURFACE_2_PLANES) {
        ctx->blit_yuv_2_plane_object[ctx->blit_yuv_2_plane_count] = src_surface;
        ctx->blit_yuv_2_plane_count++;
    } else {
        ctx->blit_yuv_3_plane_object[ctx->blit_yuv_3_plane_count] = src_surface;
        ctx->blit_yuv_3_plane_count++;
    }

    struct copybit_rect_t clip;
    while ((status == 0) && region->next(region, &clip)) {
        set_rects(ctx, &(src_surface), dst_rect, src_rect, &clip);
        if (ctx->blit_count == MAX_BLIT_OBJECT_COUNT) {
            ALOGW("Reached end of blit count");
            finish_copybit(dev);
        }
        ctx->blit_list[ctx->blit_count] = src_surface;
        ctx->blit_count++;
    }

    // Check if we need to perform an early draw-finish.
    flags |= (need_temp_dst || need_temp_src) ? FLAGS_TEMP_SRC_DST : 0;
    if (need_to_execute_draw((eC2DFlags)flags))
    {
        finish_copybit(dev);
    }

    if (need_temp_dst) {
        // copy the temp. destination without the alignment to the actual
        // destination.
        status = copy_image(dst_hnd, dst, CONVERT_TO_ANDROID_FORMAT);
        if (status == COPYBIT_FAILURE) {
            ALOGE("%s:copy_image failed in temp Dest",__FUNCTION__);
            delete_handle(dst_hnd);
            delete_handle(src_hnd);
            unmap_gpuaddr(ctx, mapped_dst_idx);
            unmap_gpuaddr(ctx, mapped_src_idx);
            return status;
        }
        // Clean the cache.
        IMemAlloc* memalloc = sAlloc->getAllocator(dst_hnd->flags);
        memalloc->clean_buffer((void *)(dst_hnd->base), dst_hnd->size,
                               dst_hnd->offset, dst_hnd->fd,
                               gralloc::CACHE_CLEAN);
    }
    delete_handle(dst_hnd);
    delete_handle(src_hnd);

    ctx->is_premultiplied_alpha = false;
    ctx->fb_width = 0;
    ctx->fb_height = 0;
    ctx->config_mask = 0;
    return status;
}

static int set_sync_copybit(struct copybit_device_t *dev,
    int /*acquireFenceFd*/)
{
    if(!dev)
        return -EINVAL;

    return 0;
}

static int stretch_copybit(
    struct copybit_device_t *dev,
    struct copybit_image_t const *dst,
    struct copybit_image_t const *src,
    struct copybit_rect_t const *dst_rect,
    struct copybit_rect_t const *src_rect,
    struct copybit_region_t const *region)
{
    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    int status = COPYBIT_SUCCESS;
    bool needsBlending = (ctx->src_global_alpha != 0);
    pthread_mutex_lock(&ctx->wait_cleanup_lock);
    status = stretch_copybit_internal(dev, dst, src, dst_rect, src_rect,
                                    region, needsBlending);
    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
    return status;
}

/** Perform a blit type operation */
static int blit_copybit(
    struct copybit_device_t *dev,
    struct copybit_image_t const *dst,
    struct copybit_image_t const *src,
    struct copybit_region_t const *region)
{
    int status = COPYBIT_SUCCESS;
    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    struct copybit_rect_t dr = { 0, 0, (int)dst->w, (int)dst->h };
    struct copybit_rect_t sr = { 0, 0, (int)src->w, (int)src->h };
    pthread_mutex_lock(&ctx->wait_cleanup_lock);
    status = stretch_copybit_internal(dev, dst, src, &dr, &sr, region, false);
    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
    return status;
}

/** Fill the rect on dst with RGBA color **/
static int fill_color(struct copybit_device_t *dev,
                      struct copybit_image_t const *dst,
                      struct copybit_rect_t const *rect,
                      uint32_t /*color*/)
{
    // TODO: Implement once c2d driver supports color fill
    if(!dev || !dst || !rect)
       return -EINVAL;

    return -EINVAL;
}

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

static void clean_up(copybit_context_t* ctx)
{
    void* ret;
    if (!ctx)
        return;

    // stop the wait_cleanup_thread
    pthread_mutex_lock(&ctx->wait_cleanup_lock);
    ctx->stop_thread = true;
    // Signal waiting thread
    pthread_cond_signal(&ctx->wait_cleanup_cond);
    pthread_mutex_unlock(&ctx->wait_cleanup_lock);
    // waits for the cleanup thread to exit
    pthread_join(ctx->wait_thread_id, &ret);
    pthread_mutex_destroy(&ctx->wait_cleanup_lock);
    pthread_cond_destroy (&ctx->wait_cleanup_cond);

    for (int i = 0; i < NUM_SURFACE_TYPES; i++) {
        if (ctx->dst[i])
            LINK_c2dDestroySurface(ctx->dst[i]);
    }

    for (int i = 0; i < MAX_RGB_SURFACES; i++) {
        if (ctx->blit_rgb_object[i].surface_id)
            LINK_c2dDestroySurface(ctx->blit_rgb_object[i].surface_id);
    }

    for (int i = 0; i < MAX_YUV_2_PLANE_SURFACES; i++) {
        if (ctx->blit_yuv_2_plane_object[i].surface_id)
            LINK_c2dDestroySurface(ctx->blit_yuv_2_plane_object[i].surface_id);
    }

    for (int i = 0; i < MAX_YUV_3_PLANE_SURFACES; i++) {
        if (ctx->blit_yuv_3_plane_object[i].surface_id)
            LINK_c2dDestroySurface(ctx->blit_yuv_3_plane_object[i].surface_id);
    }

    if (ctx->libc2d2) {
        ::dlclose(ctx->libc2d2);
        ALOGV("dlclose(libc2d2)");
    }

    free(ctx);
}

/** Close the copybit device */
static int close_copybit(struct hw_device_t *dev)
{
    struct copybit_context_t* ctx = (struct copybit_context_t*)dev;
    if (ctx) {
        free_temp_buffer(ctx->temp_src_buffer);
        free_temp_buffer(ctx->temp_dst_buffer);
    }
    clean_up(ctx);
    return 0;
}

/** Open a new instance of a copybit device using name */
static int open_copybit(const struct hw_module_t* module, const char* name,
                        struct hw_device_t** device)
{
    int status = COPYBIT_SUCCESS;
    if (strcmp(name, COPYBIT_HARDWARE_COPYBIT0)) {
        return COPYBIT_FAILURE;
    }

    C2D_RGB_SURFACE_DEF surfDefinition = {0};
    C2D_YUV_SURFACE_DEF yuvSurfaceDef = {0} ;
    struct copybit_context_t *ctx;

    ctx = (struct copybit_context_t *)malloc(sizeof(struct copybit_context_t));
    if(!ctx) {
        ALOGE("%s: malloc failed", __FUNCTION__);
        return COPYBIT_FAILURE;
    }

    /* initialize drawstate */
    memset(ctx, 0, sizeof(*ctx));
    ctx->libc2d2 = ::dlopen("libC2D2.so", RTLD_NOW);
    if (!ctx->libc2d2) {
        ALOGE("FATAL ERROR: could not dlopen libc2d2.so: %s", dlerror());
        clean_up(ctx);
        status = COPYBIT_FAILURE;
        *device = NULL;
        return status;
    }
    *(void **)&LINK_c2dCreateSurface = ::dlsym(ctx->libc2d2,
                                               "c2dCreateSurface");
    *(void **)&LINK_c2dUpdateSurface = ::dlsym(ctx->libc2d2,
                                               "c2dUpdateSurface");
    *(void **)&LINK_c2dReadSurface = ::dlsym(ctx->libc2d2,
                                             "c2dReadSurface");
    *(void **)&LINK_c2dDraw = ::dlsym(ctx->libc2d2, "c2dDraw");
    *(void **)&LINK_c2dFlush = ::dlsym(ctx->libc2d2, "c2dFlush");
    *(void **)&LINK_c2dFinish = ::dlsym(ctx->libc2d2, "c2dFinish");
    *(void **)&LINK_c2dWaitTimestamp = ::dlsym(ctx->libc2d2,
                                               "c2dWaitTimestamp");
    *(void **)&LINK_c2dDestroySurface = ::dlsym(ctx->libc2d2,
                                                "c2dDestroySurface");
    *(void **)&LINK_c2dMapAddr = ::dlsym(ctx->libc2d2,
                                         "c2dMapAddr");
    *(void **)&LINK_c2dUnMapAddr = ::dlsym(ctx->libc2d2,
                                           "c2dUnMapAddr");
    *(void **)&LINK_c2dGetDriverCapabilities = ::dlsym(ctx->libc2d2,
                                           "c2dGetDriverCapabilities");
    *(void **)&LINK_c2dCreateFenceFD = ::dlsym(ctx->libc2d2,
                                           "c2dCreateFenceFD");
    *(void **)&LINK_c2dFillSurface = ::dlsym(ctx->libc2d2,
                                           "c2dFillSurface");

    if (!LINK_c2dCreateSurface || !LINK_c2dUpdateSurface || !LINK_c2dReadSurface
        || !LINK_c2dDraw || !LINK_c2dFlush || !LINK_c2dWaitTimestamp ||
        !LINK_c2dFinish  || !LINK_c2dDestroySurface ||
        !LINK_c2dGetDriverCapabilities || !LINK_c2dCreateFenceFD ||
        !LINK_c2dFillSurface) {
        ALOGE("%s: dlsym ERROR", __FUNCTION__);
        clean_up(ctx);
        status = COPYBIT_FAILURE;
        *device = NULL;
        return status;
    }

    ctx->device.common.tag = HARDWARE_DEVICE_TAG;
    ctx->device.common.version = 1;
    ctx->device.common.module = (hw_module_t*)(module);
    ctx->device.common.close = close_copybit;
    ctx->device.set_parameter = set_parameter_copybit;
    ctx->device.get = get;
    ctx->device.blit = blit_copybit;
    ctx->device.set_sync = set_sync_copybit;
    ctx->device.stretch = stretch_copybit;
    ctx->device.finish = finish_copybit;
    ctx->device.flush_get_fence = flush_get_fence_copybit;
    ctx->device.clear = clear_copybit;
    ctx->device.fill_color = fill_color;

    /* Create RGB Surface */
    surfDefinition.buffer = (void*)0xdddddddd;
    surfDefinition.phys = (void*)0xdddddddd;
    surfDefinition.stride = 1 * 4;
    surfDefinition.width = 1;
    surfDefinition.height = 1;
    surfDefinition.format = C2D_COLOR_FORMAT_8888_ARGB;
    if (LINK_c2dCreateSurface(&(ctx->dst[RGB_SURFACE]), C2D_TARGET | C2D_SOURCE,
                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
                                                 C2D_SURFACE_WITH_PHYS |
                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
                                                 &surfDefinition)) {
        ALOGE("%s: create ctx->dst_surface[RGB_SURFACE] failed", __FUNCTION__);
        ctx->dst[RGB_SURFACE] = 0;
        clean_up(ctx);
        status = COPYBIT_FAILURE;
        *device = NULL;
        return status;
    }

    unsigned int surface_id = 0;
    for (int i = 0; i < MAX_RGB_SURFACES; i++)
    {
        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
                              (C2D_SURFACE_TYPE)(C2D_SURFACE_RGB_HOST |
                                                 C2D_SURFACE_WITH_PHYS |
                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
                                                 &surfDefinition)) {
            ALOGE("%s: create RGB source surface %d failed", __FUNCTION__, i);
            ctx->blit_rgb_object[i].surface_id = 0;
            status = COPYBIT_FAILURE;
            break;
        } else {
            ctx->blit_rgb_object[i].surface_id = surface_id;
            ALOGW("%s i = %d surface_id=%d",  __FUNCTION__, i,
                                          ctx->blit_rgb_object[i].surface_id);
        }
    }

    if (status == COPYBIT_FAILURE) {
        clean_up(ctx);
        status = COPYBIT_FAILURE;
        *device = NULL;
        return status;
    }

    // Create 2 plane YUV surfaces
    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_NV12;
    yuvSurfaceDef.width = 4;
    yuvSurfaceDef.height = 4;
    yuvSurfaceDef.plane0 = (void*)0xaaaaaaaa;
    yuvSurfaceDef.phys0 = (void*) 0xaaaaaaaa;
    yuvSurfaceDef.stride0 = 4;

    yuvSurfaceDef.plane1 = (void*)0xaaaaaaaa;
    yuvSurfaceDef.phys1 = (void*) 0xaaaaaaaa;
    yuvSurfaceDef.stride1 = 4;
    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_2_PLANES]),
                              C2D_TARGET | C2D_SOURCE,
                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
                               C2D_SURFACE_WITH_PHYS |
                               C2D_SURFACE_WITH_PHYS_DUMMY),
                              &yuvSurfaceDef)) {
        ALOGE("%s: create ctx->dst[YUV_SURFACE_2_PLANES] failed", __FUNCTION__);
        ctx->dst[YUV_SURFACE_2_PLANES] = 0;
        clean_up(ctx);
        status = COPYBIT_FAILURE;
        *device = NULL;
        return status;
    }

    for (int i=0; i < MAX_YUV_2_PLANE_SURFACES; i++)
    {
        if (LINK_c2dCreateSurface(&surface_id, C2D_TARGET | C2D_SOURCE,
                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
                                                 C2D_SURFACE_WITH_PHYS |
                                                 C2D_SURFACE_WITH_PHYS_DUMMY ),
                              &yuvSurfaceDef)) {
            ALOGE("%s: create YUV source %d failed", __FUNCTION__, i);
            ctx->blit_yuv_2_plane_object[i].surface_id = 0;
            status = COPYBIT_FAILURE;
            break;
        } else {
            ctx->blit_yuv_2_plane_object[i].surface_id = surface_id;
            ALOGW("%s: 2 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
                                   ctx->blit_yuv_2_plane_object[i].surface_id);
        }
    }

    if (status == COPYBIT_FAILURE) {
        clean_up(ctx);
        status = COPYBIT_FAILURE;
        *device = NULL;
        return status;
    }

    // Create YUV 3 plane surfaces
    yuvSurfaceDef.format = C2D_COLOR_FORMAT_420_YV12;
    yuvSurfaceDef.plane2 = (void*)0xaaaaaaaa;
    yuvSurfaceDef.phys2 = (void*) 0xaaaaaaaa;
    yuvSurfaceDef.stride2 = 4;

    if (LINK_c2dCreateSurface(&(ctx->dst[YUV_SURFACE_3_PLANES]),
                              C2D_TARGET | C2D_SOURCE,
                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
                                                 C2D_SURFACE_WITH_PHYS |
                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
                              &yuvSurfaceDef)) {
        ALOGE("%s: create ctx->dst[YUV_SURFACE_3_PLANES] failed", __FUNCTION__);
        ctx->dst[YUV_SURFACE_3_PLANES] = 0;
        clean_up(ctx);
        status = COPYBIT_FAILURE;
        *device = NULL;
        return status;
    }

    for (int i=0; i < MAX_YUV_3_PLANE_SURFACES; i++)
    {
        if (LINK_c2dCreateSurface(&(surface_id),
                              C2D_TARGET | C2D_SOURCE,
                              (C2D_SURFACE_TYPE)(C2D_SURFACE_YUV_HOST |
                                                 C2D_SURFACE_WITH_PHYS |
                                                 C2D_SURFACE_WITH_PHYS_DUMMY),
                              &yuvSurfaceDef)) {
            ALOGE("%s: create 3 plane YUV surface %d failed", __FUNCTION__, i);
            ctx->blit_yuv_3_plane_object[i].surface_id = 0;
            status = COPYBIT_FAILURE;
            break;
        } else {
            ctx->blit_yuv_3_plane_object[i].surface_id = surface_id;
            ALOGW("%s: 3 Plane YUV i=%d surface_id=%d",  __FUNCTION__, i,
                                   ctx->blit_yuv_3_plane_object[i].surface_id);
        }
    }

    if (status == COPYBIT_FAILURE) {
        clean_up(ctx);
        status = COPYBIT_FAILURE;
        *device = NULL;
        return status;
    }

    if (LINK_c2dGetDriverCapabilities(&(ctx->c2d_driver_info))) {
         ALOGE("%s: LINK_c2dGetDriverCapabilities failed", __FUNCTION__);
         clean_up(ctx);
         status = COPYBIT_FAILURE;
        *device = NULL;
        return status;
    }
    // Initialize context variables.
    ctx->trg_transform = C2D_TARGET_ROTATE_0;

    ctx->temp_src_buffer.fd = -1;
    ctx->temp_src_buffer.base = 0;
    ctx->temp_src_buffer.size = 0;

    ctx->temp_dst_buffer.fd = -1;
    ctx->temp_dst_buffer.base = 0;
    ctx->temp_dst_buffer.size = 0;

    ctx->fb_width = 0;
    ctx->fb_height = 0;

    ctx->blit_rgb_count = 0;
    ctx->blit_yuv_2_plane_count = 0;
    ctx->blit_yuv_3_plane_count = 0;
    ctx->blit_count = 0;

    ctx->wait_timestamp = false;
    ctx->stop_thread = false;
    pthread_mutex_init(&(ctx->wait_cleanup_lock), NULL);
    pthread_cond_init(&(ctx->wait_cleanup_cond), NULL);
    /* Start the wait thread */
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    pthread_create(&ctx->wait_thread_id, &attr, &c2d_wait_loop,
                                                            (void *)ctx);
    pthread_attr_destroy(&attr);

    *device = &ctx->device.common;
    return status;
}
