/*
 * 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>

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  "hw.sf.app_buff_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;
    }

    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();

    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++;
            }
        }
        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
    }
    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 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;
}

};//namespace qhwc
