Merge "liboverlay: Set mdp src format as rotator output format."
diff --git a/Android.mk b/Android.mk
index 1e8cdda..b62e45b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,7 +1,10 @@
-ifeq ($(call is-vendor-board-platform,QCOM),true)
-
 display-hals := libgralloc libgenlock libcopybit liblight
 display-hals += libhwcomposer liboverlay libqdutils libexternal libqservice
-
-include $(call all-named-subdir-makefiles,$(display-hals))
+ifeq ($(call is-vendor-board-platform,QCOM),true)
+    include $(call all-named-subdir-makefiles,$(display-hals))
+else
+ifneq ($(filter msm8960,$(TARGET_BOARD_PLATFORM)),)
+    #This is for mako since it doesn't have the QCOM make functions
+    include $(call all-named-subdir-makefiles,$(display-hals))
+endif
 endif
diff --git a/common.mk b/common.mk
index ebfc8ec..78b48dd 100644
--- a/common.mk
+++ b/common.mk
@@ -32,8 +32,9 @@
 common_deps  :=
 kernel_includes :=
 
-#Kernel includes. Not being executed on JB+
+# Executed only on QCOM BSPs
 ifeq ($(call is-vendor-board-platform,QCOM),true)
+    common_flags += -DQCOM_BSP
     common_deps += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr
     kernel_includes += $(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ/usr/include
 endif
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index b721195..1c8f170 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -85,6 +85,7 @@
     openFrameBuffer(mHdmiFbNum);
     if(mFd == -1)
         return -1;
+    readCEUnderscanInfo();
     readResolution();
     // TODO: Move this to activate
     /* Used for changing the resolution
@@ -167,7 +168,7 @@
 
 ExternalDisplay::ExternalDisplay(hwc_context_t* ctx):mFd(-1),
     mCurrentMode(-1), mConnected(0), mConnectedFbNum(0), mModeCount(0),
-    mHwcContext(ctx), mHdmiFbNum(-1), mWfdFbNum(-1)
+     mUnderscanSupported(false), mHwcContext(ctx), mHdmiFbNum(-1), mWfdFbNum(-1)
 {
     memset(&mVInfo, 0, sizeof(mVInfo));
     //Determine the fb index for external display devices.
@@ -193,7 +194,12 @@
 void ExternalDisplay::setActionSafeDimension(int w, int h) {
     ALOGD_IF(DEBUG,"ActionSafe w=%d h=%d", w, h);
     Mutex::Autolock lock(mExtDispLock);
-    overlay::utils::ActionSafe::getInstance()->setDimension(w, h);
+    char actionsafeWidth[PROPERTY_VALUE_MAX];
+    char actionsafeHeight[PROPERTY_VALUE_MAX];
+    sprintf(actionsafeWidth, "%d", w);
+    property_set("hw.actionsafe.width", actionsafeWidth);
+    sprintf(actionsafeHeight, "%d", h);
+    property_set("hw.actionsafe.height", actionsafeHeight);
     setExternalDisplay(true, mHdmiFbNum);
 }
 
@@ -210,6 +216,75 @@
     }
 }
 
+void ExternalDisplay::readCEUnderscanInfo()
+{
+    int hdmiScanInfoFile = -1;
+    int len = -1;
+    char scanInfo[17];
+    char *ce_info_str = NULL;
+    const char token[] = ", \n";
+    int ce_info = -1;
+    char sysFsScanInfoFilePath[128];
+    sprintf(sysFsScanInfoFilePath, "/sys/devices/virtual/graphics/fb%d/"
+                                   "scan_info", mHdmiFbNum);
+
+    memset(scanInfo, 0, sizeof(scanInfo));
+    hdmiScanInfoFile = open(sysFsScanInfoFilePath, O_RDONLY, 0);
+    if (hdmiScanInfoFile < 0) {
+        ALOGD_IF(DEBUG, "%s: scan_info file '%s' not found",
+                                __FUNCTION__, sysFsScanInfoFilePath);
+        return;
+    } else {
+        len = read(hdmiScanInfoFile, scanInfo, sizeof(scanInfo)-1);
+        ALOGD("%s: Scan Info string: %s length = %d",
+                 __FUNCTION__, scanInfo, len);
+        if (len <= 0) {
+            close(hdmiScanInfoFile);
+            ALOGE("%s: Scan Info file empty '%s'",
+                                __FUNCTION__, sysFsScanInfoFilePath);
+            return;
+        }
+        scanInfo[len] = '\0';  /* null terminate the string */
+    }
+    close(hdmiScanInfoFile);
+
+    /*
+     * The scan_info contains the three fields
+     * PT - preferred video format
+     * IT - video format
+     * CE video format - containing the underscan support information
+     */
+
+    /* PT */
+    ce_info_str = strtok(scanInfo, token);
+    if (ce_info_str) {
+        /* IT */
+        ce_info_str = strtok(NULL, token);
+        if (ce_info_str) {
+            /* CE */
+            ce_info_str = strtok(NULL, token);
+            if (ce_info_str)
+                ce_info = atoi(ce_info_str);
+        }
+    }
+
+    if (ce_info_str) {
+        // ce_info contains the underscan information
+        if (ce_info == EXT_SCAN_ALWAYS_UNDERSCANED ||
+            ce_info == EXT_SCAN_BOTH_SUPPORTED)
+            // if TV supported underscan, then driver will always underscan
+            // hence no need to apply action safe rectangle
+            mUnderscanSupported = true;
+    } else {
+        ALOGE("%s: scan_info string error", __FUNCTION__);
+    }
+
+    // Store underscan support info in a system property
+    const char* prop = (mUnderscanSupported) ? "1" : "0";
+    property_set("hw.underscan_supported", prop);
+    return;
+}
+
 ExternalDisplay::~ExternalDisplay()
 {
     closeFrameBuffer();
@@ -393,6 +468,10 @@
     memset(mEDIDModes, 0, sizeof(mEDIDModes));
     mModeCount = 0;
     mCurrentMode = -1;
+    mUnderscanSupported = false;
+    // Reset the underscan supported system property
+    const char* prop = "0";
+    property_set("hw.underscan_supported", prop);
 }
 
 int ExternalDisplay::getModeOrder(int mode)
