/*
 * Copyright (C) 2010 The Android Open Source Project
 * Copyright (C) 2012-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.
 */
#define ATRACE_TAG (ATRACE_TAG_GRAPHICS | ATRACE_TAG_HAL)
#define HWC_UTILS_DEBUG 0
#include <math.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#include <binder/IServiceManager.h>
#include <EGL/egl.h>
#include <cutils/properties.h>
#include <utils/Trace.h>
#include <gralloc_priv.h>
#include <overlay.h>
#include <overlayRotator.h>
#include <overlayWriteback.h>
#include "hwc_utils.h"
#include "hwc_mdpcomp.h"
#include "hwc_fbupdate.h"
#include "hwc_ad.h"
#include "mdp_version.h"
#include "hwc_copybit.h"
#include "hwc_dump_layers.h"
#include "hdmi.h"
#include "hwc_qclient.h"
#include "QService.h"
#include "comptype.h"
#include "hwc_virtual.h"
#include "qd_utils.h"
#include <sys/sysinfo.h>
#include <dlfcn.h>
#include <video/msm_hdmi_modes.h>

using namespace qClient;
using namespace qService;
using namespace android;
using namespace overlay;
using namespace overlay::utils;
namespace ovutils = overlay::utils;

#ifdef QCOM_BSP
#ifdef __cplusplus
extern "C" {
#endif

EGLAPI EGLBoolean eglGpuPerfHintQCOM(EGLDisplay dpy, EGLContext ctx,
                                           EGLint *attrib_list);
#define EGL_GPU_HINT_1        0x32D0
#define EGL_GPU_HINT_2        0x32D1

#define EGL_GPU_LEVEL_0       0x0
#define EGL_GPU_LEVEL_1       0x1
#define EGL_GPU_LEVEL_2       0x2
#define EGL_GPU_LEVEL_3       0x3
#define EGL_GPU_LEVEL_4       0x4
#define EGL_GPU_LEVEL_5       0x5

#ifdef __cplusplus
}
#endif
#endif

#define PROP_DEFAULT_APPBUFFER  "sf.default.app_buffer_count"
#define MAX_RAM_SIZE  512*1024*1024
#define qHD_WIDTH 540


namespace qhwc {

// Std refresh rates for digital videos- 24p, 30p, 48p and 60p
uint32_t stdRefreshRates[] = { 30, 24, 48, 60 };

bool isValidResolution(hwc_context_t *ctx, uint32_t xres, uint32_t yres)
{
    return !((xres > qdutils::MDPVersion::getInstance().getMaxPipeWidth() &&
                !isDisplaySplit(ctx, HWC_DISPLAY_PRIMARY)) ||
            (xres < MIN_DISPLAY_XRES || yres < MIN_DISPLAY_YRES));
}

void changeResolution(hwc_context_t *ctx, int xres_orig, int yres_orig,
                      int width, int height) {
    //Store original display resolution.
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_orig;
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_orig;
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = false;
    char property[PROPERTY_VALUE_MAX] = {'\0'};
    char *yptr = NULL;
    if (property_get("debug.hwc.fbsize", property, NULL) > 0) {
        yptr = strcasestr(property,"x");
        if(yptr) {
            int xres_new = atoi(property);
            int yres_new = atoi(yptr + 1);
            if (isValidResolution(ctx,xres_new,yres_new) &&
                xres_new != xres_orig && yres_new != yres_orig) {
                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_new;
                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_new;
                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = true;

                //Caluculate DPI according to changed resolution.
                float xdpi = ((float)xres_new * 25.4f) / (float)width;
                float ydpi = ((float)yres_new * 25.4f) / (float)height;
                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi;
                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
            }
        }
    }
}

// Initialize hdmi display attributes based on
// hdmi display class state
void updateDisplayInfo(hwc_context_t* ctx, int dpy) {
    ctx->dpyAttr[dpy].fd = ctx->mHDMIDisplay->getFd();
    ctx->dpyAttr[dpy].xres = ctx->mHDMIDisplay->getWidth();
    ctx->dpyAttr[dpy].yres = ctx->mHDMIDisplay->getHeight();
    ctx->dpyAttr[dpy].mMDPScalingMode = ctx->mHDMIDisplay->getMDPScalingMode();
    ctx->dpyAttr[dpy].vsync_period = ctx->mHDMIDisplay->getVsyncPeriod();
    //FIXME: for now assume HDMI as secure
    //Will need to read the HDCP status from the driver
    //and update this accordingly
    ctx->dpyAttr[dpy].secure = true;
    ctx->mViewFrame[dpy].left = 0;
    ctx->mViewFrame[dpy].top = 0;
    ctx->mViewFrame[dpy].right = ctx->dpyAttr[dpy].xres;
    ctx->mViewFrame[dpy].bottom = ctx->dpyAttr[dpy].yres;
}

// Reset hdmi display attributes and list stats structures
void resetDisplayInfo(hwc_context_t* ctx, int dpy) {
    memset(&(ctx->dpyAttr[dpy]), 0, sizeof(ctx->dpyAttr[dpy]));
    memset(&(ctx->listStats[dpy]), 0, sizeof(ctx->listStats[dpy]));
    // We reset the fd to -1 here but External display class is responsible
    // for it when the display is disconnected. This is handled as part of
    // EXTERNAL_OFFLINE event.
    ctx->dpyAttr[dpy].fd = -1;
}

// Initialize composition resources
void initCompositionResources(hwc_context_t* ctx, int dpy) {
    ctx->mFBUpdate[dpy] = IFBUpdate::getObject(ctx, dpy);
    ctx->mMDPComp[dpy] = MDPComp::getObject(ctx, dpy);
}

void destroyCompositionResources(hwc_context_t* ctx, int dpy) {
    if(ctx->mFBUpdate[dpy]) {
        delete ctx->mFBUpdate[dpy];
        ctx->mFBUpdate[dpy] = NULL;
    }
    if(ctx->mMDPComp[dpy]) {
        delete ctx->mMDPComp[dpy];
        ctx->mMDPComp[dpy] = NULL;
    }
}

static int openFramebufferDevice(hwc_context_t *ctx)
{
    struct fb_fix_screeninfo finfo;
    struct fb_var_screeninfo info;

    int fb_fd = openFb(HWC_DISPLAY_PRIMARY);
    if(fb_fd < 0) {
        ALOGE("%s: Error Opening FB : %s", __FUNCTION__, strerror(errno));
        return -errno;
    }

    if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &info) == -1) {
        ALOGE("%s:Error in ioctl FBIOGET_VSCREENINFO: %s", __FUNCTION__,
                                                       strerror(errno));
        close(fb_fd);
        return -errno;
    }

    if (int(info.width) <= 0 || int(info.height) <= 0) {
        // the driver doesn't return that information
        // default to 160 dpi
        info.width  = (int)(((float)info.xres * 25.4f)/160.0f + 0.5f);
        info.height = (int)(((float)info.yres * 25.4f)/160.0f + 0.5f);
    }

    float xdpi = ((float)info.xres * 25.4f) / (float)info.width;
    float ydpi = ((float)info.yres * 25.4f) / (float)info.height;

#ifdef MSMFB_METADATA_GET
    struct msmfb_metadata metadata;
    memset(&metadata, 0 , sizeof(metadata));
    metadata.op = metadata_op_frame_rate;

    if (ioctl(fb_fd, MSMFB_METADATA_GET, &metadata) == -1) {
        ALOGE("%s:Error retrieving panel frame rate: %s", __FUNCTION__,
                                                      strerror(errno));
        close(fb_fd);
        return -errno;
    }

    float fps  = (float)metadata.data.panel_frame_rate;
#else
    //XXX: Remove reserved field usage on all baselines
    //The reserved[3] field is used to store FPS by the driver.
    float fps  = info.reserved[3] & 0xFF;
#endif

    if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
        ALOGE("%s:Error in ioctl FBIOGET_FSCREENINFO: %s", __FUNCTION__,
                                                       strerror(errno));
        close(fb_fd);
        return -errno;
    }

    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = fb_fd;
    //xres, yres may not be 32 aligned
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride = finfo.line_length /(info.xres/8);
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = info.xres;
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = info.yres;
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = xdpi;
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].ydpi = ydpi;
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].refreshRate = (uint32_t)fps;
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].dynRefreshRate = (uint32_t)fps;
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].secure = true;
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period =
            (uint32_t)(1000000000l / fps);

    //To change resolution of primary display
    changeResolution(ctx, info.xres, info.yres, info.width, info.height);

    //Unblank primary on first boot
    if(ioctl(fb_fd, FBIOBLANK,FB_BLANK_UNBLANK) < 0) {
        ALOGE("%s: Failed to unblank display", __FUNCTION__);
        return -errno;
    }
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].isActive = true;

    return 0;
}

static void changeDefaultAppBufferCount() {
    struct sysinfo info;
    unsigned long int ramSize = 0;
    if (!sysinfo(&info)) {
           ramSize = info.totalram ;
    }
    int fb_fd = -1;
    struct fb_var_screeninfo sInfo ={0};
    fb_fd = open("/dev/graphics/fb0", O_RDONLY);
    if (fb_fd >=0) {
        ioctl(fb_fd, FBIOGET_VSCREENINFO, &sInfo);
        close(fb_fd);
    }
    if ((ramSize && ramSize < MAX_RAM_SIZE) &&
         (sInfo.xres &&  sInfo.xres <= qHD_WIDTH )) {
                  property_set(PROP_DEFAULT_APPBUFFER, "2");
    }
}

void initContext(hwc_context_t *ctx)
{
    overlay::Overlay::initOverlay();
    ctx->mHDMIDisplay = new HDMIDisplay();
    uint32_t priW = 0, priH = 0;
    // 1. HDMI as Primary
    //    -If HDMI cable is connected, read display configs from edid data
    //    -If HDMI cable is not connected then use default data in vscreeninfo
    // 2. HDMI as External
    //    -Initialize HDMI class for use with external display
    //    -Use vscreeninfo to populate display configs
    if(ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
        int connected = ctx->mHDMIDisplay->getConnectedState();
        if(connected == 1) {
            ctx->mHDMIDisplay->configure();
            updateDisplayInfo(ctx, HWC_DISPLAY_PRIMARY);
            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
        } else {
            openFramebufferDevice(ctx);
            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = false;
        }
    } else {
        openFramebufferDevice(ctx);
        ctx->dpyAttr[HWC_DISPLAY_PRIMARY].connected = true;
        // Send the primary resolution to the hdmi display class
        // to be used for MDP scaling functionality
        priW = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
        priH = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
        ctx->mHDMIDisplay->setPrimaryAttributes(priW, priH);
    }

    char value[PROPERTY_VALUE_MAX];
    ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
    ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
    ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
    ctx->mOverlay = overlay::Overlay::getInstance();
    ctx->mRotMgr = RotMgr::getInstance();
    ctx->mBWCEnabled = qdutils::MDPVersion::getInstance().supportsBWC();

    //default_app_buffer for ferrum
    if (ctx->mMDP.version ==  qdutils::MDP_V3_0_5) {
       changeDefaultAppBufferCount();
    }
    // Initialize composition objects for the primary display
    initCompositionResources(ctx, HWC_DISPLAY_PRIMARY);

    // Check if the target supports copybit compostion (dyn/mdp) to
    // decide if we need to open the copybit module.
    int compositionType =
        qdutils::QCCompositionType::getInstance().getCompositionType();

    // Only MDP copybit is used
    if ((compositionType & (qdutils::COMPOSITION_TYPE_DYN |
            qdutils::COMPOSITION_TYPE_MDP)) &&
            ((qdutils::MDPVersion::getInstance().getMDPVersion() ==
            qdutils::MDP_V3_0_4) ||
            (qdutils::MDPVersion::getInstance().getMDPVersion() ==
            qdutils::MDP_V3_0_5))) {
        ctx->mCopyBit[HWC_DISPLAY_PRIMARY] = new CopyBit(ctx,
                                                         HWC_DISPLAY_PRIMARY);
    }

    ctx->mHWCVirtual = new HWCVirtualVDS();
    ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive = false;
    ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected = false;
    ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isActive = false;
    ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected = false;
    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].mMDPScalingMode= false;
    ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].mMDPScalingMode = false;
    ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].mMDPScalingMode = false;

    //Initialize the primary display viewFrame info
    ctx->mViewFrame[HWC_DISPLAY_PRIMARY].left = 0;
    ctx->mViewFrame[HWC_DISPLAY_PRIMARY].top = 0;
    ctx->mViewFrame[HWC_DISPLAY_PRIMARY].right =
        (int)ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
    ctx->mViewFrame[HWC_DISPLAY_PRIMARY].bottom =
         (int)ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;

    for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
        ctx->mHwcDebug[i] = new HwcDebug(i);
        ctx->mLayerRotMap[i] = new LayerRotMap();
        ctx->mAnimationState[i] = ANIMATION_STOPPED;
        ctx->dpyAttr[i].mActionSafePresent = false;
        ctx->dpyAttr[i].mAsWidthRatio = 0;
        ctx->dpyAttr[i].mAsHeightRatio = 0;
        ctx->dpyAttr[i].s3dMode = HDMI_S3D_NONE;
        ctx->dpyAttr[i].s3dModeForced = false;
    }

    //Make sure that the 3D mode is unset at bootup
    //This makes sure that the state is accurate on framework reboots
    ctx->mHDMIDisplay->configure3D(HDMI_S3D_NONE);

    for (uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
        ctx->mPrevHwLayerCount[i] = 0;
    }

    MDPComp::init(ctx);
    ctx->mAD = new AssertiveDisplay(ctx);

    ctx->vstate.enable = false;
    ctx->vstate.fakevsync = false;
    ctx->mExtOrientation = 0;
    ctx->numActiveDisplays = 1;

    //Right now hwc starts the service but anybody could do it, or it could be
    //independent process as well.
    QService::init();
    sp<IQClient> client = new QClient(ctx);
    android::sp<qService::IQService> qservice_sp = interface_cast<IQService>(
            defaultServiceManager()->getService(
            String16("display.qservice")));
    if (qservice_sp.get()) {
      qservice_sp->connect(client);
    } else {
      ALOGE("%s: Failed to acquire service pointer", __FUNCTION__);
      return ;
    }

    // Initialize device orientation to its default orientation
    ctx->deviceOrientation = 0;
    ctx->mBufferMirrorMode = false;

    property_get("sys.hwc.windowbox_aspect_ratio_tolerance", value, "0");
    ctx->mAspectRatioToleranceLevel = (((float)atoi(value)) / 100.0f);

    ctx->enableABC = false;
    property_get("debug.sf.hwc.canUseABC", value, "0");
    ctx->enableABC  = atoi(value) ? true : false;

    // Initializing boot anim completed check to false
    ctx->mBootAnimCompleted = false;

    // Initialize gpu perfomance hint related parameters
    property_get("sys.hwc.gpu_perf_mode", value, "0");
