/* Helpers */
bool configPrimVid(hwc_context_t *ctx, hwc_layer_1_t *layer) {
    overlay::Overlay& ov = *(ctx->mOverlay);
    private_handle_t *hnd = (private_handle_t *)layer->handle;
    ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);

    ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
    if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
    }
    if(layer->blending == HWC_BLENDING_PREMULT) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_BLEND_FG_PREMULT);
    }

    ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
    if (ctx->numHwLayers == 1) {
        isFgFlag = ovutils::IS_FG_SET;
    }

    ovutils::PipeArgs parg(mdpFlags,
            info,
            ovutils::ZORDER_0,
            isFgFlag,
            ovutils::ROT_FLAG_DISABLED);
    ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
    ov.setSource(pargs, ovutils::OV_PIPE0);

    hwc_rect_t sourceCrop = layer->sourceCrop;
    hwc_rect_t displayFrame = layer->displayFrame;

    //Calculate the rect for primary based on whether the supplied position
    //is within or outside bounds.
    const int fbWidth =
            ovutils::FrameBufferInfo::getInstance()->getWidth();
    const int fbHeight =
            ovutils::FrameBufferInfo::getInstance()->getHeight();

    if( displayFrame.left < 0 ||
            displayFrame.top < 0 ||
            displayFrame.right > fbWidth ||
            displayFrame.bottom > fbHeight) {
        calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight);
    }

    // source crop x,y,w,h
    ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
            sourceCrop.right - sourceCrop.left,
            sourceCrop.bottom - sourceCrop.top);
    //Only for Primary
    ov.setCrop(dcrop, ovutils::OV_PIPE0);

    ovutils::eTransform orient =
            static_cast<ovutils::eTransform>(layer->transform);
    ov.setTransform(orient, ovutils::OV_PIPE0);

    // position x,y,w,h
    ovutils::Dim dpos(displayFrame.left,
            displayFrame.top,
            displayFrame.right - displayFrame.left,
            displayFrame.bottom - displayFrame.top);
    ov.setPosition(dpos, ovutils::OV_PIPE0);

    if (!ov.commit(ovutils::OV_PIPE0)) {
        ALOGE("%s: commit fails", __FUNCTION__);
        return false;
    }
    return true;
}
/* Helpers */
bool configPrimVid(hwc_context_t *ctx, hwc_layer_t *layer) {
    overlay::Overlay& ov = *(ctx->mOverlay);
    private_handle_t *hnd = (private_handle_t *)layer->handle;
    ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);

    ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
    if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
    }
    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
    if (metadata->paramType == PP_PARAM_INTERLACED && metadata->paramValue) {
        ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_DEINTERLACE);
    }
    ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
    if (ctx->numHwLayers == 1) {
        isFgFlag = ovutils::IS_FG_SET;
    }

    ovutils::PipeArgs parg(mdpFlags,
            info,
            ovutils::ZORDER_0,
            isFgFlag,
            ovutils::ROT_FLAG_DISABLED);
    ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
    ov.setSource(pargs, ovutils::OV_PIPE0);

    hwc_rect_t sourceCrop = layer->sourceCrop;
    // x,y,w,h
    ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
            sourceCrop.right - sourceCrop.left,
            sourceCrop.bottom - sourceCrop.top);

    ovutils::Dim dpos;
    hwc_rect_t displayFrame = layer->displayFrame;
    dpos.x = displayFrame.left;
    dpos.y = displayFrame.top;
    dpos.w = (displayFrame.right - displayFrame.left);
    dpos.h = (displayFrame.bottom - displayFrame.top);

    //Calculate the rect for primary based on whether the supplied position
    //is within or outside bounds.
    const int fbWidth =
            ovutils::FrameBufferInfo::getInstance()->getWidth();
    const int fbHeight =
            ovutils::FrameBufferInfo::getInstance()->getHeight();

    if( displayFrame.left < 0 ||
            displayFrame.top < 0 ||
            displayFrame.right > fbWidth ||
            displayFrame.bottom > fbHeight) {

        calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight);

        //Update calculated width and height
        dcrop.w = sourceCrop.right - sourceCrop.left;
        dcrop.h = sourceCrop.bottom - sourceCrop.top;

        dpos.x = displayFrame.left;
        dpos.y = displayFrame.top;
        dpos.w = displayFrame.right - displayFrame.left;
        dpos.h = displayFrame.bottom - displayFrame.top;
    }

    //Only for Primary
    ov.setCrop(dcrop, ovutils::OV_PIPE0);

    int transform = layer->transform & FINAL_TRANSFORM_MASK;
    ovutils::eTransform orient =
            static_cast<ovutils::eTransform>(transform);
    ov.setTransform(orient, ovutils::OV_PIPE0);

    ov.setPosition(dpos, ovutils::OV_PIPE0);

    if (!ov.commit(ovutils::OV_PIPE0)) {
        ALOGE("%s: commit fails", __FUNCTION__);
        return false;
    }
    return true;
}
bool VideoOverlay::configure(hwc_context_t *ctx, hwc_layer_t *layer)
{
    if (LIKELY(ctx->mOverlay)) {

        overlay::Overlay& ov = *(ctx->mOverlay);
        // Set overlay state
        ov.setState(sState);

        private_handle_t *hnd = (private_handle_t *)layer->handle;
        ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);

        //TODO change this based on state.
        ovutils::eDest dest = ovutils::OV_PIPE_ALL;

        ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
        if (hnd->flags & private_handle_t::PRIV_FLAGS_SECURE_BUFFER) {
            ovutils::setMdpFlags(mdpFlags,
                                 ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
        }

        ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
        if (ctx->numHwLayers == 1) {
            isFgFlag = ovutils::IS_FG_SET;
        }

        ovutils::PipeArgs parg(mdpFlags,
                               info,
                               ovutils::ZORDER_0,
                               isFgFlag,
                               ovutils::ROT_FLAG_DISABLED);
        ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
        ov.setSource(pargs, dest);

        hwc_rect_t sourceCrop = layer->sourceCrop;
        // x,y,w,h
        ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
                           sourceCrop.right - sourceCrop.left,
                           sourceCrop.bottom - sourceCrop.top);
        //Only for External
        ov.setCrop(dcrop, ovutils::OV_PIPE1);

        // FIXME: Use source orientation for TV when source is portrait
        //Only for External
        ov.setTransform(0, dest);

        ovutils::Dim dpos;
        hwc_rect_t displayFrame = layer->displayFrame;
        dpos.x = displayFrame.left;
        dpos.y = displayFrame.top;
        dpos.w = (displayFrame.right - displayFrame.left);
        dpos.h = (displayFrame.bottom - displayFrame.top);

        //Only for External
        ov.setPosition(dpos, ovutils::OV_PIPE1);

        //Calculate the rect for primary based on whether the supplied position
        //is within or outside bounds.
        const int fbWidth =
            ovutils::FrameBufferInfo::getInstance()->getWidth();
        const int fbHeight =
            ovutils::FrameBufferInfo::getInstance()->getHeight();

        if( displayFrame.left < 0 ||
                displayFrame.top < 0 ||
                displayFrame.right > fbWidth ||
                displayFrame.bottom > fbHeight) {

            calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight);

            //Update calculated width and height
            dcrop.w = sourceCrop.right - sourceCrop.left;
            dcrop.h = sourceCrop.bottom - sourceCrop.top;

            dpos.w = displayFrame.right - displayFrame.left;
            dpos.h = displayFrame.bottom - displayFrame.top;
        }

        //Only for Primary
        ov.setCrop(dcrop, ovutils::OV_PIPE0);

        int transform = layer->transform & FINAL_TRANSFORM_MASK;
        ovutils::eTransform orient =
            static_cast<ovutils::eTransform>(transform);
        ov.setTransform(orient, ovutils::OV_PIPE0);

        ov.setPosition(dpos, ovutils::OV_PIPE0);

        //Both prim and external
        if (!ov.commit(dest)) {
            ALOGE("%s: commit fails", __FUNCTION__);
            return false;
        }

        sIsModeOn = true;
    }
    return sIsModeOn;
}
bool configExtVid(hwc_context_t *ctx, hwc_layer_1_t *layer) {
    overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]);
    private_handle_t *hnd = (private_handle_t *)layer->handle;
    ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);

    ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
    if (isSecureBuffer(hnd)) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
    }

    if(layer->blending == HWC_BLENDING_PREMULT) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_BLEND_FG_PREMULT);
    }

    ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
    if (ctx->listStats[HWC_DISPLAY_EXTERNAL].numAppLayers == 1) {
        isFgFlag = ovutils::IS_FG_SET;
    }

    ovutils::PipeArgs parg(mdpFlags,
            info,
            ovutils::ZORDER_1,
            isFgFlag,
            ovutils::ROT_FLAG_DISABLED);
    ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
    ov.setSource(pargs, ovutils::OV_PIPE1);

    int transform = layer->transform;
    ovutils::eTransform orient =
            static_cast<ovutils::eTransform>(transform);

    hwc_rect_t sourceCrop = layer->sourceCrop;
    hwc_rect_t displayFrame = layer->displayFrame;

    //Calculate the rect for primary based on whether the supplied position
    //is within or outside bounds.
    const int fbWidth = ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].xres;
    const int fbHeight = ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].yres;

    if( displayFrame.left < 0 ||
            displayFrame.top < 0 ||
            displayFrame.right > fbWidth ||
            displayFrame.bottom > fbHeight) {
        calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight,
                transform);
    }

    // x,y,w,h
    ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
            sourceCrop.right - sourceCrop.left,
            sourceCrop.bottom - sourceCrop.top);
    //Only for External
    ov.setCrop(dcrop, ovutils::OV_PIPE1);

    ov.setTransform(orient, ovutils::OV_PIPE1);

    ovutils::Dim dpos(displayFrame.left,
            displayFrame.top,
            (displayFrame.right - displayFrame.left),
            (displayFrame.bottom - displayFrame.top));

    //Only for External
    ov.setPosition(dpos, ovutils::OV_PIPE1);

    if (!ov.commit(ovutils::OV_PIPE1)) {
        ALOGE("%s: commit fails", __FUNCTION__);
        return false;
    }
    return true;
}