@@ -446,7 +525,7 @@
     int mode = atoi(property_value);
     // We dont support interlaced modes
     if(isValidMode(mode) && !isInterlacedMode(mode)) {
-        ALOGD_IF("%s: setting the HDMI mode = %d", __FUNCTION__, mode);
+        ALOGD_IF(DEBUG, "%s: setting the HDMI mode = %d", __FUNCTION__, mode);
         return mode;
     }
     return -1;
@@ -528,16 +607,10 @@
         mode->set_info(mVInfo);
         ALOGD_IF(DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx %d"
                  "(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, ID,
-                 mVInfo.reserved[3], mVInfo.xres, mVInfo.yres,
+                 mode->video_format, mVInfo.xres, mVInfo.yres,
                  mVInfo.right_margin, mVInfo.hsync_len, mVInfo.left_margin,
                  mVInfo.lower_margin, mVInfo.vsync_len, mVInfo.upper_margin,
                  mVInfo.pixclock/1000/1000);
-        mVInfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE;
-        ret = ioctl(mFd, FBIOPUT_VSCREENINFO, &mVInfo);
-        if(ret < 0) {
-            ALOGD("In %s: FBIOPUT_VSCREENINFO failed Err Str = %s",
-                                                 __FUNCTION__, strerror(errno));
-        }
 #ifdef FB_METADATA_VIDEO_INFO_CODE_SUPPORT
         struct msmfb_metadata metadata;
         memset(&metadata, 0 , sizeof(metadata));
@@ -548,6 +621,12 @@
                                                  __FUNCTION__, strerror(errno));
         }
 #endif
+        mVInfo.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_ALL | FB_ACTIVATE_FORCE;
+        ret = ioctl(mFd, FBIOPUT_VSCREENINFO, &mVInfo);
+        if(ret < 0) {
+            ALOGD("In %s: FBIOPUT_VSCREENINFO failed Err Str = %s",
+                                                 __FUNCTION__, strerror(errno));
+        }
         mCurrentMode = ID;
     }
 }