#ifdef QCOM_BSP
    ctx->mGPUHintInfo.mGpuPerfModeEnable = atoi(value)? true : false;

    ctx->mGPUHintInfo.mEGLDisplay = NULL;
    ctx->mGPUHintInfo.mEGLContext = NULL;
    ctx->mGPUHintInfo.mCompositionState = COMPOSITION_STATE_MDP;
    ctx->mGPUHintInfo.mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
#endif
    // Read the system property to determine if windowboxing feature is enabled.
    ctx->mWindowboxFeature = false;
    if(property_get("sys.hwc.windowbox_feature", value, "false")
            && !strcmp(value, "true")) {
        ctx->mWindowboxFeature = true;
    }

    ctx->mUseMetaDataRefreshRate = true;
    if(property_get("persist.metadata_dynfps.disable", value, "false")
            && !strcmp(value, "true")) {
        ctx->mUseMetaDataRefreshRate = false;
    }

    memset(&(ctx->mPtorInfo), 0, sizeof(ctx->mPtorInfo));
    ctx->mHPDEnabled = false;
    ALOGI("Initializing Qualcomm Hardware Composer");
    ALOGI("MDP version: %d", ctx->mMDP.version);
}

void closeContext(hwc_context_t *ctx)
{
    if(ctx->mOverlay) {
        delete ctx->mOverlay;
        ctx->mOverlay = NULL;
    }

    if(ctx->mRotMgr) {
        delete ctx->mRotMgr;
        ctx->mRotMgr = NULL;
    }

    for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
        if(ctx->mCopyBit[i]) {
            delete ctx->mCopyBit[i];
            ctx->mCopyBit[i] = NULL;
        }
    }

    if(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd) {
        close(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd);
        ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd = -1;
    }

    if(ctx->mHDMIDisplay) {
        delete ctx->mHDMIDisplay;
        ctx->mHDMIDisplay = NULL;
    }

    for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
        destroyCompositionResources(ctx, i);

        if(ctx->mHwcDebug[i]) {
            delete ctx->mHwcDebug[i];
            ctx->mHwcDebug[i] = NULL;
        }
        if(ctx->mLayerRotMap[i]) {
            delete ctx->mLayerRotMap[i];
            ctx->mLayerRotMap[i] = NULL;
        }
    }
    if(ctx->mHWCVirtual) {
        delete ctx->mHWCVirtual;
        ctx->mHWCVirtual = NULL;
    }
    if(ctx->mAD) {
        delete ctx->mAD;
        ctx->mAD = NULL;
    }


}

//Helper to roundoff the refreshrates
uint32_t roundOff(uint32_t refreshRate) {
    int count =  (int) (sizeof(stdRefreshRates)/sizeof(stdRefreshRates[0]));
    uint32_t rate = refreshRate;
    for(int i=0; i< count; i++) {
        if(abs(stdRefreshRates[i] - refreshRate) < 2) {
            // Most likely used for video, the fps can fluctuate
            // Ex: b/w 29 and 30 for 30 fps clip
            rate = stdRefreshRates[i];
            break;
        }
    }
    return rate;
}

//Helper func to set the dyn fps
void setRefreshRate(hwc_context_t* ctx, int dpy, uint32_t refreshRate) {
    //Update only if different
    if(!ctx || refreshRate == ctx->dpyAttr[dpy].dynRefreshRate)
        return;
    const int fbNum = Overlay::getFbForDpy(dpy);
    char sysfsPath[qdutils::MAX_SYSFS_FILE_PATH];
    snprintf (sysfsPath, sizeof(sysfsPath),
            "/sys/devices/virtual/graphics/fb%d/dynamic_fps", fbNum);

    int fd = open(sysfsPath, O_WRONLY);
    if(fd >= 0) {
        char str[64];
        snprintf(str, sizeof(str), "%d", refreshRate);
        ssize_t ret = write(fd, str, strlen(str));
        if(ret < 0) {
            ALOGE("%s: Failed to write %d with error %s",
                    __FUNCTION__, refreshRate, strerror(errno));
        } else {
            ctx->dpyAttr[dpy].dynRefreshRate = refreshRate;
            ALOGD_IF(HWC_UTILS_DEBUG, "%s: Wrote %d to dynamic_fps",
                     __FUNCTION__, refreshRate);
        }
        close(fd);
    } else {
        ALOGE("%s: Failed to open %s with error %s", __FUNCTION__, sysfsPath,
              strerror(errno));
    }
}

void dumpsys_log(android::String8& buf, const char* fmt, ...)
{
    va_list varargs;
    va_start(varargs, fmt);
    buf.appendFormatV(fmt, varargs);
    va_end(varargs);
}

int getExtOrientation(hwc_context_t* ctx) {
    int extOrient = ctx->mExtOrientation;
    if(ctx->mBufferMirrorMode)
        extOrient = getMirrorModeOrientation(ctx);
    return extOrient;
}

/* Calculates the destination position based on the action safe rectangle */
void getActionSafePosition(hwc_context_t *ctx, int dpy, hwc_rect_t& rect) {
    // Position
    int x = rect.left, y = rect.top;
    int w = rect.right - rect.left;
    int h = rect.bottom - rect.top;

    if(!ctx->dpyAttr[dpy].mActionSafePresent)
        return;
   // Read action safe properties
    int asWidthRatio = ctx->dpyAttr[dpy].mAsWidthRatio;
    int asHeightRatio = ctx->dpyAttr[dpy].mAsHeightRatio;

    float wRatio = 1.0;
    float hRatio = 1.0;
    float xRatio = 1.0;
    float yRatio = 1.0;

    uint32_t fbWidth = ctx->dpyAttr[dpy].xres;
    uint32_t fbHeight = ctx->dpyAttr[dpy].yres;
    if(ctx->dpyAttr[dpy].mMDPScalingMode) {
        // if MDP scaling mode is enabled for external, need to query
        // the actual width and height, as that is the physical w & h
         ctx->mHDMIDisplay->getAttributes(fbWidth, fbHeight);
    }


    // Since external is rotated 90, need to swap width/height
    int extOrient = getExtOrientation(ctx);

    if(extOrient & HWC_TRANSFORM_ROT_90)
        swap(fbWidth, fbHeight);

    float asX = 0;
    float asY = 0;
    float asW = (float)fbWidth;
    float asH = (float)fbHeight;

    // based on the action safe ratio, get the Action safe rectangle
    asW = ((float)fbWidth * (1.0f -  (float)asWidthRatio / 100.0f));
    asH = ((float)fbHeight * (1.0f -  (float)asHeightRatio / 100.0f));
    asX = ((float)fbWidth - asW) / 2;
    asY = ((float)fbHeight - asH) / 2;

    // calculate the position ratio
    xRatio = (float)x/(float)fbWidth;
    yRatio = (float)y/(float)fbHeight;
    wRatio = (float)w/(float)fbWidth;
    hRatio = (float)h/(float)fbHeight;

    //Calculate the position...
    x = int((xRatio * asW) + asX);
    y = int((yRatio * asH) + asY);
    w = int(wRatio * asW);
    h = int(hRatio * asH);

    // Convert it back to hwc_rect_t
    rect.left = x;
    rect.top = y;
    rect.right = w + rect.left;
    rect.bottom = h + rect.top;

    return;
}

// This function gets the destination position for Seconday display
// based on the position and aspect ratio with orientation
void getAspectRatioPosition(hwc_context_t* ctx, int dpy, int extOrientation,
                            hwc_rect_t& inRect, hwc_rect_t& outRect) {
    // Physical display resolution
    float fbWidth  = (float)ctx->dpyAttr[dpy].xres;
    float fbHeight = (float)ctx->dpyAttr[dpy].yres;
    //display position(x,y,w,h) in correct aspectratio after rotation
    int xPos = 0;
    int yPos = 0;
    float width = fbWidth;
    float height = fbHeight;
    // Width/Height used for calculation, after rotation
    float actualWidth = fbWidth;
    float actualHeight = fbHeight;

    float wRatio = 1.0;
    float hRatio = 1.0;
    float xRatio = 1.0;
    float yRatio = 1.0;
    hwc_rect_t rect = {0, 0, (int)fbWidth, (int)fbHeight};

    Dim inPos(inRect.left, inRect.top, inRect.right - inRect.left,
                inRect.bottom - inRect.top);
    Dim outPos(outRect.left, outRect.top, outRect.right - outRect.left,
                outRect.bottom - outRect.top);

    Whf whf((uint32_t)fbWidth, (uint32_t)fbHeight, 0);
    eTransform extorient = static_cast<eTransform>(extOrientation);
    // To calculate the destination co-ordinates in the new orientation
    preRotateSource(extorient, whf, inPos);

    if(extOrientation & HAL_TRANSFORM_ROT_90) {
        // Swap width/height for input position
        swapWidthHeight(actualWidth, actualHeight);
        qdutils::getAspectRatioPosition((int)fbWidth, (int)fbHeight,
                                (int)actualWidth, (int)actualHeight, rect);
        xPos = rect.left;
        yPos = rect.top;
        width = float(rect.right - rect.left);
        height = float(rect.bottom - rect.top);
    }
    xRatio = (float)((float)inPos.x/actualWidth);
    yRatio = (float)((float)inPos.y/actualHeight);
    wRatio = (float)((float)inPos.w/actualWidth);
    hRatio = (float)((float)inPos.h/actualHeight);

    //Calculate the pos9ition...
    outPos.x = uint32_t((xRatio * width) + (float)xPos);
    outPos.y = uint32_t((yRatio * height) + (float)yPos);
    outPos.w = uint32_t(wRatio * width);
    outPos.h = uint32_t(hRatio * height);
    ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio Position: x = %d,"
                 "y = %d w = %d h = %d", __FUNCTION__, outPos.x, outPos.y,
                 outPos.w, outPos.h);

    // For sidesync, the dest fb will be in portrait orientation, and the crop
    // will be updated to avoid the black side bands, and it will be upscaled
    // to fit the dest RB, so recalculate
    // the position based on the new width and height
    if ((extOrientation & HWC_TRANSFORM_ROT_90) &&
                        isOrientationPortrait(ctx)) {
        hwc_rect_t r = {0, 0, 0, 0};
        //Calculate the position
        xRatio = (float)(outPos.x - xPos)/width;
        // GetaspectRatio -- tricky to get the correct aspect ratio
        // But we need to do this.
        qdutils::getAspectRatioPosition((int)width, (int)height,
                               (int)width,(int)height, r);
        xPos = r.left;
        yPos = r.top;
        float tempHeight = float(r.bottom - r.top);
        yRatio = (float)yPos/height;
        wRatio = (float)outPos.w/width;
        hRatio = tempHeight/height;

        //Map the coordinates back to Framebuffer domain
        outPos.x = uint32_t(xRatio * fbWidth);
        outPos.y = uint32_t(yRatio * fbHeight);
        outPos.w = uint32_t(wRatio * fbWidth);
        outPos.h = uint32_t(hRatio * fbHeight);

        ALOGD_IF(HWC_UTILS_DEBUG, "%s: Calculated AspectRatio for device in"
                 "portrait: x = %d,y = %d w = %d h = %d", __FUNCTION__,
                 outPos.x, outPos.y,
                 outPos.w, outPos.h);
    }
    if(ctx->dpyAttr[dpy].mMDPScalingMode) {
        uint32_t extW = 0, extH = 0;
        if(dpy == HWC_DISPLAY_EXTERNAL) {
            ctx->mHDMIDisplay->getAttributes(extW, extH);
        } else if(dpy == HWC_DISPLAY_VIRTUAL) {
            extW = ctx->mHWCVirtual->getScalingWidth();
            extH = ctx->mHWCVirtual->getScalingHeight();
        }
        ALOGD_IF(HWC_UTILS_DEBUG, "%s: Scaling mode extW=%d extH=%d",
                __FUNCTION__, extW, extH);

        fbWidth  = (float)ctx->dpyAttr[dpy].xres;
        fbHeight = (float)ctx->dpyAttr[dpy].yres;
        //Calculate the position...
        xRatio = (float)outPos.x/fbWidth;
        yRatio = (float)outPos.y/fbHeight;
        wRatio = (float)outPos.w/fbWidth;
        hRatio = (float)outPos.h/fbHeight;

        outPos.x = uint32_t(xRatio * (float)extW);
        outPos.y = uint32_t(yRatio * (float)extH);
        outPos.w = uint32_t(wRatio * (float)extW);
        outPos.h = uint32_t(hRatio * (float)extH);
    }
    // Convert Dim to hwc_rect_t
    outRect.left = outPos.x;
    outRect.top = outPos.y;
    outRect.right = outPos.x + outPos.w;
    outRect.bottom = outPos.y + outPos.h;

    return;
}

bool isPrimaryPortrait(hwc_context_t *ctx) {
    int fbWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
    int fbHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
    if(fbWidth < fbHeight) {
        return true;
    }
    return false;
}

bool isOrientationPortrait(hwc_context_t *ctx) {
    if(isPrimaryPortrait(ctx)) {
        return !(ctx->deviceOrientation & 0x1);
    }
    return (ctx->deviceOrientation & 0x1);
}

