/*
* Copyright (C) 2008 The Android Open Source Project
* Copyright (c) 2010-2014, The Linux Foundation. All rights reserved.
*
* 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 <math.h>
#include <mdp_version.h>
#include "overlayUtils.h"
#include "overlayMdp.h"
#include "mdp_version.h"
#include <overlay.h>

#define HSIC_SETTINGS_DEBUG 0

using namespace qdutils;

namespace ovutils = overlay::utils;
namespace overlay {

bool MdpCtrl::init(const int& dpy) {
    int fbnum = Overlay::getFbForDpy(dpy);
    if( fbnum < 0 ) {
        ALOGE("%s: Invalid FB for the display: %d",__FUNCTION__, dpy);
        return false;
    }

    // FD init
    if(!utils::openDev(mFd, fbnum,
                Res::fbPath, O_RDWR)){
        ALOGE("Ctrl failed to init fbnum=%d", fbnum);
        return false;
    }
    mDpy = dpy;
    return true;
}

void MdpCtrl::reset() {
    utils::memset0(mOVInfo);
    mOVInfo.id = MSMFB_NEW_REQUEST;
    mOrientation = utils::OVERLAY_TRANSFORM_0;
    mDpy = 0;
#ifdef USES_POST_PROCESSING
    memset(&mParams, 0, sizeof(struct compute_params));
    mParams.params.conv_params.order = hsic_order_hsc_i;
    mParams.params.conv_params.interface = interface_rec601;
    mParams.params.conv_params.cc_matrix[0][0] = 1;
    mParams.params.conv_params.cc_matrix[1][1] = 1;
    mParams.params.conv_params.cc_matrix[2][2] = 1;
#endif
}

bool MdpCtrl::close() {
    bool result = true;
    if(MSMFB_NEW_REQUEST != static_cast<int>(mOVInfo.id)) {
        if(!mdp_wrapper::unsetOverlay(mFd.getFD(), mOVInfo.id)) {
            ALOGE("MdpCtrl close error in unset");
            result = false;
        }
    }
#ifdef USES_POST_PROCESSING
    /* free allocated memory in PP */
    if (mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data)
            free(mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data);
#endif
    reset();

    if(!mFd.close()) {
        result = false;
    }

    return result;
}

void MdpCtrl::setSource(const utils::PipeArgs& args) {
    setSrcWhf(args.whf);

    //TODO These are hardcoded. Can be moved out of setSource.
    mOVInfo.transp_mask = 0xffffffff;

    //TODO These calls should ideally be a part of setPipeParams API
    setFlags(args.mdpFlags);
    setZ(args.zorder);
    setPlaneAlpha(args.planeAlpha);
    setBlending(args.blending);
}

void MdpCtrl::setCrop(const utils::Dim& d) {
    setSrcRectDim(d);
}

void MdpCtrl::setColor(const uint32_t color) {
    mOVInfo.bg_color = color;
}

void MdpCtrl::setPosition(const overlay::utils::Dim& d) {
    setDstRectDim(d);
}

void MdpCtrl::setTransform(const utils::eTransform& orient) {
    int rot = utils::getMdpOrient(orient);
    setUserData(rot);
    mOrientation = static_cast<utils::eTransform>(rot);
}

void MdpCtrl::setPipeType(const utils::eMdpPipeType& pType){
    switch((int) pType){
        case utils::OV_MDP_PIPE_RGB:
            mOVInfo.pipe_type = PIPE_TYPE_RGB;
            break;
        case utils::OV_MDP_PIPE_VG:
            mOVInfo.pipe_type = PIPE_TYPE_VIG;
            break;
        case utils::OV_MDP_PIPE_DMA:
            mOVInfo.pipe_type = PIPE_TYPE_DMA;
            break;
        default:
            mOVInfo.pipe_type = PIPE_TYPE_AUTO;
            break;
    }
}

void MdpCtrl::doTransform() {
    setRotationFlags();
    utils::Whf whf = getSrcWhf();
    utils::Dim dim = getSrcRectDim();
    utils::preRotateSource(mOrientation, whf, dim);
    setSrcWhf(whf);
    setSrcRectDim(dim);
}

void MdpCtrl::doDownscale() {
    if(MDPVersion::getInstance().supportsDecimation()) {
        utils::getDecimationFactor(mOVInfo.src_rect.w, mOVInfo.src_rect.h,
                mOVInfo.dst_rect.w, mOVInfo.dst_rect.h, mOVInfo.horz_deci,
                mOVInfo.vert_deci);
    }
}

