/*
 * Copyright (C) 2010 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.
 */

/*
 *
 * @author Rama, Meka(v.meka@samsung.com)
           Sangwoo, Park(sw5771.park@samsung.com)
           Jamie Oh (jung-min.oh@samsung.com)
 * @date   2011-07-28
 *
 */

#include <sys/resource.h>
#include <cutils/log.h>
#include <cutils/atomic.h>
#include <EGL/egl.h>
#include <GLES/gl.h>
#include <hardware_legacy/uevent.h>
#include "SecHWCUtils.h"

static IMG_gralloc_module_public_t *gpsGrallocModule;

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

static struct hw_module_methods_t hwc_module_methods = {
    open: hwc_device_open
};

hwc_module_t HAL_MODULE_INFO_SYM = {
    common: {
        tag: HARDWARE_MODULE_TAG,
        module_api_version: HWC_MODULE_API_VERSION_0_1,
        hal_api_version: HARDWARE_HAL_API_VERSION,
        id: HWC_HARDWARE_MODULE_ID,
        name: "Samsung S5PC11X hwcomposer module",
        author: "SAMSUNG",
        methods: &hwc_module_methods,
    }
};

static void dump_layer(hwc_layer_t const* l) {
    ALOGD("\ttype=%d, flags=%08x, handle=%p, tr=%02x, blend=%04x, {%d,%d,%d,%d}, {%d,%d,%d,%d}",
            l->compositionType, l->flags, l->handle, l->transform, l->blending,
            l->sourceCrop.left,
            l->sourceCrop.top,
            l->sourceCrop.right,
            l->sourceCrop.bottom,
            l->displayFrame.left,
            l->displayFrame.top,
            l->displayFrame.right,
            l->displayFrame.bottom);
}

static int set_src_dst_info(hwc_layer_t *cur,
                            struct hwc_win_info_t *win,
                            struct sec_img *src_img,
                            struct sec_img *dst_img,
                            struct sec_rect *src_rect,
                            struct sec_rect *dst_rect,
                            int win_idx)
{
    IMG_native_handle_t *prev_handle = (IMG_native_handle_t *)(cur->handle);

    // set src image
    src_img->w       = prev_handle->iWidth;
    src_img->h       = prev_handle->iHeight;
    src_img->format  = prev_handle->iFormat;
    src_img->base    = NULL;
    src_img->offset  = 0;
    src_img->mem_id  =0;

    src_img->mem_type = HWC_PHYS_MEM_TYPE;
    src_img->w = (src_img->w + 15) & (~15);
    src_img->h = (src_img->h + 1) & (~1) ;

    //set src rect
    src_rect->x = SEC_MAX(cur->sourceCrop.left, 0);
    src_rect->y = SEC_MAX(cur->sourceCrop.top, 0);
    src_rect->w = SEC_MAX(cur->sourceCrop.right - cur->sourceCrop.left, 0);
    src_rect->w = SEC_MIN(src_rect->w, src_img->w - src_rect->x);
    src_rect->h = SEC_MAX(cur->sourceCrop.bottom - cur->sourceCrop.top, 0);
    src_rect->h = SEC_MIN(src_rect->h, src_img->h - src_rect->y);

    //set dst image
    dst_img->w = win->lcd_info.xres;
    dst_img->h = win->lcd_info.yres;

    switch (win->lcd_info.bits_per_pixel) {
    case 32:
        dst_img->format = HAL_PIXEL_FORMAT_RGBX_8888;
        break;
    default:
        dst_img->format = HAL_PIXEL_FORMAT_RGB_565;
        break;
    }

    dst_img->base     = win->addr[win->buf_index];
    dst_img->offset   = 0;
    dst_img->mem_id   = 0;
    dst_img->mem_type = HWC_PHYS_MEM_TYPE;

    //set dst rect
    //fimc dst image will be stored from left top corner
    dst_rect->x = 0;
    dst_rect->y = 0;
    dst_rect->w = win->rect_info.w;
    dst_rect->h = win->rect_info.h;

    ALOGV("%s::sr_x %d sr_y %d sr_w %d sr_h %d dr_x %d dr_y %d dr_w %d dr_h %d ",
            __func__, src_rect->x, src_rect->y, src_rect->w, src_rect->h,
            dst_rect->x, dst_rect->y, dst_rect->w, dst_rect->h);

    return 0;
}