void calcExtDisplayPosition(hwc_context_t *ctx,
                               private_handle_t *hnd,
                               int dpy,
                               hwc_rect_t& sourceCrop,
                               hwc_rect_t& displayFrame,
                               int& transform,
                               ovutils::eTransform& orient) {
    // Swap width and height when there is a 90deg transform
    int extOrient = getExtOrientation(ctx);
    if(dpy && ctx->mOverlay->isUIScalingOnExternalSupported()) {
        if(!isYuvBuffer(hnd)) {
            if(extOrient & HWC_TRANSFORM_ROT_90) {
                int dstWidth = ctx->dpyAttr[dpy].xres;
                int dstHeight = ctx->dpyAttr[dpy].yres;;
                int srcWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
                int srcHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
                if(!isPrimaryPortrait(ctx)) {
                    swap(srcWidth, srcHeight);
                }                    // Get Aspect Ratio for external
                qdutils::getAspectRatioPosition(dstWidth, dstHeight, srcWidth,
                                    srcHeight, displayFrame);
                // Crop - this is needed, because for sidesync, the dest fb will
                // be in portrait orientation, so update the crop to not show the
                // black side bands.
                if (isOrientationPortrait(ctx)) {
                    sourceCrop = displayFrame;
                    displayFrame.left = 0;
                    displayFrame.top = 0;
                    displayFrame.right = dstWidth;
                    displayFrame.bottom = dstHeight;
                }
            }
            if(ctx->dpyAttr[dpy].mMDPScalingMode) {
                uint32_t extW = 0, extH = 0;
                // if MDP scaling mode is enabled, map the co-ordinates to new
                // domain(downscaled)
                float fbWidth  = (float)ctx->dpyAttr[dpy].xres;
                float fbHeight = (float)ctx->dpyAttr[dpy].yres;
                // query MDP configured attributes
                if(dpy == HWC_DISPLAY_EXTERNAL) {
                    ctx->mHDMIDisplay->getAttributes(extW, extH);
                } else if(dpy == HWC_DISPLAY_VIRTUAL) {
                    extW = ctx->mHWCVirtual->getScalingWidth();
                    extH = ctx->mHWCVirtual->getScalingHeight();
                }
                ALOGD_IF(HWC_UTILS_DEBUG, "%s: Scaling mode extW=%d extH=%d",
                        __FUNCTION__, extW, extH);

                //Calculate the ratio...
                float wRatio = ((float)extW)/fbWidth;
                float hRatio = ((float)extH)/fbHeight;

                //convert Dim to hwc_rect_t
                displayFrame.left = int(wRatio*(float)displayFrame.left);
                displayFrame.top = int(hRatio*(float)displayFrame.top);
                displayFrame.right = int(wRatio*(float)displayFrame.right);
                displayFrame.bottom = int(hRatio*(float)displayFrame.bottom);
                ALOGD_IF(DEBUG_MDPDOWNSCALE, "Calculated external display frame"
                         " for MDPDownscale feature [%d %d %d %d]",
                         displayFrame.left, displayFrame.top,
                         displayFrame.right, displayFrame.bottom);
            }
        }else {
            if(extOrient || ctx->dpyAttr[dpy].mMDPScalingMode) {
                getAspectRatioPosition(ctx, dpy, extOrient,
                                       displayFrame, displayFrame);
            }
        }
        // If there is a external orientation set, use that
        if(extOrient) {
            transform = extOrient;
            orient = static_cast<ovutils::eTransform >(extOrient);
        }
        // Calculate the actionsafe dimensions for External(dpy = 1 or 2)
        getActionSafePosition(ctx, dpy, displayFrame);
    }
}

/* Returns the orientation which needs to be set on External for
 *  SideSync/Buffer Mirrormode
 */
int getMirrorModeOrientation(hwc_context_t *ctx) {
    int extOrientation = 0;
    int deviceOrientation = ctx->deviceOrientation;
    if(!isPrimaryPortrait(ctx))
        deviceOrientation = (deviceOrientation + 1) % 4;
     if (deviceOrientation == 0)
         extOrientation = HWC_TRANSFORM_ROT_270;
     else if (deviceOrientation == 1)//90
         extOrientation = 0;
     else if (deviceOrientation == 2)//180
         extOrientation = HWC_TRANSFORM_ROT_90;
     else if (deviceOrientation == 3)//270
         extOrientation = HWC_TRANSFORM_FLIP_V | HWC_TRANSFORM_FLIP_H;

    return extOrientation;
}

/* Get External State names */
const char* getExternalDisplayState(uint32_t external_state) {
    static const char* externalStates[EXTERNAL_MAXSTATES] = {0};
    externalStates[EXTERNAL_OFFLINE] = STR(EXTERNAL_OFFLINE);
    externalStates[EXTERNAL_ONLINE]  = STR(EXTERNAL_ONLINE);
    externalStates[EXTERNAL_PAUSE]   = STR(EXTERNAL_PAUSE);
    externalStates[EXTERNAL_RESUME]  = STR(EXTERNAL_RESUME);

    if(external_state >= EXTERNAL_MAXSTATES) {
        return "EXTERNAL_INVALID";
    }

    return externalStates[external_state];
}

bool isDownscaleRequired(hwc_layer_1_t const* layer) {
    hwc_rect_t displayFrame  = layer->displayFrame;
    hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
    int dst_w, dst_h, src_w, src_h;
    dst_w = displayFrame.right - displayFrame.left;
    dst_h = displayFrame.bottom - displayFrame.top;
    src_w = sourceCrop.right - sourceCrop.left;
    src_h = sourceCrop.bottom - sourceCrop.top;

    if(((src_w > dst_w) || (src_h > dst_h)))
        return true;

    return false;
}
bool needsScaling(hwc_layer_1_t const* layer) {
    int dst_w, dst_h, src_w, src_h;
    hwc_rect_t displayFrame  = layer->displayFrame;
    hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);

    dst_w = displayFrame.right - displayFrame.left;
    dst_h = displayFrame.bottom - displayFrame.top;
    src_w = sourceCrop.right - sourceCrop.left;
    src_h = sourceCrop.bottom - sourceCrop.top;

    if(layer->transform & HWC_TRANSFORM_ROT_90)
        swap(src_w, src_h);

    if(((src_w != dst_w) || (src_h != dst_h)))
        return true;

    return false;
}

// Checks if layer needs scaling with split
bool needsScalingWithSplit(hwc_context_t* ctx, hwc_layer_1_t const* layer,
        const int& dpy) {

    int src_width_l, src_height_l;
    int src_width_r, src_height_r;
    int dst_width_l, dst_height_l;
    int dst_width_r, dst_height_r;
    int hw_w = ctx->dpyAttr[dpy].xres;
    int hw_h = ctx->dpyAttr[dpy].yres;
    hwc_rect_t cropL, dstL, cropR, dstR;
    const int lSplit = getLeftSplit(ctx, dpy);
    hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
    hwc_rect_t displayFrame  = layer->displayFrame;
    private_handle_t *hnd = (private_handle_t *)layer->handle;

    cropL = sourceCrop;
    dstL = displayFrame;
    hwc_rect_t scissorL = { 0, 0, lSplit, hw_h };
    scissorL = getIntersection(ctx->mViewFrame[dpy], scissorL);
    qhwc::calculate_crop_rects(cropL, dstL, scissorL, 0);

    cropR = sourceCrop;
    dstR = displayFrame;
    hwc_rect_t scissorR = { lSplit, 0, hw_w, hw_h };
    scissorR = getIntersection(ctx->mViewFrame[dpy], scissorR);
    qhwc::calculate_crop_rects(cropR, dstR, scissorR, 0);

    // Sanitize Crop to stitch
    sanitizeSourceCrop(cropL, cropR, hnd);

    // Calculate the left dst
    dst_width_l = dstL.right - dstL.left;
    dst_height_l = dstL.bottom - dstL.top;
    src_width_l = cropL.right - cropL.left;
    src_height_l = cropL.bottom - cropL.top;

    // check if there is any scaling on the left
    if(((src_width_l != dst_width_l) || (src_height_l != dst_height_l)))
        return true;

    // Calculate the right dst
    dst_width_r = dstR.right - dstR.left;
    dst_height_r = dstR.bottom - dstR.top;
    src_width_r = cropR.right - cropR.left;
    src_height_r = cropR.bottom - cropR.top;

    // check if there is any scaling on the right
    if(((src_width_r != dst_width_r) || (src_height_r != dst_height_r)))
        return true;

    return false;
}

bool isAlphaScaled(hwc_layer_1_t const* layer) {
    if(needsScaling(layer) && isAlphaPresent(layer)) {
        return true;
    }
    return false;
}

bool isAlphaPresent(hwc_layer_1_t const* layer) {
    private_handle_t *hnd = (private_handle_t *)layer->handle;
    if(hnd) {
        int format = hnd->format;
        switch(format) {
        case HAL_PIXEL_FORMAT_RGBA_8888:
        case HAL_PIXEL_FORMAT_BGRA_8888:
            // In any more formats with Alpha go here..
            return true;
        default : return false;
        }
    }
    return false;
}

static void trimLayer(hwc_context_t *ctx, const int& dpy, const int& transform,
        hwc_rect_t& crop, hwc_rect_t& dst) {
    int hw_w = ctx->dpyAttr[dpy].xres;
    int hw_h = ctx->dpyAttr[dpy].yres;
    if(dst.left < 0 || dst.top < 0 ||
            dst.right > hw_w || dst.bottom > hw_h) {
        hwc_rect_t scissor = {0, 0, hw_w, hw_h };
        scissor = getIntersection(ctx->mViewFrame[dpy], scissor);
        qhwc::calculate_crop_rects(crop, dst, scissor, transform);
    }
}

static void trimList(hwc_context_t *ctx, hwc_display_contents_1_t *list,
        const int& dpy) {
    for(uint32_t i = 0; i < list->numHwLayers - 1; i++) {
        hwc_layer_1_t *layer = &list->hwLayers[i];
        hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
        int transform = (list->hwLayers[i].flags & HWC_COLOR_FILL) ? 0 :
                list->hwLayers[i].transform;
        trimLayer(ctx, dpy,
                transform,
                (hwc_rect_t&)crop,
                (hwc_rect_t&)list->hwLayers[i].displayFrame);
        layer->sourceCropf.left = (float)crop.left;
        layer->sourceCropf.right = (float)crop.right;
        layer->sourceCropf.top = (float)crop.top;
        layer->sourceCropf.bottom = (float)crop.bottom;
    }
}

void setListStats(hwc_context_t *ctx,
        hwc_display_contents_1_t *list, int dpy) {
    const int prevYuvCount = ctx->listStats[dpy].yuvCount;
    memset(&ctx->listStats[dpy], 0, sizeof(ListStats));
    ctx->listStats[dpy].numAppLayers = (int)list->numHwLayers - 1;
    ctx->listStats[dpy].fbLayerIndex = (int)list->numHwLayers - 1;
    ctx->listStats[dpy].skipCount = 0;
    ctx->listStats[dpy].preMultipliedAlpha = false;
    ctx->listStats[dpy].isSecurePresent = false;
    ctx->listStats[dpy].yuvCount = 0;
    char property[PROPERTY_VALUE_MAX];
    ctx->listStats[dpy].isDisplayAnimating = false;
    ctx->listStats[dpy].secureUI = false;
    ctx->listStats[dpy].yuv4k2kCount = 0;
    ctx->dpyAttr[dpy].mActionSafePresent = isActionSafePresent(ctx, dpy);
    ctx->listStats[dpy].renderBufIndexforABC = -1;
    ctx->listStats[dpy].secureRGBCount = 0;
    ctx->listStats[dpy].refreshRateRequest = ctx->dpyAttr[dpy].refreshRate;
    uint32_t refreshRate = 0;
    qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
    int s3dFormat = HAL_NO_3D;
    int s3dLayerCount = 0;

    ctx->listStats[dpy].mAIVVideoMode = false;
    resetROI(ctx, dpy);

    trimList(ctx, list, dpy);
    optimizeLayerRects(list);
    for (size_t i = 0; i < (size_t)ctx->listStats[dpy].numAppLayers; i++) {
        hwc_layer_1_t const* layer = &list->hwLayers[i];
        private_handle_t *hnd = (private_handle_t *)layer->handle;

#ifdef QCOM_BSP
        // Window boxing feature is applicable obly for external display, So
        // enable mAIVVideoMode only for external display
        if(ctx->mWindowboxFeature && dpy && isAIVVideoLayer(layer)) {
            ctx->listStats[dpy].mAIVVideoMode = true;
        }
        if (layer->flags & HWC_SCREENSHOT_ANIMATOR_LAYER) {
            ctx->listStats[dpy].isDisplayAnimating = true;
        }
        if(isSecureDisplayBuffer(hnd)) {
            ctx->listStats[dpy].secureUI = true;
        }
#endif
        // continue if number of app layers exceeds MAX_NUM_APP_LAYERS
        if(ctx->listStats[dpy].numAppLayers > MAX_NUM_APP_LAYERS)
            continue;

        //reset yuv indices
        ctx->listStats[dpy].yuvIndices[i] = -1;
        ctx->listStats[dpy].yuv4k2kIndices[i] = -1;

        if (isSecureBuffer(hnd)) {
            ctx->listStats[dpy].isSecurePresent = true;
            if(not isYuvBuffer(hnd)) {
                // cache secureRGB layer parameters like we cache for YUV layers
                int& secureRGBCount = ctx->listStats[dpy].secureRGBCount;
                ctx->listStats[dpy].secureRGBIndices[secureRGBCount] = (int)i;
                secureRGBCount++;
            }
        }

        if (isSkipLayer(&list->hwLayers[i])) {
            ctx->listStats[dpy].skipCount++;
        }

        if (UNLIKELY(isYuvBuffer(hnd))) {
            int& yuvCount = ctx->listStats[dpy].yuvCount;
            ctx->listStats[dpy].yuvIndices[yuvCount] = (int)i;
            yuvCount++;

            if(UNLIKELY(isYUVSplitNeeded(hnd))){
                int& yuv4k2kCount = ctx->listStats[dpy].yuv4k2kCount;
                ctx->listStats[dpy].yuv4k2kIndices[yuv4k2kCount] = (int)i;
                yuv4k2kCount++;
            }

            // Gets set if one YUV layer is 3D
            if (displaySupports3D(ctx,dpy)) {
                s3dFormat = get3DFormat(hnd);
                if(s3dFormat != HAL_NO_3D)
                    s3dLayerCount++;
            }

        }
        if(layer->blending == HWC_BLENDING_PREMULT)
            ctx->listStats[dpy].preMultipliedAlpha = true;

#ifdef DYNAMIC_FPS
        if (!dpy && mdpHw.isDynFpsSupported() && ctx->mUseMetaDataRefreshRate){
            //dyn fps: get refreshrate from metadata
            //Support multiple refresh rates if they are same
            //else set to  default
            MetaData_t *mdata = hnd ? (MetaData_t *)hnd->base_metadata : NULL;
            if (mdata && (mdata->operation & UPDATE_REFRESH_RATE)) {
                // Valid refreshRate in metadata and within the range
                uint32_t rate = roundOff(mdata->refreshrate);
                if((rate >= mdpHw.getMinFpsSupported() &&
                                rate <= mdpHw.getMaxFpsSupported())) {
                    if (!refreshRate) {
                        refreshRate = rate;
                    } else if(refreshRate != rate) {
                        // multiple refreshrate requests, set to default
                        refreshRate = ctx->dpyAttr[dpy].refreshRate;
                    }
                }
            }
        }
#endif
    }

    //Set the TV's 3D mode based on format if it was not forced
    //Only one 3D YUV layer is supported on external
    //If there is more than one 3D YUV layer, the switch to 3D cannot occur.
    if( !ctx->dpyAttr[dpy].s3dModeForced && (s3dLayerCount <= 1)) {
        //XXX: Rapidly going in and out of 3D mode in some cases such
        // as rotation might cause flickers. The OEMs are recommended to disable
        // rotation on HDMI globally or in the app that plays 3D video
        setup3DMode(ctx, dpy, convertS3DFormatToMode(s3dFormat));
    }

    if(ctx->listStats[dpy].yuvCount > 0) {
        if (property_get("hw.cabl.yuv", property, NULL) > 0) {
            if (atoi(property) != 1) {
                property_set("hw.cabl.yuv", "1");
            }
        }
    } else {
        if (property_get("hw.cabl.yuv", property, NULL) > 0) {
            if (atoi(property) != 0) {
                property_set("hw.cabl.yuv", "0");
            }
        }
    }

    //The marking of video begin/end is useful on some targets where we need
    //to have a padding round to be able to shift pipes across mixers.
    if(prevYuvCount != ctx->listStats[dpy].yuvCount) {
        ctx->mVideoTransFlag = true;
    }

    if(dpy == HWC_DISPLAY_PRIMARY) {
        ctx->mAD->markDoable(ctx, list);
        //Store the requested fresh rate
        ctx->listStats[dpy].refreshRateRequest = refreshRate ?
                                refreshRate : ctx->dpyAttr[dpy].refreshRate;
    }
}