bool MdpCtrl::set() {
    int mdpVersion = MDPVersion::getInstance().getMDPVersion();
    //deferred calcs, so APIs could be called in any order.
    doTransform();
    utils::Whf whf = getSrcWhf();
    if(utils::isYuv(whf.format)) {
        utils::normalizeCrop(mOVInfo.src_rect.x, mOVInfo.src_rect.w);
        utils::normalizeCrop(mOVInfo.src_rect.y, mOVInfo.src_rect.h);
        if(mdpVersion < MDSS_V5) {
            utils::even_floor(mOVInfo.dst_rect.w);
            utils::even_floor(mOVInfo.dst_rect.h);
        } else if (mOVInfo.flags & MDP_DEINTERLACE) {
            // For interlaced, crop.h should be 4-aligned
            if (!(mOVInfo.flags & MDP_SOURCE_ROTATED_90) &&
                (mOVInfo.src_rect.h % 4))
                mOVInfo.src_rect.h = utils::aligndown(mOVInfo.src_rect.h, 4);
            // For interlaced, width must be multiple of 4 when rotated 90deg.
            else if ((mOVInfo.flags & MDP_SOURCE_ROTATED_90) &&
                (mOVInfo.src_rect.w % 4))
                mOVInfo.src_rect.w = utils::aligndown(mOVInfo.src_rect.w, 4);
        }
    } else {
        // On 8974 and 8x26, there is a limitation of 1-pixel down-scaling
        if (mdpVersion >= MDSS_V5) {
            if(qdutils::MDPVersion::getInstance().is8x74v2() ||
                    qdutils::MDPVersion::getInstance().is8x26()) {
                if (mOVInfo.src_rect.w - mOVInfo.dst_rect.w == 1)
                    mOVInfo.src_rect.w -= 1;
                if (mOVInfo.src_rect.h - mOVInfo.dst_rect.h == 1)
                    mOVInfo.src_rect.h -= 1;
            }
        }
    }

    doDownscale();
    return true;
}

//Update src format based on rotator's destination format.
void MdpCtrl::updateSrcFormat(const uint32_t& rotDestFmt) {
    utils::Whf whf = getSrcWhf();
    whf.format =  rotDestFmt;
    setSrcWhf(whf);
}

void MdpCtrl::dump() const {
    ALOGE("== Dump MdpCtrl start ==");
    mFd.dump();
    mdp_wrapper::dump("mOVInfo", mOVInfo);
    ALOGE("== Dump MdpCtrl end ==");
}

void MdpCtrl::getDump(char *buf, size_t len) {
    ovutils::getDump(buf, len, "Ctrl", mOVInfo);
}

void MdpData::dump() const {
    ALOGE("== Dump MdpData start ==");
    mFd.dump();
    mdp_wrapper::dump("mOvData", mOvData);
    ALOGE("== Dump MdpData end ==");
}

void MdpData::getDump(char *buf, size_t len) {
    ovutils::getDump(buf, len, "Data", mOvData);
}