static int get_hwc_compos_decision(hwc_layer_t* cur)
{
    if(cur->flags & HWC_SKIP_LAYER || !cur->handle) {
        ALOGV("%s::is_skip_layer %d cur->handle %x",
                __func__, cur->flags & HWC_SKIP_LAYER, (uint32_t)cur->handle);
        return HWC_FRAMEBUFFER;
    }

    IMG_native_handle_t *prev_handle = (IMG_native_handle_t *)(cur->handle);
    int compositionType = HWC_FRAMEBUFFER;

    /* check here....if we have any resolution constraints */
    if (((cur->sourceCrop.right - cur->sourceCrop.left) < 16) ||
        ((cur->sourceCrop.bottom - cur->sourceCrop.top) < 8))
        return compositionType;

    if ((cur->transform == HAL_TRANSFORM_ROT_90) ||
        (cur->transform == HAL_TRANSFORM_ROT_270)) {
        if(((cur->displayFrame.right - cur->displayFrame.left) < 4)||
           ((cur->displayFrame.bottom - cur->displayFrame.top) < 8))
            return compositionType;
        } else if (((cur->displayFrame.right - cur->displayFrame.left) < 8) ||
                   ((cur->displayFrame.bottom - cur->displayFrame.top) < 4))
         return compositionType;

    if((prev_handle->usage & GRALLOC_USAGE_PHYS_CONTIG) &&
       (cur->blending == HWC_BLENDING_NONE))
        compositionType = HWC_OVERLAY;
    else
        compositionType = HWC_FRAMEBUFFER;

    ALOGV("%s::compositionType %d bpp %d format %x usage %x",
            __func__,compositionType, prev_handle->uiBpp, prev_handle->iFormat,
            prev_handle->usage & GRALLOC_USAGE_PHYS_CONTIG);

    return  compositionType;
}

static int assign_overlay_window(struct hwc_context_t *ctx,
                                 hwc_layer_t *cur,
                                 int win_idx,
                                 int layer_idx)
{
    struct hwc_win_info_t *win;
    sec_rect rect;
    int ret = 0;

    if(NUM_OF_WIN <= win_idx)
        return -1;

    win = &ctx->win[win_idx];

    rect.x = SEC_MAX(cur->displayFrame.left, 0);
    rect.y = SEC_MAX(cur->displayFrame.top, 0);
    rect.w = SEC_MIN(cur->displayFrame.right - rect.x, win->lcd_info.xres - rect.x);
    rect.h = SEC_MIN(cur->displayFrame.bottom - rect.y, win->lcd_info.yres - rect.y);
    win->set_win_flag = 0;

    if((rect.x != win->rect_info.x) || (rect.y != win->rect_info.y) ||
       (rect.w != win->rect_info.w) || (rect.h != win->rect_info.h)){
            win->rect_info.x = rect.x;
            win->rect_info.y = rect.y;
            win->rect_info.w = rect.w;
            win->rect_info.h = rect.h;
            win->set_win_flag = 1;
            win->layer_prev_buf = 0;
    }

    win->layer_index = layer_idx;
    win->status = HWC_WIN_RESERVED;

    ALOGV("%s:: win_x %d win_y %d win_w %d win_h %d lay_idx %d win_idx %d",
            __func__, win->rect_info.x, win->rect_info.y, win->rect_info.w,
            win->rect_info.h, win->layer_index, win_idx );

    return 0;
}