static void calc_cut(double& leftCutRatio, double& topCutRatio,
        double& rightCutRatio, double& bottomCutRatio, int orient) {
    if(orient & HAL_TRANSFORM_FLIP_H) {
        swap(leftCutRatio, rightCutRatio);
    }
    if(orient & HAL_TRANSFORM_FLIP_V) {
        swap(topCutRatio, bottomCutRatio);
    }
    if(orient & HAL_TRANSFORM_ROT_90) {
        //Anti clock swapping
        double tmpCutRatio = leftCutRatio;
        leftCutRatio = topCutRatio;
        topCutRatio = rightCutRatio;
        rightCutRatio = bottomCutRatio;
        bottomCutRatio = tmpCutRatio;
    }
}

bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer) {
    if((ctx->mMDP.version < qdutils::MDSS_V5) &&
       (ctx->mMDP.version > qdutils::MDP_V3_0) &&
        ctx->mSecuring) {
        return true;
    }
    if (isSecureModePolicy(ctx->mMDP.version)) {
        private_handle_t *hnd = (private_handle_t *)layer->handle;
        if(ctx->mSecureMode) {
            if (! isSecureBuffer(hnd)) {
                ALOGD_IF(HWC_UTILS_DEBUG,"%s:Securing Turning ON ...",
                         __FUNCTION__);
                return true;
            }
        } else {
            if (isSecureBuffer(hnd)) {
                ALOGD_IF(HWC_UTILS_DEBUG,"%s:Securing Turning OFF ...",
                         __FUNCTION__);
                return true;
            }
        }
    }
    return false;
}

bool isSecureModePolicy(int mdpVersion) {
    if (mdpVersion < qdutils::MDSS_V5)
        return true;
    else
        return false;
}

bool isRotatorSupportedFormat(private_handle_t *hnd) {
    // Following rotator src formats are supported by mdp driver
    // TODO: Add more formats in future, if mdp driver adds support
    if(hnd != NULL) {
        switch(hnd->format) {
            case HAL_PIXEL_FORMAT_RGBA_8888:
            case HAL_PIXEL_FORMAT_RGBA_5551:
            case HAL_PIXEL_FORMAT_RGBA_4444:
            case HAL_PIXEL_FORMAT_RGB_565:
            case HAL_PIXEL_FORMAT_RGB_888:
            case HAL_PIXEL_FORMAT_BGRA_8888:
                return true;
            default:
                return false;
        }
    }
    return false;
}

bool isRotationDoable(hwc_context_t *ctx, private_handle_t *hnd) {
    // Rotate layers, if it is not secure display buffer and not
    // for the MDP versions below MDP5
    if((!isSecureDisplayBuffer(hnd) && isRotatorSupportedFormat(hnd) &&
        !ctx->mMDP.version < qdutils::MDSS_V5)
                   || isYuvBuffer(hnd)) {
        return true;
    }
    return false;
}

// returns true if Action safe dimensions are set and target supports Actionsafe
bool isActionSafePresent(hwc_context_t *ctx, int dpy) {
    // if external supports underscan, do nothing
    // it will be taken care in the driver
    // Disable Action safe for 8974 due to HW limitation for downscaling
    // layers with overlapped region
    // Disable Actionsafe for non HDMI displays.
    if(!(dpy == HWC_DISPLAY_EXTERNAL) ||
        qdutils::MDPVersion::getInstance().is8x74v2() ||
        ctx->mHDMIDisplay->isCEUnderscanSupported()) {
        return false;
    }

    char value[PROPERTY_VALUE_MAX];
    // Read action safe properties
    property_get("persist.sys.actionsafe.width", value, "0");
    ctx->dpyAttr[dpy].mAsWidthRatio = atoi(value);
    property_get("persist.sys.actionsafe.height", value, "0");
    ctx->dpyAttr[dpy].mAsHeightRatio = atoi(value);

    if(!ctx->dpyAttr[dpy].mAsWidthRatio && !ctx->dpyAttr[dpy].mAsHeightRatio) {
        //No action safe ratio set, return
        return false;
    }
    return true;
}

int getBlending(int blending) {
    switch(blending) {
    case HWC_BLENDING_NONE:
        return overlay::utils::OVERLAY_BLENDING_OPAQUE;
    case HWC_BLENDING_PREMULT:
        return overlay::utils::OVERLAY_BLENDING_PREMULT;
    case HWC_BLENDING_COVERAGE :
    default:
        return overlay::utils::OVERLAY_BLENDING_COVERAGE;
    }
}

//Crops source buffer against destination and FB boundaries
void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
                          const hwc_rect_t& scissor, int orient) {

    int& crop_l = crop.left;
    int& crop_t = crop.top;
    int& crop_r = crop.right;
    int& crop_b = crop.bottom;
    int crop_w = crop.right - crop.left;
    int crop_h = crop.bottom - crop.top;

    int& dst_l = dst.left;
    int& dst_t = dst.top;
    int& dst_r = dst.right;
    int& dst_b = dst.bottom;
    int dst_w = abs(dst.right - dst.left);
    int dst_h = abs(dst.bottom - dst.top);

    const int& sci_l = scissor.left;
    const int& sci_t = scissor.top;
    const int& sci_r = scissor.right;
    const int& sci_b = scissor.bottom;

    double leftCutRatio = 0.0, rightCutRatio = 0.0, topCutRatio = 0.0,
            bottomCutRatio = 0.0;

    if(dst_l < sci_l) {
        leftCutRatio = (double)(sci_l - dst_l) / (double)dst_w;
        dst_l = sci_l;
    }

    if(dst_r > sci_r) {
        rightCutRatio = (double)(dst_r - sci_r) / (double)dst_w;
        dst_r = sci_r;
    }

    if(dst_t < sci_t) {
        topCutRatio = (double)(sci_t - dst_t) / (double)dst_h;
        dst_t = sci_t;
    }

    if(dst_b > sci_b) {
        bottomCutRatio = (double)(dst_b - sci_b) / (double)dst_h;
        dst_b = sci_b;
    }

    calc_cut(leftCutRatio, topCutRatio, rightCutRatio, bottomCutRatio, orient);
    crop_l += (int)round((double)crop_w * leftCutRatio);
    crop_t += (int)round((double)crop_h * topCutRatio);
    crop_r -= (int)round((double)crop_w * rightCutRatio);
    crop_b -= (int)round((double)crop_h * bottomCutRatio);
}

bool areLayersIntersecting(const hwc_layer_1_t* layer1,
        const hwc_layer_1_t* layer2) {
    hwc_rect_t irect = getIntersection(layer1->displayFrame,
            layer2->displayFrame);
    return isValidRect(irect);
}

bool isSameRect(const hwc_rect& rect1, const hwc_rect& rect2)
{
   return ((rect1.left == rect2.left) && (rect1.top == rect2.top) &&
           (rect1.right == rect2.right) && (rect1.bottom == rect2.bottom));
}

bool isValidRect(const hwc_rect& rect)
{
   return ((rect.bottom > rect.top) && (rect.right > rect.left)) ;
}

bool operator ==(const hwc_rect_t& lhs, const hwc_rect_t& rhs) {
    if(lhs.left == rhs.left && lhs.top == rhs.top &&
       lhs.right == rhs.right &&  lhs.bottom == rhs.bottom )
          return true ;
    return false;
}

hwc_rect_t moveRect(const hwc_rect_t& rect, const int& x_off, const int& y_off)
{
    hwc_rect_t res;

    if(!isValidRect(rect))
        return (hwc_rect_t){0, 0, 0, 0};

    res.left = rect.left + x_off;
    res.top = rect.top + y_off;
    res.right = rect.right + x_off;
    res.bottom = rect.bottom + y_off;

    return res;
}

/* computes the intersection of two rects */
hwc_rect_t getIntersection(const hwc_rect_t& rect1, const hwc_rect_t& rect2)
{
   hwc_rect_t res;

   if(!isValidRect(rect1) || !isValidRect(rect2)){
      return (hwc_rect_t){0, 0, 0, 0};
   }


   res.left = max(rect1.left, rect2.left);
   res.top = max(rect1.top, rect2.top);
   res.right = min(rect1.right, rect2.right);
   res.bottom = min(rect1.bottom, rect2.bottom);

   if(!isValidRect(res))
      return (hwc_rect_t){0, 0, 0, 0};

   return res;
}

/* computes the union of two rects */
hwc_rect_t getUnion(const hwc_rect &rect1, const hwc_rect &rect2)
{
   hwc_rect_t res;

   if(!isValidRect(rect1)){
      return rect2;
   }

   if(!isValidRect(rect2)){
      return rect1;
   }

   res.left = min(rect1.left, rect2.left);
   res.top = min(rect1.top, rect2.top);
   res.right =  max(rect1.right, rect2.right);
   res.bottom =  max(rect1.bottom, rect2.bottom);

   return res;
}

/* Not a geometrical rect deduction. Deducts rect2 from rect1 only if it results
 * a single rect */