diff --git a/libexternal/external.h b/libexternal/external.h
index d85ce44..baf3598 100644
--- a/libexternal/external.h
+++ b/libexternal/external.h
@@ -28,6 +28,13 @@
 
 namespace qhwc {
 
+//Type of scanning of EDID(Video Capability Data Block)
+enum external_scansupport_type {
+    EXT_SCAN_NOT_SUPPORTED      = 0,
+    EXT_SCAN_ALWAYS_OVERSCANED  = 1,
+    EXT_SCAN_ALWAYS_UNDERSCANED = 2,
+    EXT_SCAN_BOTH_SUPPORTED     = 3
+};
 
 class ExternalDisplay
 {
@@ -36,6 +43,7 @@
     ~ExternalDisplay();
     int getModeCount() const;
     void getEDIDModes(int *out) const;
+    bool isCEUnderscanSupported() { return mUnderscanSupported; }
     void setExternalDisplay(bool connected, int extFbNum = 0);
     bool isExternalConnected() { return mConnected;};
     bool post();
@@ -46,6 +54,7 @@
     void processUEventOffline(const char *str);
 
 private:
+    void readCEUnderscanInfo();
     bool readResolution();
     int  parseResolution(char* edidStr, int* edidModes);
     void setResolution(int ID);
@@ -78,6 +87,7 @@
     char mEDIDs[128];
     int mEDIDModes[64];
     int mModeCount;
+    bool mUnderscanSupported;
     hwc_context_t *mHwcContext;
     fb_var_screeninfo mVInfo;
     int mHdmiFbNum;
diff --git a/libgralloc/alloc_controller.cpp b/libgralloc/alloc_controller.cpp
index 6fb520d..6003688 100644
--- a/libgralloc/alloc_controller.cpp
+++ b/libgralloc/alloc_controller.cpp
@@ -114,8 +114,10 @@
         noncontig = true;
     }
 
-    if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP)
+    if(usage & GRALLOC_USAGE_PRIVATE_IOMMU_HEAP) {
         ionFlags |= ION_HEAP(ION_IOMMU_HEAP_ID);
+        noncontig = true;
+    }
 
     if(usage & GRALLOC_USAGE_PRIVATE_MM_HEAP)
         ionFlags |= ION_HEAP(ION_CP_MM_HEAP_ID);
@@ -123,7 +125,7 @@
     if(usage & GRALLOC_USAGE_PRIVATE_CAMERA_HEAP)
         ionFlags |= ION_HEAP(ION_CAMERA_HEAP_ID);
 
-    if(usage & GRALLOC_USAGE_PROTECTED)
+    if(usage & GRALLOC_USAGE_PROTECTED && !noncontig)
         ionFlags |= ION_SECURE;
 
     // if no flags are set, default to
diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
index 45a2749..ab36830 100644
--- a/libgralloc/framebuffer.cpp
+++ b/libgralloc/framebuffer.cpp
@@ -86,24 +86,15 @@
 
 static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)
 {
-
-    fb_context_t* ctx = (fb_context_t*) dev;
-
-    private_handle_t *hnd = static_cast<private_handle_t*>
-            (const_cast<native_handle_t*>(buffer));
     private_module_t* m =
         reinterpret_cast<private_module_t*>(dev->common.module);
-
-    if (hnd) {
-        m->info.activate = FB_ACTIVATE_VBL | FB_ACTIVATE_FORCE;
-        m->info.yoffset = hnd->offset / m->finfo.line_length;
-        m->commit.var = m->info;
-        m->commit.flags |= MDP_DISPLAY_COMMIT_OVERLAY;
-        if (ioctl(m->framebuffer->fd, MSMFB_DISPLAY_COMMIT, &m->commit) == -1) {
-            ALOGE("%s: MSMFB_DISPLAY_COMMIT ioctl failed, err: %s", __FUNCTION__,
-                    strerror(errno));
-            return -errno;
-        }
+    struct mdp_display_commit prim_commit;
+    memset(&prim_commit, 0, sizeof(struct mdp_display_commit));
+    prim_commit.flags = MDP_DISPLAY_COMMIT_OVERLAY;
+    if (ioctl(m->framebuffer->fd, MSMFB_DISPLAY_COMMIT, &prim_commit) == -1) {
+        ALOGE("%s: MSMFB_DISPLAY_COMMIT for primary failed, str: %s",
+                __FUNCTION__, strerror(errno));
+        return -errno;
     }
     return 0;
 }
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index 3bacdbf..f1af045 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -47,7 +47,9 @@
     common.module  = const_cast<hw_module_t*>(&module->base.common);
     common.close   = gralloc_close;
     alloc          = gralloc_alloc;
+#ifdef QCOM_BSP
     allocSize      = gralloc_alloc_size;
+#endif
     free           = gralloc_free;
 
 }