static void reset_win_rect_info(hwc_win_info_t *win)
{
    win->rect_info.x = 0;
    win->rect_info.y = 0;
    win->rect_info.w = 0;
    win->rect_info.h = 0;
    return;
}

static int hwc_prepare(hwc_composer_device_t *dev, hwc_layer_list_t* list)
{

    struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
    int overlay_win_cnt = 0;
    int compositionType = 0;
    int ret;

    //if geometry is not changed, there is no need to do any work here
    if( !list || (!(list->flags & HWC_GEOMETRY_CHANGED)))
        return 0;

    //all the windows are free here....
    for (int i = 0; i < NUM_OF_WIN; i++) {
        ctx->win[i].status = HWC_WIN_FREE;
        ctx->win[i].buf_index = 0;
    }
    ctx->num_of_hwc_layer = 0;
    ctx->num_of_fb_layer = 0;
    ALOGV("%s:: hwc_prepare list->numHwLayers %d", __func__, list->numHwLayers);

    for (int i = 0; i < list->numHwLayers ; i++) {
        hwc_layer_t* cur = &list->hwLayers[i];

        if (overlay_win_cnt < NUM_OF_WIN) {
            compositionType = get_hwc_compos_decision(cur);

            if (compositionType == HWC_FRAMEBUFFER) {
                cur->compositionType = HWC_FRAMEBUFFER;
                ctx->num_of_fb_layer++;
            } else {
                ret = assign_overlay_window(ctx, cur, overlay_win_cnt, i);
                if (ret != 0) {
                    cur->compositionType = HWC_FRAMEBUFFER;
                    ctx->num_of_fb_layer++;
                    continue;
                }

                cur->compositionType = HWC_OVERLAY;
                cur->hints = HWC_HINT_CLEAR_FB;
                overlay_win_cnt++;
                ctx->num_of_hwc_layer++;
            }
        } else {
            cur->compositionType = HWC_FRAMEBUFFER;
            ctx->num_of_fb_layer++;
        }
    }

    if(list->numHwLayers != (ctx->num_of_fb_layer + ctx->num_of_hwc_layer))
        ALOGV("%s:: numHwLayers %d num_of_fb_layer %d num_of_hwc_layer %d ",
                __func__, list->numHwLayers, ctx->num_of_fb_layer,
                ctx->num_of_hwc_layer);

    if (overlay_win_cnt < NUM_OF_WIN) {
        //turn off the free windows
        for (int i = overlay_win_cnt; i < NUM_OF_WIN; i++) {
            window_hide(&ctx->win[i]);
            reset_win_rect_info(&ctx->win[i]);
        }
    }
    return 0;
}