hwc_rect_t deductRect(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {

   hwc_rect_t res = rect1;

   if((rect1.left == rect2.left) && (rect1.right == rect2.right)) {
      if((rect1.top == rect2.top) && (rect2.bottom <= rect1.bottom))
         res.top = rect2.bottom;
      else if((rect1.bottom == rect2.bottom)&& (rect2.top >= rect1.top))
         res.bottom = rect2.top;
   }
   else if((rect1.top == rect2.top) && (rect1.bottom == rect2.bottom)) {
      if((rect1.left == rect2.left) && (rect2.right <= rect1.right))
         res.left = rect2.right;
      else if((rect1.right == rect2.right)&& (rect2.left >= rect1.left))
         res.right = rect2.left;
   }
   return res;
}

void optimizeLayerRects(const hwc_display_contents_1_t *list) {
    int i= (int)list->numHwLayers-2;
    while(i > 0) {
        //see if there is no blending required.
        //If it is opaque see if we can substract this region from below
        //layers.
        if(list->hwLayers[i].blending == HWC_BLENDING_NONE &&
                list->hwLayers[i].planeAlpha == 0xFF) {
            int j= i-1;
            hwc_rect_t& topframe =
                (hwc_rect_t&)list->hwLayers[i].displayFrame;
            while(j >= 0) {
               if(!needsScaling(&list->hwLayers[j])) {
                  hwc_layer_1_t* layer = (hwc_layer_1_t*)&list->hwLayers[j];
                  hwc_rect_t& bottomframe = layer->displayFrame;
                  hwc_rect_t bottomCrop =
                      integerizeSourceCrop(layer->sourceCropf);
                  int transform = (layer->flags & HWC_COLOR_FILL) ? 0 :
                      layer->transform;

                  hwc_rect_t irect = getIntersection(bottomframe, topframe);
                  if(isValidRect(irect)) {
                     hwc_rect_t dest_rect;
                     //if intersection is valid rect, deduct it
                     dest_rect  = deductRect(bottomframe, irect);
                     qhwc::calculate_crop_rects(bottomCrop, bottomframe,
                                                dest_rect, transform);
                     //Update layer sourceCropf
                     layer->sourceCropf.left =(float)bottomCrop.left;
                     layer->sourceCropf.top = (float)bottomCrop.top;
                     layer->sourceCropf.right = (float)bottomCrop.right;
                     layer->sourceCropf.bottom = (float)bottomCrop.bottom;
#ifdef QCOM_BSP
                     //Update layer dirtyRect
                     layer->dirtyRect = getIntersection(bottomCrop,
                                            layer->dirtyRect);
#endif
                  }
               }
               j--;
            }
        }
        i--;
    }
}

void getNonWormholeRegion(hwc_display_contents_1_t* list,
                              hwc_rect_t& nwr)
{
    size_t last = list->numHwLayers - 1;
    hwc_rect_t fbDisplayFrame = list->hwLayers[last].displayFrame;
    //Initiliaze nwr to first frame
    nwr.left =  list->hwLayers[0].displayFrame.left;
    nwr.top =  list->hwLayers[0].displayFrame.top;
    nwr.right =  list->hwLayers[0].displayFrame.right;
    nwr.bottom =  list->hwLayers[0].displayFrame.bottom;

    for (size_t i = 1; i < last; i++) {
        hwc_rect_t displayFrame = list->hwLayers[i].displayFrame;
        nwr = getUnion(nwr, displayFrame);
    }

    //Intersect with the framebuffer
    nwr = getIntersection(nwr, fbDisplayFrame);
}

void closeAcquireFds(hwc_display_contents_1_t* list) {
    if(LIKELY(list)) {
        for(uint32_t i = 0; i < list->numHwLayers; i++) {
            //Close the acquireFenceFds
            //HWC_FRAMEBUFFER are -1 already by SF, rest we close.
            if(list->hwLayers[i].acquireFenceFd >= 0) {
                close(list->hwLayers[i].acquireFenceFd);
                list->hwLayers[i].acquireFenceFd = -1;
            }
        }
        //Writeback
        if(list->outbufAcquireFenceFd >= 0) {
            close(list->outbufAcquireFenceFd);
            list->outbufAcquireFenceFd = -1;
        }
    }
}

int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
        int fd) {
    ATRACE_CALL();
    int ret = 0;
    int acquireFd[MAX_NUM_APP_LAYERS];
    int count = 0;
    int releaseFd = -1;
    int retireFd = -1;
    int fbFd = -1;
    bool swapzero = false;

    struct mdp_buf_sync data;
    memset(&data, 0, sizeof(data));
    data.acq_fen_fd = acquireFd;
    data.rel_fen_fd = &releaseFd;
    data.retire_fen_fd = &retireFd;
    data.flags = MDP_BUF_SYNC_FLAG_RETIRE_FENCE;

    char property[PROPERTY_VALUE_MAX];
    if(property_get("debug.egl.swapinterval", property, "1") > 0) {
        if(atoi(property) == 0)
            swapzero = true;
    }

    bool isExtAnimating = false;
    if(dpy)
       isExtAnimating = ctx->listStats[dpy].isDisplayAnimating;

    //Send acquireFenceFds to rotator
    for(uint32_t i = 0; i < ctx->mLayerRotMap[dpy]->getCount(); i++) {
        int rotFd = ctx->mRotMgr->getRotDevFd();
        int rotReleaseFd = -1;
        overlay::Rotator* currRot = ctx->mLayerRotMap[dpy]->getRot(i);
        hwc_layer_1_t* currLayer = ctx->mLayerRotMap[dpy]->getLayer(i);
        if((currRot == NULL) || (currLayer == NULL)) {
            continue;
        }
        struct mdp_buf_sync rotData;
        memset(&rotData, 0, sizeof(rotData));
        rotData.acq_fen_fd =
                &currLayer->acquireFenceFd;
        rotData.rel_fen_fd = &rotReleaseFd; //driver to populate this
        rotData.session_id = currRot->getSessId();
        if(currLayer->acquireFenceFd >= 0) {
            rotData.acq_fen_fd_cnt = 1; //1 ioctl call per rot session
        }
        int ret = 0;
        if(LIKELY(!swapzero) and (not ctx->mLayerRotMap[dpy]->isRotCached(i)))
            ret = ioctl(rotFd, MSMFB_BUFFER_SYNC, &rotData);

        if(ret < 0) {
            ALOGE("%s: ioctl MSMFB_BUFFER_SYNC failed for rot sync, err=%s",
                    __FUNCTION__, strerror(errno));
            close(rotReleaseFd);
        } else {
            close(currLayer->acquireFenceFd);
            //For MDP to wait on.
            currLayer->acquireFenceFd =
                    dup(rotReleaseFd);
            //A buffer is free to be used by producer as soon as its copied to
            //rotator
            currLayer->releaseFenceFd =
                    rotReleaseFd;
        }
    }

    //Accumulate acquireFenceFds for MDP Overlays
    if(list->outbufAcquireFenceFd >= 0) {
        //Writeback output buffer
        if(LIKELY(!swapzero) )
            acquireFd[count++] = list->outbufAcquireFenceFd;
    }

    for(uint32_t i = 0; i < list->numHwLayers; i++) {
        if(((isAbcInUse(ctx)== true ) ||
          (list->hwLayers[i].compositionType == HWC_OVERLAY)) &&
                        list->hwLayers[i].acquireFenceFd >= 0) {
            if(LIKELY(!swapzero) ) {
                // if ABC is enabled for more than one layer.
                // renderBufIndexforABC will work as FB.Hence
                // set the acquireFD from fd - which is coming from copybit
                if(fd >= 0 && (isAbcInUse(ctx) == true)) {
                    if(ctx->listStats[dpy].renderBufIndexforABC ==(int32_t)i)
                        acquireFd[count++] = fd;
                    else
                        continue;
                } else
                    acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
            }
        }
        if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
            if(LIKELY(!swapzero) ) {
                if(fd >= 0) {
                    //set the acquireFD from fd - which is coming from c2d
                    acquireFd[count++] = fd;
                    // Buffer sync IOCTL should be async when using c2d fence is
                    // used
                    data.flags &= ~MDP_BUF_SYNC_FLAG_WAIT;
                } else if(list->hwLayers[i].acquireFenceFd >= 0)
                    acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
            }
        }
    }

    if ((fd >= 0) && !dpy && ctx->mPtorInfo.isActive()) {
        // Acquire c2d fence of Overlap render buffer
        if(LIKELY(!swapzero) )
            acquireFd[count++] = fd;
    }

    data.acq_fen_fd_cnt = count;
    fbFd = ctx->dpyAttr[dpy].fd;

    //Waits for acquire fences, returns a release fence
    if(LIKELY(!swapzero)) {
        ret = ioctl(fbFd, MSMFB_BUFFER_SYNC, &data);
    }

    if(ret < 0) {
        ALOGE("%s: ioctl MSMFB_BUFFER_SYNC failed, err=%s",
                  __FUNCTION__, strerror(errno));
        ALOGE("%s: acq_fen_fd_cnt=%d flags=%d fd=%d dpy=%d numHwLayers=%zu",
              __FUNCTION__, data.acq_fen_fd_cnt, data.flags, fbFd,
              dpy, list->numHwLayers);
        close(releaseFd);
        releaseFd = -1;
        close(retireFd);
        retireFd = -1;
    }

    for(uint32_t i = 0; i < list->numHwLayers; i++) {
        if(list->hwLayers[i].compositionType == HWC_OVERLAY ||
#ifdef QCOM_BSP
           list->hwLayers[i].compositionType == HWC_BLIT ||
#endif
           list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) {
            //Populate releaseFenceFds.
            if(UNLIKELY(swapzero)) {
                list->hwLayers[i].releaseFenceFd = -1;
            } else if(isExtAnimating) {
                // Release all the app layer fds immediately,
                // if animation is in progress.
                list->hwLayers[i].releaseFenceFd = -1;
            } else if(list->hwLayers[i].releaseFenceFd < 0 ) {
#ifdef QCOM_BSP
                //If rotator has not already populated this field
                // & if it's a not VPU layer

                // if ABC is enabled for more than one layer
                if(fd >= 0 && (isAbcInUse(ctx) == true) &&
                  ctx->listStats[dpy].renderBufIndexforABC !=(int32_t)i){
                    list->hwLayers[i].releaseFenceFd = dup(fd);
                } else if((list->hwLayers[i].compositionType == HWC_BLIT)&&
                                               (isAbcInUse(ctx) == false)){
                    //For Blit, the app layers should be released when the Blit
                    //is complete. This fd was passed from copybit->draw
                    list->hwLayers[i].releaseFenceFd = dup(fd);
                } else
#endif
                {
                    list->hwLayers[i].releaseFenceFd = dup(releaseFd);
                }
            }
        }
    }

    if(fd >= 0) {
        close(fd);
        fd = -1;
    }

    if (ctx->mCopyBit[dpy]) {
        if (!dpy && ctx->mPtorInfo.isActive())
            ctx->mCopyBit[dpy]->setReleaseFdSync(releaseFd);
        else
            ctx->mCopyBit[dpy]->setReleaseFd(releaseFd);
    }

    //Signals when MDP finishes reading rotator buffers.
    ctx->mLayerRotMap[dpy]->setReleaseFd(releaseFd);
    close(releaseFd);
    releaseFd = -1;

    if(UNLIKELY(swapzero)) {
        list->retireFenceFd = -1;
    } else {
        list->retireFenceFd = retireFd;
    }
    return ret;
}

void setMdpFlags(hwc_context_t *ctx, hwc_layer_1_t *layer,
        ovutils::eMdpFlags &mdpFlags,
        int rotDownscale, int transform) {
    private_handle_t *hnd = (private_handle_t *)layer->handle;
    MetaData_t *metadata = hnd ? (MetaData_t *)hnd->base_metadata : NULL;

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

    if(metadata && (metadata->operation & PP_PARAM_INTERLACED) &&
            metadata->interlaced) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_DEINTERLACE);
    }

    // Mark MDP flags with SECURE_OVERLAY_SESSION for driver
    if(isSecureBuffer(hnd)) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_SMP_FORCE_ALLOC);
    }

    if(isProtectedBuffer(hnd)) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_SMP_FORCE_ALLOC);
    }

    if(isSecureDisplayBuffer(hnd)) {
        // Mark MDP flags with SECURE_DISPLAY_OVERLAY_SESSION for driver
        ovutils::setMdpFlags(mdpFlags,
                             ovutils::OV_MDP_SECURE_DISPLAY_OVERLAY_SESSION);
    }

    //Pre-rotation will be used using rotator.
    if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
        ovutils::setMdpFlags(mdpFlags,
                ovutils::OV_MDP_SOURCE_ROTATED_90);
    }
    //No 90 component and no rot-downscale then flips done by MDP
    //If we use rot then it might as well do flips
    if(!(transform & HWC_TRANSFORM_ROT_90) && !rotDownscale) {
        if(transform & HWC_TRANSFORM_FLIP_H) {
            ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H);
        }

        if(transform & HWC_TRANSFORM_FLIP_V) {
            ovutils::setMdpFlags(mdpFlags,  ovutils::OV_MDP_FLIP_V);
        }
    }

    if(metadata &&
        ((metadata->operation & PP_PARAM_HSIC)
        || (metadata->operation & PP_PARAM_IGC)
        || (metadata->operation & PP_PARAM_SHARP2))) {
        ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_PP_EN);
    }
}

int configRotator(Rotator *rot, Whf& whf,
        hwc_rect_t& crop, const eMdpFlags& mdpFlags,
        const eTransform& orient, const int& downscale) {

    // Fix alignments for TILED format
    if(whf.format == MDP_Y_CRCB_H2V2_TILE ||
                            whf.format == MDP_Y_CBCR_H2V2_TILE) {
        whf.w =  utils::alignup(whf.w, 64);
        whf.h = utils::alignup(whf.h, 32);
    }
    rot->setSource(whf);

    if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
        qdutils::MDSS_V5) {
         Dim rotCrop(crop.left, crop.top, crop.right - crop.left,
                crop.bottom - crop.top);
        rot->setCrop(rotCrop);
    }

    rot->setFlags(mdpFlags);
    rot->setTransform(orient);
    rot->setDownscale(downscale);
    if(!rot->commit()) return -1;
    return 0;
}

int configMdp(Overlay *ov, const PipeArgs& parg,
        const eTransform& orient, const hwc_rect_t& crop,
        const hwc_rect_t& pos, const MetaData_t *metadata,
        const eDest& dest) {
    ov->setSource(parg, dest);
    ov->setTransform(orient, dest);

    int crop_w = crop.right - crop.left;
    int crop_h = crop.bottom - crop.top;
    Dim dcrop(crop.left, crop.top, crop_w, crop_h);
    ov->setCrop(dcrop, dest);

    int posW = pos.right - pos.left;
    int posH = pos.bottom - pos.top;
    Dim position(pos.left, pos.top, posW, posH);
    ov->setPosition(position, dest);

    if (metadata)
        ov->setVisualParams(*metadata, dest);

    if (!ov->commit(dest)) {
        return -1;
    }
    return 0;
}

int configColorLayer(hwc_context_t *ctx, hwc_layer_1_t *layer,
        const int& dpy, eMdpFlags& mdpFlags, eZorder& z,
        const eDest& dest) {

    hwc_rect_t dst = layer->displayFrame;
    trimLayer(ctx, dpy, 0, dst, dst);

    int w = ctx->dpyAttr[dpy].xres;
    int h = ctx->dpyAttr[dpy].yres;
    int dst_w = dst.right - dst.left;
    int dst_h = dst.bottom - dst.top;
    uint32_t color = layer->transform;
    Whf whf(w, h, getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888));

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

    PipeArgs parg(mdpFlags, whf, z, static_cast<eRotFlags>(0),
                  layer->planeAlpha,
                  (ovutils::eBlending) getBlending(layer->blending));

    // Configure MDP pipe for Color layer
    Dim pos(dst.left, dst.top, dst_w, dst_h);
    ctx->mOverlay->setSource(parg, dest);
    ctx->mOverlay->setColor(color, dest);
    ctx->mOverlay->setTransform(0, dest);
    ctx->mOverlay->setCrop(pos, dest);
    ctx->mOverlay->setPosition(pos, dest);

    if (!ctx->mOverlay->commit(dest)) {
        ALOGE("%s: Configure color layer failed!", __FUNCTION__);
        return -1;
    }
    return 0;
}

void updateSource(eTransform& orient, Whf& whf,
        hwc_rect_t& crop, Rotator *rot) {
    Dim transformedCrop(crop.left, crop.top,
            crop.right - crop.left,
            crop.bottom - crop.top);
    if (qdutils::MDPVersion::getInstance().getMDPVersion() >=
        qdutils::MDSS_V5) {
        //B-family rotator internally could modify destination dimensions if
        //downscaling is supported
        whf = rot->getDstWhf();
        transformedCrop = rot->getDstDimensions();
    } else {
        //A-family rotator rotates entire buffer irrespective of crop, forcing
        //us to recompute the crop based on transform
        orient = static_cast<eTransform>(ovutils::getMdpOrient(orient));
        preRotateSource(orient, whf, transformedCrop);
    }

    crop.left = transformedCrop.x;
    crop.top = transformedCrop.y;
    crop.right = transformedCrop.x + transformedCrop.w;
    crop.bottom = transformedCrop.y + transformedCrop.h;
}