diff --git a/libgralloc/gralloc_priv.h b/libgralloc/gralloc_priv.h
index ea3fcdc..2c50e77 100644
--- a/libgralloc/gralloc_priv.h
+++ b/libgralloc/gralloc_priv.h
@@ -84,8 +84,7 @@
 enum {
     /* Gralloc perform enums
     */
-    GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER =
-                                    GRALLOC_MODULE_PERFORM_PRIVATE_START,
+    GRALLOC_MODULE_PERFORM_CREATE_HANDLE_FROM_BUFFER = 1,
 };
 
 #define GRALLOC_HEAP_MASK   (GRALLOC_USAGE_PRIVATE_UI_CONTIG_HEAP |\
diff --git a/libgralloc/ionalloc.cpp b/libgralloc/ionalloc.cpp
index 7aec73f..49e687e 100644
--- a/libgralloc/ionalloc.cpp
+++ b/libgralloc/ionalloc.cpp
@@ -40,6 +40,9 @@
 using gralloc::IonAlloc;
 
 #define ION_DEVICE "/dev/ion"
+#ifdef QCOM_BSP
+#define NEW_ION_API
+#endif
 
 int IonAlloc::open_device()
 {
@@ -66,6 +69,10 @@
 {
     Locker::Autolock _l(mLock);
     int err = 0;
+#ifndef NEW_ION_API
+    int ionSyncFd = FD_INIT;
+    int iFd = FD_INIT;
+#endif
     struct ion_handle_data handle_data;
     struct ion_fd_data fd_data;
     struct ion_allocation_data ionAllocData;
@@ -73,9 +80,12 @@
 
     ionAllocData.len = data.size;
     ionAllocData.align = data.align;
+#ifndef NEW_ION_API
+    ionAllocData.flags = data.flags;
+#else
     ionAllocData.heap_mask = data.flags & ~ION_SECURE;
     ionAllocData.flags = data.uncached ? 0 : ION_FLAG_CACHED;
-
+#endif
     // ToDo: replace usage of alloc data structure with
     //  ionallocdata structure.
     if (data.flags & ION_SECURE)
@@ -84,10 +94,32 @@
     err = open_device();
     if (err)
         return err;
+#ifndef NEW_ION_API
+    if(data.uncached) {
+        // Use the sync FD to alloc and map 93
+        // when we need uncached memory 94
+        ionSyncFd = open(ION_DEVICE, O_RDONLY|O_DSYNC);
+        if(ionSyncFd < 0) {
+            ALOGE("%s: Failed to open ion device - %s",
+                  __FUNCTION__, strerror(errno));
+            return -errno;
+        }
+        iFd = ionSyncFd;
+    } else {
+        iFd = mIonFd;
+    }
 
+    if(ioctl(iFd, ION_IOC_ALLOC, &ionAllocData)) {
+#else
     if(ioctl(mIonFd, ION_IOC_ALLOC, &ionAllocData)) {
+#endif
         err = -errno;
         ALOGE("ION_IOC_ALLOC failed with error - %s", strerror(errno));
+#ifndef NEW_ION_API
+        if(ionSyncFd >= 0)
+            close(ionSyncFd);
+        ionSyncFd = FD_INIT;
+#endif
         return err;
     }
 
@@ -203,11 +235,15 @@
     flush_data.offset  = offset;
     flush_data.length  = size;
 
+#ifdef NEW_ION_API
     struct ion_custom_data d;
     d.cmd = ION_IOC_CLEAN_INV_CACHES;
     d.arg = (unsigned long int)&flush_data;
 
     if(ioctl(mIonFd, ION_IOC_CUSTOM, &d)) {
+#else
+    if(ioctl(mIonFd, ION_IOC_CLEAN_INV_CACHES, &flush_data)) {
+#endif
         err = -errno;
         ALOGE("%s: ION_IOC_CLEAN_INV_CACHES failed with error - %s",
 
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index b8e1526..4f28877 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -353,6 +353,7 @@
                 break;
 
             }
+#ifdef QCOM_BSP
         case GRALLOC_MODULE_PERFORM_UPDATE_BUFFER_GEOMETRY:
             {
                 int width = va_arg(args, int);
@@ -368,6 +369,7 @@
                 res = 0;
             }
             break;
+#endif
         default:
             break;
     }
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index 130f263..6a0e0ee 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -332,10 +332,10 @@
                     ret = -1;
                 }
             }
-            if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) {
-                ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__);
-                return -1;
-            }
+        }
+        if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) {
+            ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__);
+            return -1;
         }
     }
     return ret;
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index e764c69..8ce9f0d 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -24,6 +24,11 @@
 #include "hwc_copybit.h"
 #include "comptype.h"
 