static int hwc_set(hwc_composer_device_t *dev,
                   hwc_display_t dpy,
                   hwc_surface_t sur,
                   hwc_layer_list_t* list)
{
    struct hwc_context_t *ctx = (struct hwc_context_t *)dev;
    unsigned int phyAddr[MAX_NUM_PLANES];
    int skipped_window_mask = 0;
    hwc_layer_t* cur;
    struct hwc_win_info_t *win;
    int ret;
    struct sec_img src_img;
    struct sec_img dst_img;
    struct sec_rect src_rect;
    struct sec_rect dst_rect;

    if (dpy == NULL && sur == NULL && list == NULL) {
        // release our resources, the screen is turning off
        // in our case, there is nothing to do.
        ctx->num_of_fb_layer_prev = 0;
        return 0;
    }

    bool need_swap_buffers = ctx->num_of_fb_layer > 0;

    /*
     * H/W composer documentation states:
     * There is an implicit layer containing opaque black
     * pixels behind all the layers in the list.
     * It is the responsibility of the hwcomposer module to make
     * sure black pixels are output (or blended from).
     *
     * Since we're using a blitter, we need to erase the frame-buffer when
     * switching to all-overlay mode.
     *
     */
    if (ctx->num_of_hwc_layer &&
        ctx->num_of_fb_layer==0 && ctx->num_of_fb_layer_prev) {
        /* we're clearing the screen using GLES here, this is very
         * hack-ish, ideal we would use the fimc (if it can do it) */
        glDisable(GL_SCISSOR_TEST);
        glClearColor(0, 0, 0, 0);
        glClear(GL_COLOR_BUFFER_BIT);
        glEnable(GL_SCISSOR_TEST);
        need_swap_buffers = true;
    }

    ctx->num_of_fb_layer_prev = ctx->num_of_fb_layer;

    if (need_swap_buffers || !list) {
        EGLBoolean sucess = eglSwapBuffers((EGLDisplay)dpy, (EGLSurface)sur);
        if (!sucess) {
            return HWC_EGL_ERROR;
        }
    }

    if (!list) {
        /* turn off the all windows */
        for (int i = 0; i < NUM_OF_WIN; i++) {
            window_hide(&ctx->win[i]);
            reset_win_rect_info(&ctx->win[i]);
            ctx->win[i].status = HWC_WIN_FREE;
        }
        ctx->num_of_hwc_layer = 0;
        return 0;
    }

    if(ctx->num_of_hwc_layer > NUM_OF_WIN)
        ctx->num_of_hwc_layer = NUM_OF_WIN;

    /* compose hardware layers here */
    for (uint32_t i = 0; i < ctx->num_of_hwc_layer; i++) {
        win = &ctx->win[i];
        if (win->status == HWC_WIN_RESERVED) {
            cur = &list->hwLayers[win->layer_index];

            if (cur->compositionType == HWC_OVERLAY) {

                ret = gpsGrallocModule->GetPhyAddrs(gpsGrallocModule,
                        cur->handle, phyAddr);
                if (ret) {
                    ALOGE("%s::GetPhyAddrs fail : ret=%d\n", __func__, ret);
                    skipped_window_mask |= (1 << i);
                    continue;
                }

                /* initialize the src & dist context for fimc */
                set_src_dst_info (cur, win, &src_img, &dst_img, &src_rect,
                        &dst_rect, i);

                ret = runFimc(ctx, &src_img, &src_rect, &dst_img, &dst_rect,
                        phyAddr, cur->transform);
                if (ret < 0){
                   ALOGE("%s::runFimc fail : ret=%d\n", __func__, ret);
                   skipped_window_mask |= (1 << i);
                   continue;
                }

                if (win->set_win_flag == 1) {
                    /* turnoff the window and set the window position with new conf... */
                    if (window_set_pos(win) < 0) {
                        ALOGE("%s::window_set_pos is failed : %s", __func__,
                                strerror(errno));
                        skipped_window_mask |= (1 << i);
                        continue;
                    }
                    win->set_win_flag = 0;
                }

                /* is the frame didn't change, it needs to be composited
                 * because something else below it could have changed, however
                 * it doesn't need to be swapped.
                 */
                if (win->layer_prev_buf != (uint32_t)cur->handle) {
                    win->layer_prev_buf = (uint32_t)cur->handle;
                    window_pan_display(win);
                    win->buf_index = (win->buf_index + 1) % NUM_OF_WIN_BUF;
                }

                if(win->power_state == 0)
                    window_show(win);

            } else {
                ALOGE("%s:: error : layer %d compositionType should have been \
                        HWC_OVERLAY", __func__, win->layer_index);
                skipped_window_mask |= (1 << i);
                continue;
            }
         } else {
             ALOGE("%s:: error : window status should have been HWC_WIN_RESERVED \
                     by now... ", __func__);
             skipped_window_mask |= (1 << i);
             continue;
         }
    }

    if (skipped_window_mask) {
        //turn off the free windows
        for (int i = 0; i < NUM_OF_WIN; i++) {
            if (skipped_window_mask & (1 << i))
                window_hide(&ctx->win[i]);
        }
    }

    return 0;
}