int getRotDownscale(hwc_context_t *ctx, const hwc_layer_1_t *layer) {
    if(not qdutils::MDPVersion::getInstance().isRotDownscaleEnabled()) {
        return 0;
    }

    int downscale = 0;
    hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
    hwc_rect_t dst = layer->displayFrame;
    private_handle_t *hnd = (private_handle_t *)layer->handle;

    if(not hnd) {
        return 0;
    }

    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;
    bool isInterlaced = metadata && (metadata->operation & PP_PARAM_INTERLACED)
                && metadata->interlaced;
    int transform = layer->transform;
    uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);

    if(isYuvBuffer(hnd)) {
        if(ctx->mMDP.version >= qdutils::MDP_V4_2 &&
                ctx->mMDP.version < qdutils::MDSS_V5) {
            downscale = Rotator::getDownscaleFactor(crop.right - crop.left,
                    crop.bottom - crop.top, dst.right - dst.left,
                    dst.bottom - dst.top, format, isInterlaced);
        } else {
            Dim adjCrop(crop.left, crop.top, crop.right - crop.left,
                    crop.bottom - crop.top);
            Dim pos(dst.left, dst.top, dst.right - dst.left,
                    dst.bottom - dst.top);
            if(transform & HAL_TRANSFORM_ROT_90) {
                swap(adjCrop.w, adjCrop.h);
            }
            downscale = Rotator::getDownscaleFactor(adjCrop.w, adjCrop.h, pos.w,
                    pos.h, format, isInterlaced);
        }
    }
    return downscale;
}

bool isZoomModeEnabled(hwc_rect_t crop) {
    // This does not work for zooming in top left corner of the image
    return(crop.top > 0 || crop.left > 0);
}

void updateCropAIVVideoMode(hwc_context_t *ctx, hwc_rect_t& crop, int dpy) {
    ALOGD_IF(HWC_UTILS_DEBUG, "dpy %d Source crop [%d %d %d %d]", dpy,
             crop.left, crop.top, crop.right, crop.bottom);
    if(isZoomModeEnabled(crop)) {
        Dim srcCrop(crop.left, crop.top,
                crop.right - crop.left,
                crop.bottom - crop.top);
        int extW = ctx->dpyAttr[dpy].xres;
        int extH = ctx->dpyAttr[dpy].yres;
        //Crop the original video in order to fit external display aspect ratio
        if(srcCrop.w * extH < extW * srcCrop.h) {
            int offset = (srcCrop.h - ((srcCrop.w * extH) / extW)) / 2;
            crop.top += offset;
            crop.bottom -= offset;
        } else {
            int offset = (srcCrop.w - ((extW * srcCrop.h) / extH)) / 2;
            crop.left += offset;
            crop.right -= offset;
        }
        ALOGD_IF(HWC_UTILS_DEBUG, "External Resolution [%d %d] dpy %d Modified"
                 " source crop [%d %d %d %d]", extW, extH, dpy,
                 crop.left, crop.top, crop.right, crop.bottom);
    }
}

void updateDestAIVVideoMode(hwc_context_t *ctx, hwc_rect_t crop,
                           hwc_rect_t& dst, int dpy) {
    ALOGD_IF(HWC_UTILS_DEBUG, "dpy %d Destination position [%d %d %d %d]", dpy,
             dst.left, dst.top, dst.right, dst.bottom);
    Dim srcCrop(crop.left, crop.top,
            crop.right - crop.left,
            crop.bottom - crop.top);
    int extW = ctx->dpyAttr[dpy].xres;
    int extH = ctx->dpyAttr[dpy].yres;
    // Set the destination coordinates of external display to full screen,
    // when zoom in mode is enabled or the ratio between video aspect ratio
    // and external display aspect ratio is below the minimum tolerance level
    // and above maximum tolerance level
    float videoAspectRatio = ((float)srcCrop.w / (float)srcCrop.h);
    float extDisplayAspectRatio = ((float)extW / (float)extH);
    float videoToExternalRatio = videoAspectRatio / extDisplayAspectRatio;
    if((fabs(1.0f - videoToExternalRatio) <= ctx->mAspectRatioToleranceLevel) ||
        (isZoomModeEnabled(crop))) {
        dst.left = 0;
        dst.top = 0;
        dst.right = extW;
        dst.bottom = extH;
    }
    ALOGD_IF(HWC_UTILS_DEBUG, "External Resolution [%d %d] dpy %d Modified"
             " Destination position [%d %d %d %d] Source crop [%d %d %d %d]",
             extW, extH, dpy, dst.left, dst.top, dst.right, dst.bottom,
             crop.left, crop.top, crop.right, crop.bottom);
}

void updateCoordinates(hwc_context_t *ctx, hwc_rect_t& crop,
                           hwc_rect_t& dst, int dpy) {
    updateCropAIVVideoMode(ctx, crop, dpy);
    updateDestAIVVideoMode(ctx, crop, dst, dpy);
}

int configureNonSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
        const int& dpy, eMdpFlags& mdpFlags, eZorder& z,
        const eDest& dest, Rotator **rot) {

    private_handle_t *hnd = (private_handle_t *)layer->handle;

    if(!hnd) {
        if (layer->flags & HWC_COLOR_FILL) {
            // Configure Color layer
            return configColorLayer(ctx, layer, dpy, mdpFlags, z, dest);
        }
        ALOGE("%s: layer handle is NULL", __FUNCTION__);
        return -1;
    }

    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;

    hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
    hwc_rect_t dst = layer->displayFrame;
    int transform = layer->transform;
    eTransform orient = static_cast<eTransform>(transform);
    int rotFlags = ovutils::ROT_FLAGS_NONE;
    uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
    Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);

    // Handle R/B swap
    if (layer->flags & HWC_FORMAT_RB_SWAP) {
        if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
        else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
    }
    // update source crop and destination position of AIV video layer.
    if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
        updateCoordinates(ctx, crop, dst, dpy);
    }
    calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
    int downscale = getRotDownscale(ctx, layer);
    setMdpFlags(ctx, layer, mdpFlags, downscale, transform);

    //if 90 component or downscale, use rot
    if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
        *rot = ctx->mRotMgr->getNext();
        if(*rot == NULL) return -1;
        ctx->mLayerRotMap[dpy]->add(layer, *rot);
        BwcPM::setBwc(ctx, dpy, hnd, crop, dst, transform, downscale,
                mdpFlags);
        //Configure rotator for pre-rotation
        if(configRotator(*rot, whf, crop, mdpFlags, orient, downscale) < 0) {
            ALOGE("%s: configRotator failed!", __FUNCTION__);
            return -1;
        }
        updateSource(orient, whf, crop, *rot);
        rotFlags |= ROT_PREROTATED;
    }

    //For the mdp, since either we are pre-rotating or MDP does flips
    orient = OVERLAY_TRANSFORM_0;
    transform = 0;
    PipeArgs parg(mdpFlags, whf, z,
                  static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
                  (ovutils::eBlending) getBlending(layer->blending));

    if(configMdp(ctx->mOverlay, parg, orient, crop, dst, metadata, dest) < 0) {
        ALOGE("%s: commit failed for low res panel", __FUNCTION__);
        return -1;
    }
    return 0;
}

//Helper to 1) Ensure crops dont have gaps 2) Ensure L and W are even
void sanitizeSourceCrop(hwc_rect_t& cropL, hwc_rect_t& cropR,
        private_handle_t *hnd) {
    if(cropL.right - cropL.left) {
        if(isYuvBuffer(hnd)) {
            //Always safe to even down left
            ovutils::even_floor(cropL.left);
            //If right is even, automatically width is even, since left is
            //already even
            ovutils::even_floor(cropL.right);
        }
        //Make sure there are no gaps between left and right splits if the layer
        //is spread across BOTH halves
        if(cropR.right - cropR.left) {
            cropR.left = cropL.right;
        }
    }

    if(cropR.right - cropR.left) {
        if(isYuvBuffer(hnd)) {
            //Always safe to even down left
            ovutils::even_floor(cropR.left);
            //If right is even, automatically width is even, since left is
            //already even
            ovutils::even_floor(cropR.right);
        }
    }
}

int configureSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
        const int& dpy, eMdpFlags& mdpFlagsL, eZorder& z,
        const eDest& lDest, const eDest& rDest,
        Rotator **rot) {
    private_handle_t *hnd = (private_handle_t *)layer->handle;
    if(!hnd) {
        ALOGE("%s: layer handle is NULL", __FUNCTION__);
        return -1;
    }

    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;

    int hw_w = ctx->dpyAttr[dpy].xres;
    int hw_h = ctx->dpyAttr[dpy].yres;
    hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
    hwc_rect_t dst = layer->displayFrame;
    int transform = layer->transform;
    eTransform orient = static_cast<eTransform>(transform);
    int rotFlags = ROT_FLAGS_NONE;
    uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
    Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);

    // Handle R/B swap
    if (layer->flags & HWC_FORMAT_RB_SWAP) {
        if (hnd->format == HAL_PIXEL_FORMAT_RGBA_8888)
            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRA_8888);
        else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
            whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
    }

    // update source crop and destination position of AIV video layer.
    if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
        updateCoordinates(ctx, crop, dst, dpy);
    }

    /* Calculate the external display position based on MDP downscale,
       ActionSafe, and extorientation features. */
    calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);
    int downscale = getRotDownscale(ctx, layer);
    setMdpFlags(ctx, layer, mdpFlagsL, downscale, transform);

    if(lDest != OV_INVALID && rDest != OV_INVALID) {
        //Enable overfetch
        setMdpFlags(mdpFlagsL, OV_MDSS_MDP_DUAL_PIPE);
    }

    //Will do something only if feature enabled and conditions suitable
    //hollow call otherwise
    if(ctx->mAD->prepare(ctx, crop, whf, hnd)) {
        overlay::Writeback *wb = overlay::Writeback::getInstance();
        whf.format = wb->getOutputFormat();
    }

    if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
        (*rot) = ctx->mRotMgr->getNext();
        if((*rot) == NULL) return -1;
        ctx->mLayerRotMap[dpy]->add(layer, *rot);
        //Configure rotator for pre-rotation
        if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
            ALOGE("%s: configRotator failed!", __FUNCTION__);
            return -1;
        }
        updateSource(orient, whf, crop, *rot);
        rotFlags |= ROT_PREROTATED;
    }

    eMdpFlags mdpFlagsR = mdpFlagsL;
    setMdpFlags(mdpFlagsR, OV_MDSS_MDP_RIGHT_MIXER);

    hwc_rect_t tmp_cropL = {0}, tmp_dstL = {0};
    hwc_rect_t tmp_cropR = {0}, tmp_dstR = {0};

    const int lSplit = getLeftSplit(ctx, dpy);

    // Calculate Left rects
    if(dst.left < lSplit) {
        tmp_cropL = crop;
        tmp_dstL = dst;
        hwc_rect_t scissor = {0, 0, lSplit, hw_h };
        scissor = getIntersection(ctx->mViewFrame[dpy], scissor);
        qhwc::calculate_crop_rects(tmp_cropL, tmp_dstL, scissor, 0);
    }

    // Calculate Right rects
    if(dst.right > lSplit) {
        tmp_cropR = crop;
        tmp_dstR = dst;
        hwc_rect_t scissor = {lSplit, 0, hw_w, hw_h };
        scissor = getIntersection(ctx->mViewFrame[dpy], scissor);
        qhwc::calculate_crop_rects(tmp_cropR, tmp_dstR, scissor, 0);
    }

    sanitizeSourceCrop(tmp_cropL, tmp_cropR, hnd);

    //When buffer is H-flipped, contents of mixer config also needs to swapped
    //Not needed if the layer is confined to one half of the screen.
    //If rotator has been used then it has also done the flips, so ignore them.
    if((orient & OVERLAY_TRANSFORM_FLIP_H) && (dst.left < lSplit) &&
            (dst.right > lSplit) && (*rot) == NULL) {
        hwc_rect_t new_cropR;
        new_cropR.left = tmp_cropL.left;
        new_cropR.right = new_cropR.left + (tmp_cropR.right - tmp_cropR.left);

        hwc_rect_t new_cropL;
        new_cropL.left  = new_cropR.right;
        new_cropL.right = tmp_cropR.right;

        tmp_cropL.left =  new_cropL.left;
        tmp_cropL.right =  new_cropL.right;

        tmp_cropR.left = new_cropR.left;
        tmp_cropR.right =  new_cropR.right;

    }

    //For the mdp, since either we are pre-rotating or MDP does flips
    orient = OVERLAY_TRANSFORM_0;
    transform = 0;

    //configure left mixer
    if(lDest != OV_INVALID) {
        PipeArgs pargL(mdpFlagsL, whf, z,
                       static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
                       (ovutils::eBlending) getBlending(layer->blending));

        if(configMdp(ctx->mOverlay, pargL, orient,
                tmp_cropL, tmp_dstL, metadata, lDest) < 0) {
            ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
            return -1;
        }
    }

    //configure right mixer
    if(rDest != OV_INVALID) {
        PipeArgs pargR(mdpFlagsR, whf, z,
                       static_cast<eRotFlags>(rotFlags),
                       layer->planeAlpha,
                       (ovutils::eBlending) getBlending(layer->blending));
        tmp_dstR.right = tmp_dstR.right - lSplit;
        tmp_dstR.left = tmp_dstR.left - lSplit;
        if(configMdp(ctx->mOverlay, pargR, orient,
                tmp_cropR, tmp_dstR, metadata, rDest) < 0) {
            ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
            return -1;
        }
    }

    return 0;
}