+//XXX: Remove HWC_BLIT
+#ifndef QCOM_BSP
+#define HWC_BLIT 4
+#endif
+
 namespace qhwc {
 
 struct range {
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 18f75eb..a0dbbe3 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -104,6 +104,9 @@
                 displayFrame.top,
                 displayFrame.right - displayFrame.left,
                 displayFrame.bottom - displayFrame.top);
+        // Calculate the actionsafe dimensions for External(dpy = 1 or 2)
+        if(mDpy)
+            getActionSafePosition(ctx, mDpy, dpos.x, dpos.y, dpos.w, dpos.h);
         ov.setPosition(dpos, dest);
 
         ret = true;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 760b134..3a241c8 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -222,6 +222,45 @@
     }
 }
 
+bool MDPCompLowRes::isWidthValid(hwc_context_t *ctx, hwc_layer_1_t *layer) {
+
+    const int dpy = HWC_DISPLAY_PRIMARY;
+    private_handle_t *hnd = (private_handle_t *)layer->handle;
+
+    if(!hnd) {
+        ALOGE("%s: layer handle is NULL", __FUNCTION__);
+        return false;
+    }
+
+    int hw_w = ctx->dpyAttr[dpy].xres;
+    int hw_h = ctx->dpyAttr[dpy].yres;
+
+    hwc_rect_t sourceCrop = layer->sourceCrop;
+    hwc_rect_t displayFrame = layer->displayFrame;
+
+    hwc_rect_t crop =  sourceCrop;
+    int crop_w = crop.right - crop.left;
+    int crop_h = crop.bottom - crop.top;
+
+    hwc_rect_t dst = displayFrame;
+    int dst_w = dst.right - dst.left;
+    int dst_h = dst.bottom - dst.top;
+
+    if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) {
+       qhwc::calculate_crop_rects(crop, dst, hw_w, hw_h, layer->transform);
+       crop_w = crop.right - crop.left;
+       crop_h = crop.bottom - crop.top;
+    }
+
+    //Workaround for MDP HW limitation in DSI command mode panels where
+    //FPS will not go beyond 30 if buffers on RGB pipes are of width < 5
+
+    if(crop_w < 5)
+        return false;
+
+    return true;
+}
+
 /*
  * Configures pipe(s) for MDP composition
  */
@@ -379,7 +418,7 @@
     overlay::Overlay& ov = *ctx->mOverlay;
     int availablePipes = ov.availablePipes(dpy);
 
-    if(numAppLayers < 1 || numAppLayers > (uint32_t)availablePipes) {
+    if(numAppLayers < 1 || numAppLayers > availablePipes) {
         ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
         return false;
     }
@@ -416,6 +455,7 @@
         return false;
     }
 
+
     //MDP composition is not efficient if layer needs rotator.
     for(int i = 0; i < numAppLayers; ++i) {
         // As MDP h/w supports flip operation, use MDP comp only for
@@ -426,6 +466,9 @@
             ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
             return false;
         }
+
+        if(!isYuvBuffer(hnd) && !isWidthValid(ctx,layer))
+            return false;
     }
     return true;
 }
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 48c3779..9ae9b2e 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -105,6 +105,8 @@
         struct PipeLayerPair* pipeLayer;
 
     };
+    /* checks for mdp comp width limitation */
+    bool isWidthValid(hwc_context_t *ctx, hwc_layer_1_t *layer);
     /* configure's overlay pipes for the frame */
     int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
                         MdpPipeInfo& mdp_info);
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index e1f413c..093c0b3 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -148,6 +148,55 @@
     va_end(varargs);
 }
 