static void hwc_registerProcs(struct hwc_composer_device* dev,
        hwc_procs_t const* procs)
{
    struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
    ctx->procs = const_cast<hwc_procs_t *>(procs);
}

static int hwc_query(struct hwc_composer_device* dev,
        int what, int* value)
{
    struct hwc_context_t* ctx = (struct hwc_context_t*)dev;

    switch (what) {
    case HWC_BACKGROUND_LAYER_SUPPORTED:
        // we don't support the background layer yet
        value[0] = 0;
        break;
    case HWC_VSYNC_PERIOD:
        // vsync period in nanosecond
        value[0] = 1000000000.0 / gpsGrallocModule->psFrameBufferDevice->base.fps;
        break;
    default:
        // unsupported query
        return -EINVAL;
    }
    return 0;
}

static int hwc_eventControl(struct hwc_composer_device* dev,
        int event, int enabled)
{
    struct hwc_context_t* ctx = (struct hwc_context_t*)dev;

    switch (event) {
    case HWC_EVENT_VSYNC:
        int val = !!enabled;
        int err = ioctl(ctx->global_lcd_win.fd, S3CFB_SET_VSYNC_INT, &val);
        if (err < 0)
            return -errno;

        return 0;
    }

    return -EINVAL;
}

void handle_vsync_uevent(hwc_context_t *ctx, const char *buff, int len)
{
    uint64_t timestamp = 0;
    const char *s = buff;

    if(!ctx->procs || !ctx->procs->vsync)
       return;

    s += strlen(s) + 1;

    while(*s) {
        if (!strncmp(s, "VSYNC=", strlen("VSYNC=")))
            timestamp = strtoull(s + strlen("VSYNC="), NULL, 0);

        s += strlen(s) + 1;
        if (s - buff >= len)
            break;
    }

    ctx->procs->vsync(ctx->procs, 0, timestamp);
}

static void *hwc_vsync_thread(void *data)
{
    hwc_context_t *ctx = (hwc_context_t *)(data);
    char uevent_desc[4096];
    memset(uevent_desc, 0, sizeof(uevent_desc));

    setpriority(PRIO_PROCESS, 0, HAL_PRIORITY_URGENT_DISPLAY);

    uevent_init();
    while(true) {
        int len = uevent_next_event(uevent_desc, sizeof(uevent_desc) - 2);

        bool vsync = !strcmp(uevent_desc, "change@/devices/platform/s3cfb");
        if(vsync)
            handle_vsync_uevent(ctx, uevent_desc, len);
    }

    return NULL;
}

static int hwc_device_close(struct hw_device_t *dev)
{
    struct hwc_context_t* ctx = (struct hwc_context_t*)dev;
    int ret = 0;
    int i;

    if (ctx) {
        if (destroyFimc(&ctx->fimc) < 0) {
            ALOGE("%s::destroyFimc fail", __func__);
            ret = -1;
        }

        if (window_close(&ctx->global_lcd_win) < 0) {
            ALOGE("%s::window_close() fail", __func__);
            ret = -1;
        }

        for (i = 0; i < NUM_OF_WIN; i++) {
            if (window_close(&ctx->win[i]) < 0) {
                ALOGE("%s::window_close() fail", __func__);
                ret = -1;
            }
        }

        // TODO: stop vsync_thread

        free(ctx);
    }
    return ret;
}

static const struct hwc_methods hwc_methods = {
    eventControl: hwc_eventControl
};

static int hwc_device_open(const struct hw_module_t* module, const char* name,
        struct hw_device_t** device)
{
    int status = 0;
    int err;
    struct hwc_win_info_t *win;

    if(hw_get_module(GRALLOC_HARDWARE_MODULE_ID,
                (const hw_module_t**)&gpsGrallocModule))
        return -EINVAL;

    if(strcmp(gpsGrallocModule->base.common.author, "Imagination Technologies"))
        return -EINVAL;

    if (strcmp(name, HWC_HARDWARE_COMPOSER))
        return -EINVAL;