int configure3DVideo(hwc_context_t *ctx, hwc_layer_1_t *layer,
        const int& dpy, eMdpFlags& mdpFlagsL, eZorder& z,
        const eDest& lDest, const eDest& rDest,
        Rotator **rot) {
    private_handle_t *hnd = (private_handle_t *)layer->handle;
    if(!hnd) {
        ALOGE("%s: layer handle is NULL", __FUNCTION__);
        return -1;
    }
    //Both pipes are configured to the same mixer
    eZorder lz = z;
    eZorder rz = (eZorder)(z + 1);

    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;

    hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
    hwc_rect_t dst = layer->displayFrame;
    int transform = layer->transform;
    eTransform orient = static_cast<eTransform>(transform);
    int rotFlags = ROT_FLAGS_NONE;
    uint32_t format = ovutils::getMdpFormat(hnd->format, hnd->flags);
    Whf whf(getWidth(hnd), getHeight(hnd), format, (uint32_t)hnd->size);

    int downscale = getRotDownscale(ctx, layer);
    setMdpFlags(ctx, layer, mdpFlagsL, downscale, transform);

    //XXX: Check if rotation is supported and valid for 3D
    if((has90Transform(layer) or downscale) and isRotationDoable(ctx, hnd)) {
        (*rot) = ctx->mRotMgr->getNext();
        if((*rot) == NULL) return -1;
        ctx->mLayerRotMap[dpy]->add(layer, *rot);
        //Configure rotator for pre-rotation
        if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
            ALOGE("%s: configRotator failed!", __FUNCTION__);
            return -1;
        }
        updateSource(orient, whf, crop, *rot);
        rotFlags |= ROT_PREROTATED;
    }

    eMdpFlags mdpFlagsR = mdpFlagsL;

    hwc_rect_t cropL = crop, dstL = dst;
    hwc_rect_t cropR = crop, dstR = dst;
    int hw_w = ctx->dpyAttr[dpy].xres;
    int hw_h = ctx->dpyAttr[dpy].yres;

    if(get3DFormat(hnd) == HAL_3D_SIDE_BY_SIDE_L_R ||
            get3DFormat(hnd) == HAL_3D_SIDE_BY_SIDE_R_L) {
        // Calculate Left rects
        // XXX: This assumes crop.right/2 is the center point of the video
        cropL.right = crop.right/2;
        dstL.left = dst.left/2;
        dstL.right = dst.right/2;

        // Calculate Right rects
        cropR.left = crop.right/2;
        dstR.left = hw_w/2 + dst.left/2;
        dstR.right = hw_w/2 + dst.right/2;
    } else if(get3DFormat(hnd) == HAL_3D_TOP_BOTTOM) {
        // Calculate Left rects
        cropL.bottom = crop.bottom/2;
        dstL.top = dst.top/2;
        dstL.bottom = dst.bottom/2;

        // Calculate Right rects
        cropR.top = crop.bottom/2;
        dstR.top = hw_h/2 + dst.top/2;
        dstR.bottom = hw_h/2 + dst.bottom/2;
    } else {
        ALOGE("%s: Unsupported 3D mode ", __FUNCTION__);
        return -1;
    }

    //For the mdp, since either we are pre-rotating or MDP does flips
    orient = OVERLAY_TRANSFORM_0;
    transform = 0;

    //configure left pipe
    if(lDest != OV_INVALID) {
        PipeArgs pargL(mdpFlagsL, whf, lz,
                       static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
                       (ovutils::eBlending) getBlending(layer->blending));

        if(configMdp(ctx->mOverlay, pargL, orient,
                cropL, dstL, metadata, lDest) < 0) {
            ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
            return -1;
        }
    }

    //configure right pipe
    if(rDest != OV_INVALID) {
        PipeArgs pargR(mdpFlagsR, whf, rz,
                       static_cast<eRotFlags>(rotFlags),
                       layer->planeAlpha,
                       (ovutils::eBlending) getBlending(layer->blending));
        if(configMdp(ctx->mOverlay, pargR, orient,
                cropR, dstR, metadata, rDest) < 0) {
            ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
            return -1;
        }
    }

    return 0;
}

int configureSourceSplit(hwc_context_t *ctx, hwc_layer_1_t *layer,
        const int& dpy, eMdpFlags& mdpFlagsL, eZorder& z,
        const eDest& lDest, const eDest& rDest,
        Rotator **rot) {
    private_handle_t *hnd = (private_handle_t *)layer->handle;
    if(!hnd) {
        ALOGE("%s: layer handle is NULL", __FUNCTION__);
        return -1;
    }

    MetaData_t *metadata = (MetaData_t *)hnd->base_metadata;

    hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);;
    hwc_rect_t dst = layer->displayFrame;
    int transform = layer->transform;
    eTransform orient = static_cast<eTransform>(transform);
    const int downscale = 0;
    int rotFlags = ROT_FLAGS_NONE;
    //Splitting only YUV layer on primary panel needs different zorders
    //for both layers as both the layers are configured to single mixer
    eZorder lz = z;
    eZorder rz = (eZorder)(z + 1);

    Whf whf(getWidth(hnd), getHeight(hnd),
            getMdpFormat(hnd->format), (uint32_t)hnd->size);

    // update source crop and destination position of AIV video layer.
    if(ctx->listStats[dpy].mAIVVideoMode && isYuvBuffer(hnd)) {
        updateCoordinates(ctx, crop, dst, dpy);
    }

    /* Calculate the external display position based on MDP downscale,
       ActionSafe, and extorientation features. */
    calcExtDisplayPosition(ctx, hnd, dpy, crop, dst, transform, orient);

    setMdpFlags(ctx, layer, mdpFlagsL, 0, transform);
    trimLayer(ctx, dpy, transform, crop, dst);

    if(has90Transform(layer) && isRotationDoable(ctx, hnd)) {
        (*rot) = ctx->mRotMgr->getNext();
        if((*rot) == NULL) return -1;
        ctx->mLayerRotMap[dpy]->add(layer, *rot);
        //Configure rotator for pre-rotation
        if(configRotator(*rot, whf, crop, mdpFlagsL, orient, downscale) < 0) {
            ALOGE("%s: configRotator failed!", __FUNCTION__);
            return -1;
        }
        updateSource(orient, whf, crop, *rot);
        rotFlags |= ROT_PREROTATED;
    }

    eMdpFlags mdpFlagsR = mdpFlagsL;
    int lSplit = dst.left + (dst.right - dst.left)/2;

    hwc_rect_t tmp_cropL = {0}, tmp_dstL = {0};
    hwc_rect_t tmp_cropR = {0}, tmp_dstR = {0};

    if(lDest != OV_INVALID) {
        tmp_cropL = crop;
        tmp_dstL = dst;
        hwc_rect_t scissor = {dst.left, dst.top, lSplit, dst.bottom };
        qhwc::calculate_crop_rects(tmp_cropL, tmp_dstL, scissor, 0);
    }
    if(rDest != OV_INVALID) {
        tmp_cropR = crop;
        tmp_dstR = dst;
        hwc_rect_t scissor = {lSplit, dst.top, dst.right, dst.bottom };
        qhwc::calculate_crop_rects(tmp_cropR, tmp_dstR, scissor, 0);
    }

    sanitizeSourceCrop(tmp_cropL, tmp_cropR, hnd);

    //When buffer is H-flipped, contents of mixer config also needs to swapped
    //Not needed if the layer is confined to one half of the screen.
    //If rotator has been used then it has also done the flips, so ignore them.
    if((orient & OVERLAY_TRANSFORM_FLIP_H) && lDest != OV_INVALID
            && rDest != OV_INVALID && (*rot) == NULL) {
        hwc_rect_t new_cropR;
        new_cropR.left = tmp_cropL.left;
        new_cropR.right = new_cropR.left + (tmp_cropR.right - tmp_cropR.left);

        hwc_rect_t new_cropL;
        new_cropL.left  = new_cropR.right;
        new_cropL.right = tmp_cropR.right;

        tmp_cropL.left =  new_cropL.left;
        tmp_cropL.right =  new_cropL.right;

        tmp_cropR.left = new_cropR.left;
        tmp_cropR.right =  new_cropR.right;

    }

    //For the mdp, since either we are pre-rotating or MDP does flips
    orient = OVERLAY_TRANSFORM_0;
    transform = 0;

    //configure left half
    if(lDest != OV_INVALID) {
        PipeArgs pargL(mdpFlagsL, whf, lz,
                static_cast<eRotFlags>(rotFlags), layer->planeAlpha,
                (ovutils::eBlending) getBlending(layer->blending));

        if(configMdp(ctx->mOverlay, pargL, orient,
                    tmp_cropL, tmp_dstL, metadata, lDest) < 0) {
            ALOGE("%s: commit failed for left half config", __FUNCTION__);
            return -1;
        }
    }

    //configure right half
    if(rDest != OV_INVALID) {
        PipeArgs pargR(mdpFlagsR, whf, rz,
                static_cast<eRotFlags>(rotFlags),
                layer->planeAlpha,
                (ovutils::eBlending) getBlending(layer->blending));
        if(configMdp(ctx->mOverlay, pargR, orient,
                    tmp_cropR, tmp_dstR, metadata, rDest) < 0) {
            ALOGE("%s: commit failed for right half config", __FUNCTION__);
            return -1;
        }
    }

    return 0;
}

bool canUseRotator(hwc_context_t *ctx, int dpy) {
    if(ctx->mOverlay->isDMAMultiplexingSupported() &&
            isSecondaryConnected(ctx) &&
            !ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].isPause) {
        /* mdss driver on certain targets support multiplexing of DMA pipe
         * in LINE and BLOCK modes for writeback panels.
         */
        if(dpy == HWC_DISPLAY_PRIMARY)
            return false;
    }
    if((ctx->mMDP.version == qdutils::MDP_V3_0_4)
          ||(ctx->mMDP.version == qdutils::MDP_V3_0_5))
        return false;
    return true;
}

int getLeftSplit(hwc_context_t *ctx, const int& dpy) {
    //Default even split for all displays with high res
    int lSplit = ctx->dpyAttr[dpy].xres / 2;
    if(dpy == HWC_DISPLAY_PRIMARY &&
            qdutils::MDPVersion::getInstance().getLeftSplit()) {
        //Override if split published by driver for primary
        lSplit = qdutils::MDPVersion::getInstance().getLeftSplit();
    }
    return lSplit;
}

bool isDisplaySplit(hwc_context_t* ctx, int dpy) {
    qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
    if(ctx->dpyAttr[dpy].xres > mdpHw.getMaxMixerWidth()) {
        return true;
    }
    if(dpy == HWC_DISPLAY_PRIMARY && mdpHw.getRightSplit()) {
        return true;
    }
    return false;
}

//clear prev layer prop flags and realloc for current frame
void reset_layer_prop(hwc_context_t* ctx, int dpy, int numAppLayers) {
    if(ctx->layerProp[dpy]) {
       delete[] ctx->layerProp[dpy];
       ctx->layerProp[dpy] = NULL;
    }
    ctx->layerProp[dpy] = new LayerProp[numAppLayers];
}

bool isAbcInUse(hwc_context_t *ctx){
  return (ctx->enableABC && ctx->listStats[0].renderBufIndexforABC == 0);
}

void dumpBuffer(private_handle_t *ohnd, char *bufferName) {
    if (ohnd != NULL && ohnd->base) {
        char dumpFilename[PATH_MAX];
        bool bResult = false;
        int width = getWidth(ohnd);
        int height = getHeight(ohnd);
        int format = ohnd->format;
        //dummy aligned w & h.
        int alW = 0, alH = 0;
        int size = getBufferSizeAndDimensions(width, height, format, alW, alH);
        snprintf(dumpFilename, sizeof(dumpFilename), "/data/%s.%s.%dx%d.raw",
            bufferName,
            overlay::utils::getFormatString(utils::getMdpFormat(format)),
            width, height);
        FILE* fp = fopen(dumpFilename, "w+");
        if (NULL != fp) {
            bResult = (bool) fwrite((void*)ohnd->base, size, 1, fp);
            fclose(fp);
        }
        ALOGD("Buffer[%s] Dump to %s: %s",
        bufferName, dumpFilename, bResult ? "Success" : "Fail");
    }
}

bool isGLESComp(hwc_context_t *ctx,
                     hwc_display_contents_1_t* list) {
    int numAppLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
    for(int index = 0; index < numAppLayers; index++) {
        hwc_layer_1_t* layer = &(list->hwLayers[index]);
        if(layer->compositionType == HWC_FRAMEBUFFER)
            return true;
    }
    return false;
}

void setGPUHint(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
    struct gpu_hint_info *gpuHint = &ctx->mGPUHintInfo;
    if(!gpuHint->mGpuPerfModeEnable || !ctx || !list)
        return;

#ifdef QCOM_BSP
    /* Set the GPU hint flag to high for MIXED/GPU composition only for
       first frame after MDP -> GPU/MIXED mode transition. Set the GPU
       hint to default if the previous composition is GPU or current GPU
       composition is due to idle fallback */
    if(!gpuHint->mEGLDisplay || !gpuHint->mEGLContext) {
        gpuHint->mEGLDisplay = eglGetCurrentDisplay();
        if(!gpuHint->mEGLDisplay) {
            ALOGW("%s Warning: EGL current display is NULL", __FUNCTION__);
            return;
        }
        gpuHint->mEGLContext = eglGetCurrentContext();
        if(!gpuHint->mEGLContext) {
            ALOGW("%s Warning: EGL current context is NULL", __FUNCTION__);
            return;
        }
    }
    if(isGLESComp(ctx, list)) {
        if(gpuHint->mCompositionState != COMPOSITION_STATE_GPU
            && !MDPComp::isIdleFallback()) {
            EGLint attr_list[] = {EGL_GPU_HINT_1,
                                  EGL_GPU_LEVEL_3,
                                  EGL_NONE };
            if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_3) &&
                !eglGpuPerfHintQCOM(gpuHint->mEGLDisplay,
                                    gpuHint->mEGLContext, attr_list)) {
                ALOGW("eglGpuPerfHintQCOM failed for Built in display");
            } else {
                gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_3;
                gpuHint->mCompositionState = COMPOSITION_STATE_GPU;
            }
        } else {
            EGLint attr_list[] = {EGL_GPU_HINT_1,
                                  EGL_GPU_LEVEL_0,
                                  EGL_NONE };
            if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_0) &&
                !eglGpuPerfHintQCOM(gpuHint->mEGLDisplay,
                                    gpuHint->mEGLContext, attr_list)) {
                ALOGW("eglGpuPerfHintQCOM failed for Built in display");
            } else {
                gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
            }
            if(MDPComp::isIdleFallback()) {
                gpuHint->mCompositionState = COMPOSITION_STATE_IDLE_FALLBACK;
            }
        }
    } else {
        /* set the GPU hint flag to default for MDP composition */
        EGLint attr_list[] = {EGL_GPU_HINT_1,
                              EGL_GPU_LEVEL_0,
                              EGL_NONE };
        if((gpuHint->mCurrGPUPerfMode != EGL_GPU_LEVEL_0) &&
                !eglGpuPerfHintQCOM(gpuHint->mEGLDisplay,
                                    gpuHint->mEGLContext, attr_list)) {
            ALOGW("eglGpuPerfHintQCOM failed for Built in display");
        } else {
            gpuHint->mCurrGPUPerfMode = EGL_GPU_LEVEL_0;
        }
        gpuHint->mCompositionState = COMPOSITION_STATE_MDP;
    }