+/* Calculates the destination position based on the action safe rectangle */
+void getActionSafePosition(hwc_context_t *ctx, int dpy, uint32_t& x,
+                           uint32_t& y, uint32_t& w, uint32_t& h) {
+
+    // if external supports underscan, do nothing
+    // it will be taken care in the driver
+    if(ctx->mExtDisplay->isCEUnderscanSupported())
+        return;
+
+    float wRatio = 1.0;
+    float hRatio = 1.0;
+    float xRatio = 1.0;
+    float yRatio = 1.0;
+
+    float fbWidth = ctx->dpyAttr[dpy].xres;
+    float fbHeight = ctx->dpyAttr[dpy].yres;
+
+    float asX = 0;
+    float asY = 0;
+    float asW = fbWidth;
+    float asH= fbHeight;
+    char value[PROPERTY_VALUE_MAX];
+
+    // Apply action safe parameters
+    property_get("hw.actionsafe.width", value, "0");
+    int asWidthRatio = atoi(value);
+    property_get("hw.actionsafe.height", value, "0");
+    int asHeightRatio = atoi(value);
+    // based on the action safe ratio, get the Action safe rectangle
+    asW = fbWidth * (1.0f -  asWidthRatio / 100.0f);
+    asH = fbHeight * (1.0f -  asHeightRatio / 100.0f);
+    asX = (fbWidth - asW) / 2;
+    asY = (fbHeight - asH) / 2;
+
+    // calculate the position ratio
+    xRatio = (float)x/fbWidth;
+    yRatio = (float)y/fbHeight;
+    wRatio = (float)w/fbWidth;
+    hRatio = (float)h/fbHeight;
+
+    //Calculate the position...
+    x = (xRatio * asW) + asX;
+    y = (yRatio * asH) + asY;
+    w = (wRatio * asW);
+    h = (hRatio * asH);
+
+    return;
+}
+
 static inline bool isAlphaScaled(hwc_layer_1_t const* layer) {
     int dst_w, dst_h, src_w, src_h;
 
@@ -188,16 +237,14 @@
         //We disregard FB being skip for now! so the else if
         } else if (isSkipLayer(&list->hwLayers[i])) {
             ctx->listStats[dpy].skipCount++;
-        }
-
-        if(!ctx->listStats[dpy].needsAlphaScale)
-            ctx->listStats[dpy].needsAlphaScale = isAlphaScaled(layer);
-
-        if (UNLIKELY(isYuvBuffer(hnd))) {
+        } else if (UNLIKELY(isYuvBuffer(hnd))) {
             int& yuvCount = ctx->listStats[dpy].yuvCount;
             ctx->listStats[dpy].yuvIndices[yuvCount] = i;
             yuvCount++;
         }
+
+        if(!ctx->listStats[dpy].needsAlphaScale)
+            ctx->listStats[dpy].needsAlphaScale = isAlphaScaled(layer);
     }
 }
 
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 9692986..c66f7ff 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -136,6 +136,10 @@
 //Helper function to dump logs
 void dumpsys_log(android::String8& buf, const char* fmt, ...);
 
+/* Calculates the destination position based on the action safe rectangle */
+void getActionSafePosition(hwc_context_t *ctx, int dpy, uint32_t& x,
+                                        uint32_t& y, uint32_t& w, uint32_t& h);
+
 //Sync point impl.
 int hwc_sync(hwc_context_t *ctx, hwc_display_contents_1_t* list, int dpy,
                                                     int fd);
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
index 0c0a40d..6abc7ae 100644
--- a/libhwcomposer/hwc_video.cpp
+++ b/libhwcomposer/hwc_video.cpp
@@ -171,6 +171,10 @@
             displayFrame.top,
             displayFrame.right - displayFrame.left,
             displayFrame.bottom - displayFrame.top);
+    // Calculate the actionsafe dimensions for External(dpy = 1 or 2)
+    if(dpy)
+        getActionSafePosition(ctx, dpy, dpos.x, dpos.y, dpos.w, dpos.h);
+
     ov.setPosition(dpos, dest);
 
     if (!ov.commit(dest)) {
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 151cfb3..a470f45 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -133,8 +133,6 @@
     /* Dump string */
     char mDumpStr[256];
 
-    mutable android::Mutex mOvExtFbLock;
-
     /* Singleton Instance*/
     static Overlay *sInstance;
     static int sExtFbIndex;
@@ -159,12 +157,10 @@
 }
 
 inline void Overlay::setExtFbNum(int fbNum) {
-    android::Mutex::Autolock lock(mOvExtFbLock);
     sExtFbIndex = fbNum;
 }
 
 inline int Overlay::getExtFbNum() {
-    android::Mutex::Autolock lock(mOvExtFbLock);
     return sExtFbIndex;
 }
 