    struct hwc_context_t *dev;
    dev = (hwc_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 = HWC_DEVICE_API_VERSION_0_3;
    dev->device.common.module = const_cast<hw_module_t*>(module);
    dev->device.common.close = hwc_device_close;

    dev->device.prepare = hwc_prepare;
    dev->device.set = hwc_set;
    dev->device.registerProcs = hwc_registerProcs;
    dev->device.query = hwc_query;
    dev->device.methods = &hwc_methods;

    *device = &dev->device.common;

    /* initializing */
    memset(&(dev->fimc), 0, sizeof(s5p_fimc_t));
    dev->fimc.dev_fd = -1;

    /* open WIN0 & WIN1 here */
    for (int i = 0; i < NUM_OF_WIN; i++) {
        if (window_open(&(dev->win[i]), i) < 0) {
             ALOGE("%s:: Failed to open window %d device ", __func__, i);
             status = -EINVAL;
             goto err;
        }
    }

    /* open window 2, used to query global LCD info */
    if (window_open(&dev->global_lcd_win, 2) < 0) {
        ALOGE("%s:: Failed to open window 2 device ", __func__);
        status = -EINVAL;
        goto err;
    }

    /* get default window config */
    if (window_get_global_lcd_info(dev) < 0) {
        ALOGE("%s::window_get_global_lcd_info is failed : %s",
                __func__, strerror(errno));
        status = -EINVAL;
        goto err;
    }

    dev->lcd_info.yres_virtual = dev->lcd_info.yres * NUM_OF_WIN_BUF;

    /* initialize the window context */
    for (int i = 0; i < NUM_OF_WIN; i++) {
        win = &dev->win[i];
        memcpy(&win->lcd_info, &dev->lcd_info, sizeof(struct fb_var_screeninfo));
        memcpy(&win->var_info, &dev->lcd_info, sizeof(struct fb_var_screeninfo));

        win->rect_info.x = 0;
        win->rect_info.y = 0;
        win->rect_info.w = win->var_info.xres;
        win->rect_info.h = win->var_info.yres;

        if (window_set_pos(win) < 0) {
            ALOGE("%s::window_set_pos is failed : %s",
                    __func__, strerror(errno));
            status = -EINVAL;
            goto err;
        }

        if (window_get_info(win) < 0) {
            ALOGE("%s::window_get_info is failed : %s",
                    __func__, strerror(errno));
            status = -EINVAL;
            goto err;
        }

        win->size = win->fix_info.line_length * win->var_info.yres;

        if (!win->fix_info.smem_start){
            ALOGE("%s:: win-%d failed to get the reserved memory", __func__, i);
            status = -EINVAL;
            goto err;
        }

        for (int j = 0; j < NUM_OF_WIN_BUF; j++) {
            win->addr[j] = win->fix_info.smem_start + (win->size * j);
            ALOGI("%s::win-%d add[%d] %x ", __func__, i, j, win->addr[j]);
        }
    }

    /* open pp */
    if (createFimc(&dev->fimc) < 0) {
        ALOGE("%s::creatFimc() fail", __func__);
        status = -EINVAL;
        goto err;
    }

    err = pthread_create(&dev->vsync_thread, NULL, hwc_vsync_thread, dev);
    if (err) {
        ALOGE("%s::pthread_create() failed : %s", __func__, strerror(err));
        status = -err;
        goto err;
    }

    ALOGD("%s:: success\n", __func__);

    return 0;

err:
    if (destroyFimc(&dev->fimc) < 0)
        ALOGE("%s::destroyFimc() fail", __func__);

    if (window_close(&dev->global_lcd_win) < 0)
        ALOGE("%s::window_close() fail", __func__);

    for (int i = 0; i < NUM_OF_WIN; i++) {
        if (window_close(&dev->win[i]) < 0)
            ALOGE("%s::window_close() fail", __func__);
    }

    return status;
}