#endif
}

bool isPeripheral(const hwc_rect_t& rect1, const hwc_rect_t& rect2) {
    // To be peripheral, 3 boundaries should match.
    uint8_t eqBounds = 0;
    if (rect1.left == rect2.left)
        eqBounds++;
    if (rect1.top == rect2.top)
        eqBounds++;
    if (rect1.right == rect2.right)
        eqBounds++;
    if (rect1.bottom == rect2.bottom)
        eqBounds++;
    return (eqBounds == 3);
}

void processBootAnimCompleted(hwc_context_t *ctx) {
    char value[PROPERTY_VALUE_MAX];
    int boot_finished = 0, ret = -1;
    int (*applyMode)(int) = NULL;
    void *modeHandle = NULL;

    // Reading property set on boot finish in SF
    property_get("service.bootanim.exit", value, "0");
    boot_finished = atoi(value);
    if (!boot_finished)
        return;

    modeHandle = dlopen("libmm-qdcm.so", RTLD_NOW);
    if (modeHandle) {
        *(void **)&applyMode = dlsym(modeHandle, "applyDefaults");
        if (applyMode) {
            ret = applyMode(HWC_DISPLAY_PRIMARY);
            if (ret)
                ALOGD("%s: Not able to apply default mode", __FUNCTION__);
        } else {
            ALOGE("%s: No symbol applyDefaults found", __FUNCTION__);
        }
        dlclose(modeHandle);
    } else {
        ALOGE("%s: Not able to load libmm-qdcm.so", __FUNCTION__);
    }

    ctx->mBootAnimCompleted = true;
}

void BwcPM::setBwc(const hwc_context_t *ctx, const int& dpy,
        const private_handle_t *hnd,
        const hwc_rect_t& crop, const hwc_rect_t& dst,
        const int& transform,const int& downscale,
        ovutils::eMdpFlags& mdpFlags) {
    //Target doesnt support Bwc
    qdutils::MDPVersion& mdpHw = qdutils::MDPVersion::getInstance();
    if(not mdpHw.supportsBWC()) {
        return;
    }
    //Disabled at runtime
    if(not ctx->mBWCEnabled) return;
    //BWC not supported with rot-downscale
    if(downscale) return;
    //Not enabled for secondary displays
    if(dpy) return;
    //Not enabled for non-video buffers
    if(not isYuvBuffer(hnd)) return;

    int src_w = crop.right - crop.left;
    int src_h = crop.bottom - crop.top;
    int dst_w = dst.right - dst.left;
    int dst_h = dst.bottom - dst.top;
    if(transform & HAL_TRANSFORM_ROT_90) {
        swap(src_w, src_h);
    }
    //src width > MAX mixer supported dim
    if(src_w > (int) qdutils::MDPVersion::getInstance().getMaxPipeWidth()) {
        return;
    }
    //Decimation necessary, cannot use BWC. H/W requirement.
    if(qdutils::MDPVersion::getInstance().supportsDecimation()) {
        uint8_t horzDeci = 0;
        uint8_t vertDeci = 0;
        ovutils::getDecimationFactor(src_w, src_h, dst_w, dst_h, horzDeci,
                vertDeci);
        if(horzDeci || vertDeci) return;
    }

    ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDSS_MDP_BWC_EN);
}

void LayerRotMap::add(hwc_layer_1_t* layer, Rotator *rot) {
    if(mCount >= RotMgr::MAX_ROT_SESS) return;
    mLayer[mCount] = layer;
    mRot[mCount] = rot;
    mCount++;
}

void LayerRotMap::reset() {
    for (int i = 0; i < RotMgr::MAX_ROT_SESS; i++) {
        mLayer[i] = 0;
        mRot[i] = 0;
    }
    mCount = 0;
}

void LayerRotMap::clear() {
    RotMgr::getInstance()->markUnusedTop(mCount);
    reset();
}

bool LayerRotMap::isRotCached(uint32_t index) const {
    overlay::Rotator* rot = getRot(index);
    hwc_layer_1_t* layer =  getLayer(index);

    if(rot and layer and layer->handle) {
        private_handle_t *hnd = (private_handle_t *)(layer->handle);
        return (rot->isRotCached(hnd->fd,(uint32_t)(hnd->offset)));
    }
    return false;
}

void LayerRotMap::setReleaseFd(const int& fence) {
    for(uint32_t i = 0; i < mCount; i++) {
        if(mRot[i] and mLayer[i] and mLayer[i]->handle) {
            /* Ensure that none of the above (Rotator-instance,
             * layer and layer-handle) are NULL*/
            if(isRotCached(i))
                mRot[i]->setPrevBufReleaseFd(dup(fence));
            else
                mRot[i]->setCurrBufReleaseFd(dup(fence));
        }
    }
}

hwc_rect expandROIFromMidPoint(hwc_rect roi, hwc_rect fullFrame) {
    int lRoiWidth = 0, rRoiWidth = 0;
    int half_frame_width = fullFrame.right/2;

    hwc_rect lFrame = fullFrame;
    hwc_rect rFrame = fullFrame;
    lFrame.right = (lFrame.right - lFrame.left)/2;
    rFrame.left = lFrame.right;

    hwc_rect lRoi = getIntersection(roi, lFrame);
    hwc_rect rRoi = getIntersection(roi, rFrame);

    lRoiWidth = lRoi.right - lRoi.left;
    rRoiWidth = rRoi.right - rRoi.left;

    if(lRoiWidth && rRoiWidth) {
        if(lRoiWidth < rRoiWidth)
            roi.left = half_frame_width - rRoiWidth;
        else
            roi.right = half_frame_width + lRoiWidth;
    }
    return roi;
}

void resetROI(hwc_context_t *ctx, const int dpy) {
    const int fbXRes = (int)ctx->dpyAttr[dpy].xres;
    const int fbYRes = (int)ctx->dpyAttr[dpy].yres;
    if(isDisplaySplit(ctx, dpy)) {
        const int lSplit = getLeftSplit(ctx, dpy);
        ctx->listStats[dpy].lRoi = (struct hwc_rect){0, 0, lSplit, fbYRes};
        ctx->listStats[dpy].rRoi = (struct hwc_rect){lSplit, 0, fbXRes, fbYRes};
    } else  {
        ctx->listStats[dpy].lRoi = (struct hwc_rect){0, 0,fbXRes, fbYRes};
        ctx->listStats[dpy].rRoi = (struct hwc_rect){0, 0, 0, 0};
    }
}

hwc_rect_t getSanitizeROI(struct hwc_rect roi, hwc_rect boundary)
{
   if(!isValidRect(roi))
      return roi;

   struct hwc_rect t_roi = roi;

   const int LEFT_ALIGN = qdutils::MDPVersion::getInstance().getLeftAlign();
   const int WIDTH_ALIGN = qdutils::MDPVersion::getInstance().getWidthAlign();
   const int TOP_ALIGN = qdutils::MDPVersion::getInstance().getTopAlign();
   const int HEIGHT_ALIGN = qdutils::MDPVersion::getInstance().getHeightAlign();
   const int MIN_WIDTH = qdutils::MDPVersion::getInstance().getMinROIWidth();
   const int MIN_HEIGHT = qdutils::MDPVersion::getInstance().getMinROIHeight();

   /* Align to minimum width recommended by the panel */
   if((t_roi.right - t_roi.left) < MIN_WIDTH) {
       if((t_roi.left + MIN_WIDTH) > boundary.right)
           t_roi.left = t_roi.right - MIN_WIDTH;
       else
           t_roi.right = t_roi.left + MIN_WIDTH;
   }

  /* Align to minimum height recommended by the panel */
   if((t_roi.bottom - t_roi.top) < MIN_HEIGHT) {
       if((t_roi.top + MIN_HEIGHT) > boundary.bottom)
           t_roi.top = t_roi.bottom - MIN_HEIGHT;
       else
           t_roi.bottom = t_roi.top + MIN_HEIGHT;
   }

   /* Align left and width to meet panel restrictions */
   if(LEFT_ALIGN)
       t_roi.left = t_roi.left - (t_roi.left % LEFT_ALIGN);

   if(WIDTH_ALIGN) {
       int width = t_roi.right - t_roi.left;
       width = WIDTH_ALIGN * ((width + (WIDTH_ALIGN - 1)) / WIDTH_ALIGN);
       t_roi.right = t_roi.left + width;

       if(t_roi.right > boundary.right) {
           t_roi.right = boundary.right;
           t_roi.left = t_roi.right - width;

           if(LEFT_ALIGN)
               t_roi.left = t_roi.left - (t_roi.left % LEFT_ALIGN);
       }
   }


   /* Align top and height to meet panel restrictions */
   if(TOP_ALIGN)
       t_roi.top = t_roi.top - (t_roi.top % TOP_ALIGN);

   if(HEIGHT_ALIGN) {
       int height = t_roi.bottom - t_roi.top;
       height = HEIGHT_ALIGN *  ((height + (HEIGHT_ALIGN - 1)) / HEIGHT_ALIGN);
       t_roi.bottom = t_roi.top  + height;

       if(t_roi.bottom > boundary.bottom) {
           t_roi.bottom = boundary.bottom;
           t_roi.top = t_roi.bottom - height;

           if(TOP_ALIGN)
               t_roi.top = t_roi.top - (t_roi.top % TOP_ALIGN);
       }
   }


   return t_roi;
}

void handle_pause(hwc_context_t* ctx, int dpy) {
    if(ctx->dpyAttr[dpy].connected) {
        ctx->mDrawLock.lock();
        ctx->dpyAttr[dpy].isActive = true;
        ctx->dpyAttr[dpy].isPause = true;
        ctx->mDrawLock.unlock();
        ctx->proc->invalidate(ctx->proc);

        usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
               * 2 / 1000);

        // At this point all the pipes used by External have been
        // marked as UNSET.
        ctx->mDrawLock.lock();
        // Perform commit to unstage the pipes.
        if (!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
            ALOGE("%s: display commit fail! for %d dpy",
                  __FUNCTION__, dpy);
        }
        ctx->mDrawLock.unlock();
        ctx->proc->invalidate(ctx->proc);
    }
    return;
}

void handle_resume(hwc_context_t* ctx, int dpy) {
    if(ctx->dpyAttr[dpy].connected) {
        ctx->mDrawLock.lock();
        ctx->dpyAttr[dpy].isConfiguring = true;
        ctx->dpyAttr[dpy].isActive = true;
        ctx->mDrawLock.unlock();
        ctx->proc->invalidate(ctx->proc);

        usleep(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].vsync_period
               * 2 / 1000);

        //At this point external has all the pipes it would need.
        ctx->mDrawLock.lock();
        ctx->dpyAttr[dpy].isPause = false;
        ctx->mDrawLock.unlock();
        ctx->proc->invalidate(ctx->proc);
    }
    return;
}

void clearPipeResources(hwc_context_t* ctx, int dpy) {
    if(ctx->mOverlay) {
        ctx->mOverlay->configBegin();
        ctx->mOverlay->configDone();
    }
    if(ctx->mRotMgr) {
        ctx->mRotMgr->clear();
    }
    // Call a display commit to ensure that pipes and associated
    // fd's are cleaned up.
    if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd)) {
        ALOGE("%s: display commit failed for  %d", __FUNCTION__, dpy);
    }
}

// Handles online events when HDMI is the primary display. In particular,
// online events for hdmi connected before AND after boot up and HWC init.
void handle_online(hwc_context_t* ctx, int dpy) {
    // Close the current fd if it was opened earlier on when HWC
    // was initialized.
    if (ctx->dpyAttr[dpy].fd >= 0) {
        close(ctx->dpyAttr[dpy].fd);
        ctx->dpyAttr[dpy].fd = -1;
    }
    // TODO: If HDMI is connected after the display has booted up,
    // and the best configuration is different from the default
    // then we need to deal with this appropriately.
    ctx->mHDMIDisplay->configure();
    updateDisplayInfo(ctx, dpy);
    initCompositionResources(ctx, dpy);
    ctx->dpyAttr[dpy].connected = true;
}

// Handles offline events for HDMI. This can be used for offline events
// initiated by the HDMI driver and the CEC framework.
void handle_offline(hwc_context_t* ctx, int dpy) {
    destroyCompositionResources(ctx, dpy);
    // Clear all pipe resources and call a display commit to ensure
    // that all the fd's are closed. This will ensure that the HDMI
    // core turns off and that we receive an event the next time the
    // cable is connected.
    if (ctx->mHDMIDisplay->isHDMIPrimaryDisplay()) {
        clearPipeResources(ctx, dpy);
    }
    ctx->mHDMIDisplay->teardown();
    resetDisplayInfo(ctx, dpy);
    ctx->dpyAttr[dpy].connected = false;
    ctx->dpyAttr[dpy].isActive = false;
}

int convertS3DFormatToMode(int s3DFormat) {
    int ret;
    switch(s3DFormat) {
    case HAL_3D_SIDE_BY_SIDE_L_R:
    case HAL_3D_SIDE_BY_SIDE_R_L:
        ret = HDMI_S3D_SIDE_BY_SIDE;
        break;
    case HAL_3D_TOP_BOTTOM:
        ret = HDMI_S3D_TOP_AND_BOTTOM;
        break;
    default:
        ret = HDMI_S3D_NONE;
    }
    return ret;
}

bool needs3DComposition(hwc_context_t* ctx, int dpy) {
    return (displaySupports3D(ctx, dpy) && ctx->dpyAttr[dpy].connected &&
            ctx->dpyAttr[dpy].s3dMode != HDMI_S3D_NONE);
}

void setup3DMode(hwc_context_t *ctx, int dpy, int s3dMode) {
    if (ctx->dpyAttr[dpy].s3dMode != s3dMode) {
        ALOGD("%s: setup 3D mode: %d", __FUNCTION__, s3dMode);
        if(ctx->mHDMIDisplay->configure3D(s3dMode)) {
            ctx->dpyAttr[dpy].s3dMode = s3dMode;
        }
    }
}

bool displaySupports3D(hwc_context_t* ctx, int dpy) {
    return ((dpy == HWC_DISPLAY_EXTERNAL) ||
            ((dpy == HWC_DISPLAY_PRIMARY) &&
             ctx->mHDMIDisplay->isHDMIPrimaryDisplay()));
}


};//namespace qhwc