bool MdpCtrl::setVisualParams(const MetaData_t& data) {
    ALOGD_IF(0, "In %s: data.operation = %d", __FUNCTION__, data.operation);

    // Set Color Space for MDP to configure CSC matrix
    mOVInfo.color_space = ITU_R_601;
    if (data.operation & UPDATE_COLOR_SPACE) {
        mOVInfo.color_space = data.colorSpace;
    }

#ifdef USES_POST_PROCESSING
    bool needUpdate = false;
    /* calculate the data */
    if (data.operation & PP_PARAM_HSIC) {
        if (mParams.params.pa_params.hue != data.hsicData.hue) {
            ALOGD_IF(HSIC_SETTINGS_DEBUG,
                "Hue has changed from %d to %d",
                mParams.params.pa_params.hue,data.hsicData.hue);
            needUpdate = true;
        }

        if (!isEqual(mParams.params.pa_params.sat,
            data.hsicData.saturation)) {
            ALOGD_IF(HSIC_SETTINGS_DEBUG,
                "Saturation has changed from %f to %f",
                mParams.params.pa_params.sat,
                data.hsicData.saturation);
            needUpdate = true;
        }

        if (mParams.params.pa_params.intensity != data.hsicData.intensity) {
            ALOGD_IF(HSIC_SETTINGS_DEBUG,
                "Intensity has changed from %d to %d",
                mParams.params.pa_params.intensity,
                data.hsicData.intensity);
            needUpdate = true;
        }

        if (!isEqual(mParams.params.pa_params.contrast,
            data.hsicData.contrast)) {
            ALOGD_IF(HSIC_SETTINGS_DEBUG,
                "Contrast has changed from %f to %f",
                mParams.params.pa_params.contrast,
                data.hsicData.contrast);
            needUpdate = true;
        }

        if (needUpdate) {
            mParams.params.pa_params.hue = data.hsicData.hue;
            mParams.params.pa_params.sat = data.hsicData.saturation;
            mParams.params.pa_params.intensity = data.hsicData.intensity;
            mParams.params.pa_params.contrast = data.hsicData.contrast;
            mParams.params.pa_params.ops = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
            mParams.operation |= PP_OP_PA;
        }
    }

    if (data.operation & PP_PARAM_SHARP2) {
        if (mParams.params.sharp_params.strength != data.Sharp2Data.strength) {
            needUpdate = true;
        }
        if (mParams.params.sharp_params.edge_thr != data.Sharp2Data.edge_thr) {
            needUpdate = true;
        }
        if (mParams.params.sharp_params.smooth_thr !=
                data.Sharp2Data.smooth_thr) {
            needUpdate = true;
        }
        if (mParams.params.sharp_params.noise_thr !=
                data.Sharp2Data.noise_thr) {
            needUpdate = true;
        }

        if (needUpdate) {
            mParams.params.sharp_params.strength = data.Sharp2Data.strength;
            mParams.params.sharp_params.edge_thr = data.Sharp2Data.edge_thr;
            mParams.params.sharp_params.smooth_thr =
                data.Sharp2Data.smooth_thr;
            mParams.params.sharp_params.noise_thr = data.Sharp2Data.noise_thr;
            mParams.params.sharp_params.ops =
                MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
            mParams.operation |= PP_OP_SHARP;
        }
    }

    if (data.operation & PP_PARAM_IGC) {
        if (mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data == NULL){
            uint32_t *igcData
                = (uint32_t *)malloc(2 * MAX_IGC_LUT_ENTRIES * sizeof(uint32_t));
            if (!igcData) {
                ALOGE("IGC storage allocated failed");
                return false;
            }
            mOVInfo.overlay_pp_cfg.igc_cfg.c0_c1_data = igcData;
            mOVInfo.overlay_pp_cfg.igc_cfg.c2_data
                = igcData + MAX_IGC_LUT_ENTRIES;
        }

        memcpy(mParams.params.igc_lut_params.c0,
            data.igcData.c0, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES);
        memcpy(mParams.params.igc_lut_params.c1,
            data.igcData.c1, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES);
        memcpy(mParams.params.igc_lut_params.c2,
            data.igcData.c2, sizeof(uint16_t) * MAX_IGC_LUT_ENTRIES);

        mParams.params.igc_lut_params.ops
            = MDP_PP_OPS_WRITE | MDP_PP_OPS_ENABLE;
        mParams.operation |= PP_OP_IGC;
        needUpdate = true;
    }

    if (data.operation & PP_PARAM_VID_INTFC) {
        mParams.params.conv_params.interface =
            (interface_type) data.video_interface;
        needUpdate = true;
    }

    if (needUpdate) {
        display_pp_compute_params(&mParams, &mOVInfo.overlay_pp_cfg);
    }
#endif
    return true;
}

bool MdpCtrl::validateAndSet(MdpCtrl* mdpCtrlArray[], const int& count,
        const int& fbFd) {
    mdp_overlay* ovArray[count];
    memset(&ovArray, 0, sizeof(ovArray));

    for(int i = 0; i < count; i++) {
        ovArray[i] = &mdpCtrlArray[i]->mOVInfo;
    }

    struct mdp_overlay_list list;
    memset(&list, 0, sizeof(struct mdp_overlay_list));
    list.num_overlays = count;
    list.overlay_list = ovArray;

   int (*fnProgramScale)(struct mdp_overlay_list *) =
        Overlay::getFnProgramScale();
    if(fnProgramScale) {
        fnProgramScale(&list);
    }

    // Error value is based on file errno-base.h
    // 0 - indicates no error.
    int errVal = mdp_wrapper::validateAndSet(fbFd, list);
    if(errVal) {
        /* No dump for failure due to insufficient resource */
        if(errVal != E2BIG) {
            mdp_wrapper::dump("Bad ov dump: ",
                *list.overlay_list[list.processed_overlays]);
        }
        return false;
    }

    return true;
}


//// MdpData ////////////
bool MdpData::init(const int& dpy) {
    int fbnum = Overlay::getFbForDpy(dpy);
    if( fbnum < 0 ) {
        ALOGE("%s: Invalid FB for the display: %d",__FUNCTION__, dpy);
        return false;
    }

    // FD init
    if(!utils::openDev(mFd, fbnum, Res::fbPath, O_RDWR)){
        ALOGE("Ctrl failed to init fbnum=%d", fbnum);
        return false;
    }
    return true;
}

} // overlay