diff --git a/liboverlay/overlayCtrl.cpp b/liboverlay/overlayCtrl.cpp
index 03d2564..2cbf1c5 100644
--- a/liboverlay/overlayCtrl.cpp
+++ b/liboverlay/overlayCtrl.cpp
@@ -79,8 +79,6 @@
     return true;
 }
 
-utils::ActionSafe* utils::ActionSafe::sActionSafe = NULL;
-
 utils::FrameBufferInfo* utils::FrameBufferInfo::sFBInfoInstance = 0;
 
 void Ctrl::dump() const {
diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp
index 6ee9e4b..d9cdc03 100644
--- a/liboverlay/overlayMdssRot.cpp
+++ b/liboverlay/overlayMdssRot.cpp
@@ -265,10 +265,22 @@
 }
 
 void MdssRot::setBufSize(int format) {
-    if (format == MDP_Y_CBCR_H2V2_VENUS) {
-        mBufSize = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, mRotInfo.dst_rect.w,
-                                     mRotInfo.dst_rect.h);
+
+    switch (format) {
+        case MDP_Y_CBCR_H2V2_VENUS:
+            mBufSize = VENUS_BUFFER_SIZE(COLOR_FMT_NV12, mRotInfo.dst_rect.w,
+                                         mRotInfo.dst_rect.h);
+            break;
+
+        case MDP_Y_CR_CB_GH2V2:
+            int alignedw = utils::align(mRotInfo.dst_rect.w, 16);
+            int alignedh = mRotInfo.dst_rect.h;
+            mBufSize = (alignedw*alignedh) +
+                (utils::align(alignedw/2, 16) * (alignedh/2))*2;
+            mBufSize = utils::align(mBufSize, 4096);
+            break;
     }
+
     if (mRotInfo.flags & utils::OV_MDP_SECURE_OVERLAY_SESSION)
         mBufSize = utils::align(mBufSize, SIZE_1M);
 }
diff --git a/liboverlay/overlayUtils.cpp b/liboverlay/overlayUtils.cpp
index 49a1eaf..9bffff0 100644
--- a/liboverlay/overlayUtils.cpp
+++ b/liboverlay/overlayUtils.cpp
@@ -330,6 +330,11 @@
     return fmt3D;
 }
 
+bool isMdssRotator() {
+    int mdpVersion = qdutils::MDPVersion::getInstance().getMDPVersion();
+    return (mdpVersion >= qdutils::MDSS_V5);
+}
+
 } // utils
 
 } // overlay
diff --git a/liboverlay/overlayUtils.h b/liboverlay/overlayUtils.h
index 6f06b0d..2f83374 100644
--- a/liboverlay/overlayUtils.h
+++ b/liboverlay/overlayUtils.h
@@ -178,6 +178,7 @@
 bool send3DInfoPacket (uint32_t fmt);
 bool enableBarrier (uint32_t orientation);
 uint32_t getS3DFormat(uint32_t fmt);
+bool isMdssRotator();
 
 template <int CHAN>
 bool getPositionS3D(const Whf& whf, Dim& out);
@@ -245,28 +246,6 @@
     uint32_t size;
 };
 
-class ActionSafe {
-private:
-    ActionSafe() : mWidth(0.0f), mHeight(0.0f) { };
-    float mWidth;
-    float mHeight;
-    static ActionSafe *sActionSafe;
-public:
-    ~ActionSafe() { };
-    static ActionSafe* getInstance() {
-        if(!sActionSafe) {
-            sActionSafe = new ActionSafe();
-        }
-        return sActionSafe;
-    }
-    void setDimension(int w, int h) {
-        mWidth = (float)w;
-        mHeight = (float)h;
-    }
-    float getWidth() { return mWidth; }
-    float getHeight() { return mHeight; }
-};
-
 enum { MAX_PATH_LEN = 256 };
 
 /**
@@ -609,6 +588,10 @@
 }
 
 inline int getRotOutFmt(uint32_t format) {
+
+    if (isMdssRotator())
+        return format;
+
     switch (format) {
         case MDP_Y_CRCB_H2V2_TILE:
             return MDP_Y_CRCB_H2V2;