libhwcomposer: Add support for 4 layer MDP Comp

This change extends MDP composition to support
upto 4 layers by making border fill as base pipe and
using all MDP h/w pipes in overlay mode.

Conflicts:

	libhwcomposer/hwc.cpp
	libhwcomposer/hwc_utils.cpp
	libhwcomposer/hwc_utils.h

Bug: 7626586
Change-Id: I01a0e53ddfbcf3ed46734f6f3bb0ef7d912ceac6
Signed-off-by: Jeykumar Sankaran <jsanka@codeaurora.org>
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index f00d551..a05ea16 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -445,13 +445,17 @@
  */
 bool ExternalDisplay::post()
 {
-    if(mFd == -1) {
+    if(mFd == -1)
         return false;
-    } else if(ioctl(mFd, MSMFB_OVERLAY_COMMIT, &mExternalDisplay) == -1) {
-         ALOGE("%s: MSMFB_OVERLAY_COMMIT failed, str: %s", __FUNCTION__,
-                                                          strerror(errno));
+
+    struct mdp_display_commit ext_commit;
+    ext_commit.flags |= MDP_DISPLAY_COMMIT_OVERLAY;
+    if (ioctl(mFd, MSMFB_DISPLAY_COMMIT, &ext_commit) == -1) {
+         ALOGE("%s: MSMFB_DISPLAY_COMMIT for external failed, str: %s",
+                                                __FUNCTION__, strerror(errno));
          return false;
     }
+
     return true;
 }
 
diff --git a/libgralloc/framebuffer.cpp b/libgralloc/framebuffer.cpp
index 576e021..57df5b1 100644
--- a/libgralloc/framebuffer.cpp
+++ b/libgralloc/framebuffer.cpp
@@ -108,10 +108,11 @@
     private_module_t* m =
         reinterpret_cast<private_module_t*>(dev->common.module);
 
-    if (hnd && hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER) {
+    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));
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index 76dc45f..24fd2d4 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -17,5 +17,6 @@
                                  hwc_uevents.cpp  \
                                  hwc_vsync.cpp    \
                                  hwc_fbupdate.cpp \
+                                 hwc_mdpcomp.cpp  \
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index f331f84..4baf986 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -28,6 +28,7 @@
 #include "hwc_utils.h"
 #include "hwc_video.h"
 #include "hwc_fbupdate.h"
+#include "hwc_mdpcomp.h"
 #include "external.h"
 
 using namespace qhwc;
@@ -97,6 +98,20 @@
     FBUpdate::reset();
 }
 
+//clear prev layer prop flags and realloc for current frame
+static void reset_layer_prop(hwc_context_t* ctx, int dpy) {
+    int layer_count = ctx->listStats[dpy].numAppLayers;
+
+    if(ctx->layerProp[dpy]) {
+       delete[] ctx->layerProp[dpy];
+       ctx->layerProp[dpy] = NULL;
+    }
+
+    if(layer_count) {
+       ctx->layerProp[dpy] = new LayerProp[layer_count];
+    }
+}
+
 static int hwc_prepare_primary(hwc_composer_device_1 *dev,
         hwc_display_contents_1_t *list) {
     hwc_context_t* ctx = (hwc_context_t*)(dev);
@@ -109,7 +124,11 @@
         if(fbLayer->handle) {
             setListStats(ctx, list, HWC_DISPLAY_PRIMARY);
             ctx->mLayerCache->updateLayerCache(list);
-            VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY);
+            reset_layer_prop(ctx, HWC_DISPLAY_PRIMARY);
+            if(!MDPComp::configure(ctx, list)) {
+                VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY);
+                FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_PRIMARY);
+            }
         }
     }
     return 0;
@@ -123,13 +142,14 @@
         ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].isActive &&
         ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].connected) {
 
-        setListStats(ctx, list, HWC_DISPLAY_EXTERNAL);
-
         uint32_t last = list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
         if(fbLayer->handle) {
-            FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_EXTERNAL);
+            setListStats(ctx, list, HWC_DISPLAY_EXTERNAL);
+            reset_layer_prop(ctx, HWC_DISPLAY_EXTERNAL);
+
             VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL);
+            FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_EXTERNAL);
         }
     }
     return 0;
@@ -145,24 +165,20 @@
 
     ctx->mOverlay->configBegin();
 
-    //If securing of h/w in progress skip comp using overlay.
-    //TODO remove from here when sending FB via overlay
-    if(ctx->mSecuring == false) {
-        for (uint32_t i = 0; i < numDisplays; i++) {
-            hwc_display_contents_1_t *list = displays[i];
-            switch(i) {
-                case HWC_DISPLAY_PRIMARY:
-                    ret = hwc_prepare_primary(dev, list);
-                    break;
-                case HWC_DISPLAY_EXTERNAL:
-                    ret = hwc_prepare_external(dev, list);
-                    break;
-                default:
-                    ret = -EINVAL;
-            }
+    for (int32_t i = numDisplays - 1; i >= 0; i--) {
+        hwc_display_contents_1_t *list = displays[i];
+        switch(i) {
+            case HWC_DISPLAY_PRIMARY:
+                ret = hwc_prepare_primary(dev, list);
+                break;
+            case HWC_DISPLAY_EXTERNAL:
+
+                ret = hwc_prepare_external(dev, list);
+                break;
+            default:
+                ret = -EINVAL;
         }
     }
-
     ctx->mOverlay->configDone();
 
     return ret;
@@ -269,14 +285,25 @@
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
 
         hwc_sync(ctx, list, HWC_DISPLAY_PRIMARY);
-
         if (!VideoOverlay::draw(ctx, list, HWC_DISPLAY_PRIMARY)) {
             ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
             ret = -1;
         }
+        if (!MDPComp::draw(ctx, list)) {
+            ALOGE("%s: MDPComp::draw fail!", __FUNCTION__);
+            ret = -1;
+        }
+
         //TODO We dont check for SKIP flag on this layer because we need PAN
         //always. Last layer is always FB
-        if(list->hwLayers[last].compositionType == HWC_FRAMEBUFFER_TARGET) {
+        private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
+        if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET && hnd) {
+            if(!(fbLayer->flags & HWC_SKIP_LAYER)) {
+                if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_PRIMARY)) {
+                    ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
+                    ret = -1;
+                }
+            }
             if (ctx->mFbDev->post(ctx->mFbDev, fbLayer->handle)) {
                 ALOGE("%s: ctx->mFbDev->post fail!", __FUNCTION__);
                 return -1;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 0fbe309..fcbbc28 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -17,93 +17,34 @@
  */
 
 #include "hwc_mdpcomp.h"
+#include <sys/ioctl.h>
 #include "external.h"
 
-#define SUPPORT_4LAYER 0
-
 namespace qhwc {
 
-/****** Class PipeMgr ***********/
-
-void inline PipeMgr::reset() {
-    mVGPipes = MAX_VG;
-    mVGUsed = 0;
-    mVGIndex = 0;
-    mRGBPipes = MAX_RGB;
-    mRGBUsed = 0;
-    mRGBIndex = MAX_VG;
-    mTotalAvail = mVGPipes + mRGBPipes;
-    memset(&mStatus, 0x0 , sizeof(int)*mTotalAvail);
-}
-
-int PipeMgr::req_for_pipe(int pipe_req) {
-
-    switch(pipe_req) {
-        case PIPE_REQ_VG: //VG
-            if(mVGPipes){
-                mVGPipes--;
-                mVGUsed++;
-                mTotalAvail--;
-                return PIPE_REQ_VG;
-            }
-        case PIPE_REQ_RGB: // RGB
-            if(mRGBPipes) {
-                mRGBPipes--;
-                mRGBUsed++;
-                mTotalAvail--;
-                return PIPE_REQ_RGB;
-            }
-            return PIPE_NONE;
-        case PIPE_REQ_FB: //FB
-            if(mRGBPipes) {
-               mRGBPipes--;
-               mRGBUsed++;
-               mTotalAvail--;
-               mStatus[VAR_INDEX] = PIPE_IN_FB_MODE;
-               return PIPE_REQ_FB;
-           }
-        default:
-            break;
-    };
-    return PIPE_NONE;
-}
-
-int PipeMgr::assign_pipe(int pipe_pref) {
-    switch(pipe_pref) {
-        case PIPE_REQ_VG: //VG
-            if(mVGUsed) {
-                mVGUsed--;
-                mStatus[mVGIndex] = PIPE_IN_COMP_MODE;
-                return mVGIndex++;
-            }
-        case PIPE_REQ_RGB: //RGB
-            if(mRGBUsed) {
-                mRGBUsed--;
-                mStatus[mRGBIndex] = PIPE_IN_COMP_MODE;
-                return mRGBIndex++;
-            }
-        default:
-            ALOGE("%s: PipeMgr:invalid case in pipe_mgr_assign",
-                                                       __FUNCTION__);
-            return -1;
-    };
-}
-
+namespace ovutils = overlay::utils;
 /****** Class MDPComp ***********/
 
-MDPComp::State MDPComp::sMDPCompState = MDPCOMP_OFF;
-struct MDPComp::frame_info MDPComp::sCurrentFrame;
-PipeMgr MDPComp::sPipeMgr;
+MDPComp::eState MDPComp::sMDPCompState = MDPCOMP_OFF;
+struct MDPComp::FrameInfo MDPComp::sCurrentFrame;
 IdleInvalidator *MDPComp::idleInvalidator = NULL;
 bool MDPComp::sIdleFallBack = false;
 bool MDPComp::sDebugLogs = false;
-int MDPComp::sSkipCount = 0;
-int MDPComp::sMaxLayers = 0;
+bool MDPComp::sEnabled = false;
+int MDPComp::sActiveMax = 0;
+bool MDPComp::sSecuredVid = false;
 
 bool MDPComp::deinit() {
     //XXX: Tear down MDP comp state
     return true;
 }
+bool MDPComp::isSkipPresent (hwc_context_t *ctx) {
+    return  ctx->listStats[HWC_DISPLAY_PRIMARY].skipCount;
+};
+
+bool MDPComp::isYuvPresent (hwc_context_t *ctx) {
+    return  ctx->listStats[HWC_DISPLAY_PRIMARY].yuvCount;
+};
 
 void MDPComp::timeout_handler(void *udata) {
     struct hwc_context_t* ctx = (struct hwc_context_t*)(udata);
@@ -125,42 +66,13 @@
 void MDPComp::reset(hwc_context_t *ctx, hwc_display_contents_1_t* list ) {
     //Reset flags and states
     unsetMDPCompLayerFlags(ctx, list);
-    if(sMDPCompState == MDPCOMP_ON) {
-        sMDPCompState = MDPCOMP_OFF_PENDING;
-    }
-
     sCurrentFrame.count = 0;
-    if(sCurrentFrame.pipe_layer) {
-        free(sCurrentFrame.pipe_layer);
-        sCurrentFrame.pipe_layer = NULL;
+    if(sCurrentFrame.pipeLayer) {
+        free(sCurrentFrame.pipeLayer);
+        sCurrentFrame.pipeLayer = NULL;
     }
-
-    //Reset MDP pipes
-    sPipeMgr.reset();
-    sPipeMgr.setStatus(VAR_INDEX, PIPE_IN_FB_MODE);
-
-#if SUPPORT_4LAYER
-    configure_var_pipe(ctx);
-#endif
 }
 
-void MDPComp::setLayerIndex(hwc_layer_1_t* layer, const int pipe_index)
-{
-    layer->flags &= ~HWC_MDPCOMP_INDEX_MASK;
-    layer->flags |= pipe_index << MDPCOMP_INDEX_OFFSET;
-}
-
-int MDPComp::getLayerIndex(hwc_layer_1_t* layer)
-{
-    int byp_index = -1;
-
-    if(layer->flags & HWC_MDPCOMP) {
-        byp_index = ((layer->flags & HWC_MDPCOMP_INDEX_MASK) >>
-                                               MDPCOMP_INDEX_OFFSET);
-        byp_index = (byp_index < sMaxLayers ? byp_index : -1 );
-    }
-    return byp_index;
-}
 void MDPComp::print_info(hwc_layer_1_t* layer)
 {
      hwc_rect_t sourceCrop = layer->sourceCrop;
@@ -181,11 +93,21 @@
                              s_l, s_t, s_r, s_b, (s_r - s_l), (s_b - s_t),
                              d_l, d_t, d_r, d_b, (d_r - d_l), (d_b - d_t));
 }
+
+void MDPComp::setVidInfo(hwc_layer_1_t *layer, ovutils::eMdpFlags &mdpFlags) {
+    private_handle_t *hnd = (private_handle_t *)layer->handle;
+
+    if(isSecureBuffer(hnd)) {
+        ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
+        sSecuredVid = true;
+    }
+}
+
 /*
  * Configures pipe(s) for MDP composition
  */
 int MDPComp::prepare(hwc_context_t *ctx, hwc_layer_1_t *layer,
-                                            mdp_pipe_info& mdp_info) {
+                                            MdpPipeInfo& mdp_info) {
 
     int nPipeIndex = mdp_info.index;
 
@@ -193,17 +115,15 @@
 
         private_handle_t *hnd = (private_handle_t *)layer->handle;
 
-        overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_PRIMARY]);
+        overlay::Overlay& ov = *ctx->mOverlay;
 
         if(!hnd) {
             ALOGE("%s: layer handle is NULL", __FUNCTION__);
             return -1;
         }
 
-
-        int hw_w = ctx->mFbDev->width;
-        int hw_h = ctx->mFbDev->height;
-
+        int hw_w = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
+        int hw_h = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
 
         hwc_rect_t sourceCrop = layer->sourceCrop;
         hwc_rect_t displayFrame = layer->displayFrame;
@@ -219,18 +139,10 @@
         int dst_w = dst.right - dst.left;
         int dst_h = dst.bottom - dst.top;
 
-        //REDUNDANT ??
-        if(hnd != NULL &&
-               (hnd->flags & private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM )) {
-            ALOGE("%s: failed due to non-pmem memory",__FUNCTION__);
-            return -1;
-        }
-
         if(dst.left < 0 || dst.top < 0 ||
                dst.right > hw_w || dst.bottom > hw_h) {
             ALOGD_IF(isDebug(),"%s: Destination has negative coordinates",
                                                                   __FUNCTION__);
-
             qhwc::calculate_crop_rects(crop, dst, hw_w, hw_h, 0);
 
             //Update calulated width and height
@@ -249,23 +161,18 @@
         }
 
         // Determine pipe to set based on pipe index
-        ovutils::eDest dest = ovutils::OV_PIPE_ALL;
-        if (nPipeIndex == 0) {
-            dest = ovutils::OV_PIPE0;
-        } else if (nPipeIndex == 1) {
-            dest = ovutils::OV_PIPE1;
-        } else if (nPipeIndex == 2) {
-            dest = ovutils::OV_PIPE2;
-        }
+        ovutils::eDest dest = (ovutils::eDest)mdp_info.index;
 
         ovutils::eZorder zOrder = ovutils::ZORDER_0;
 
-        if(mdp_info.z_order == 0 ) {
+        if(mdp_info.zOrder == 0 ) {
             zOrder = ovutils::ZORDER_0;
-        } else if(mdp_info.z_order == 1 ) {
+        } else if(mdp_info.zOrder == 1 ) {
             zOrder = ovutils::ZORDER_1;
-        } else if(mdp_info.z_order == 2 ) {
+        } else if(mdp_info.zOrder == 2 ) {
             zOrder = ovutils::ZORDER_2;
+        } else if(mdp_info.zOrder == 3) {
+            zOrder = ovutils::ZORDER_3;
         }
 
         // Order order order
@@ -277,57 +184,53 @@
         // queueBuffer - not here, happens when draw is called
 
         ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
-        ovutils::eMdpFlags mdpFlags = mdp_info.isVG ? ovutils::OV_MDP_PIPE_SHARE
-                                                   : ovutils::OV_MDP_FLAGS_NONE;
+
+        ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
+
+        if(isYuvBuffer(hnd))
+            setVidInfo(layer, mdpFlags);
+
         ovutils::setMdpFlags(mdpFlags,ovutils::OV_MDP_BACKEND_COMPOSITION);
-        ovutils::eIsFg isFG = mdp_info.isFG ? ovutils::IS_FG_SET
-                                                    : ovutils::IS_FG_OFF;
 
         if(layer->blending == HWC_BLENDING_PREMULT) {
             ovutils::setMdpFlags(mdpFlags,
                     ovutils::OV_MDP_BLEND_FG_PREMULT);
         }
 
-        if(layer->transform & HAL_TRANSFORM_FLIP_H) {
-            ovutils::setMdpFlags(mdpFlags,
-                    ovutils::OV_MDP_FLIP_H);
-        }
+        ovutils::eTransform orient = overlay::utils::OVERLAY_TRANSFORM_0 ;
 
-        if(layer->transform & HAL_TRANSFORM_FLIP_V) {
-            ovutils::setMdpFlags(mdpFlags,
-                    ovutils::OV_MDP_FLIP_V);
-        }
+        if(!(layer->transform & HWC_TRANSFORM_ROT_90)) {
+            if(layer->transform & HWC_TRANSFORM_FLIP_H) {
+                ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_FLIP_H);
+            }
 
-        ov.setTransform(0, dest);
+            if(layer->transform & HWC_TRANSFORM_FLIP_V) {
+                ovutils::setMdpFlags(mdpFlags,  ovutils::OV_MDP_FLIP_V);
+            }
+        } else {
+            orient = static_cast<ovutils::eTransform>(layer->transform);
+        }
 
         ovutils::PipeArgs parg(mdpFlags,
                                info,
                                zOrder,
-                               isFG,
+                               ovutils::IS_FG_OFF,
                                ovutils::ROT_FLAG_DISABLED);
 
-        ovutils::PipeArgs pargs[MAX_PIPES] = { parg, parg, parg };
-        if (!ov.setSource(pargs, dest)) {
-            ALOGE("%s: setSource failed", __FUNCTION__);
-            return -1;
-        }
+        ov.setSource(parg, dest);
+
+        ov.setTransform(orient, dest);
 
         ovutils::Dim dcrop(crop.left, crop.top, crop_w, crop_h);
-        if (!ov.setCrop(dcrop, dest)) {
-            ALOGE("%s: setCrop failed", __FUNCTION__);
-            return -1;
-        }
+        ov.setCrop(dcrop, dest);
 
         ovutils::Dim dim(dst.left, dst.top, dst_w, dst_h);
-        if (!ov.setPosition(dim, dest)) {
-            ALOGE("%s: setPosition failed", __FUNCTION__);
-            return -1;
-        }
+        ov.setPosition(dim, dest);
 
         ALOGD_IF(isDebug(),"%s: MDP set: crop[%d,%d,%d,%d] dst[%d,%d,%d,%d] \
-                       nPipe: %d isFG: %d zorder: %d",__FUNCTION__, dcrop.x,
+                       nPipe: %d zorder: %d",__FUNCTION__, dcrop.x,
                        dcrop.y,dcrop.w, dcrop.h, dim.x, dim.y, dim.w, dim.h,
-                       nPipeIndex,mdp_info.isFG, mdp_info.z_order);
+                       mdp_info.index, mdp_info.zOrder);
 
         if (!ov.commit(dest)) {
             ALOGE("%s: commit failed", __FUNCTION__);
@@ -347,22 +250,29 @@
  * 5. Overlay in use
  */
 
-bool MDPComp::is_doable(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
+bool MDPComp::isDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
     //Number of layers
     int numAppLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
-    if(numAppLayers < 1 || numAppLayers > (uint32_t)sMaxLayers) {
+
+    if(numAppLayers < 1 || numAppLayers > (uint32_t)sActiveMax) {
         ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
         return false;
     }
 
-    //Disable MDPComp when ext display connected
-    if(isExternalActive(ctx)) {
-        ALOGD_IF(isDebug(), "%s: External display connected.", __FUNCTION__);
+    if(isSecuring(ctx)) {
+        ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
+        return false;
+    }
+
+    //Check for skip layers
+    if(isSkipPresent(ctx)) {
+        ALOGD_IF(isDebug(), "%s: Skip layers are present",__FUNCTION__);
         return false;
     }
 
     //FB composition on idle timeout
     if(sIdleFallBack) {
+        sIdleFallBack = false;
         ALOGD_IF(isDebug(), "%s: idle fallback",__FUNCTION__);
         return false;
     }
@@ -371,241 +281,110 @@
     for(int i = 0; i < numAppLayers; ++i) {
         // As MDP h/w supports flip operation, use MDP comp only for
         // 180 transforms. Fail for any transform involving 90 (90, 270).
-        if(list->hwLayers[i].transform & HWC_TRANSFORM_ROT_90) {
-                ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
-                return false;
+        hwc_layer_1_t* layer = &list->hwLayers[i];
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+        if((layer->transform & HWC_TRANSFORM_ROT_90)  && !isYuvBuffer(hnd)) {
+            ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
+            return false;
         }
     }
-
     return true;
 }
 
-void MDPComp::setMDPCompLayerFlags(hwc_display_contents_1_t* list) {
+void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
+                                hwc_display_contents_1_t* list) {
+    LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
 
-    for(int index = 0 ; index < sCurrentFrame.count; index++ )
-    {
-        int layer_index = sCurrentFrame.pipe_layer[index].layer_index;
-        if(layer_index >= 0) {
-            hwc_layer_1_t* layer = &(list->hwLayers[layer_index]);
-
-            layer->flags |= HWC_MDPCOMP;
-            layer->compositionType = HWC_OVERLAY;
-            layer->hints |= HWC_HINT_CLEAR_FB;
-        }
+    for(int index = 0 ; index < sCurrentFrame.count; index++ ) {
+        hwc_layer_1_t* layer = &(list->hwLayers[index]);
+        layerProp[index].mFlags |= HWC_MDPCOMP;
+        layer->compositionType = HWC_OVERLAY;
+        layer->hints |= HWC_HINT_CLEAR_FB;
     }
 }
 
-void MDPComp::get_layer_info(hwc_layer_1_t* layer, int& flags) {
+int MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type){
+    overlay::Overlay& ov = *ctx->mOverlay;
+    int mdp_pipe = -1;
 
-    private_handle_t* hnd = (private_handle_t*)layer->handle;
+    switch(type) {
+    case MDPCOMP_OV_ANY:
+    case MDPCOMP_OV_RGB:
+        mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, HWC_DISPLAY_PRIMARY);
+        if(mdp_pipe != ovutils::OV_INVALID) {
+            return mdp_pipe;
+        }
 
-    if(layer->flags & HWC_SKIP_LAYER) {
-        flags |= MDPCOMP_LAYER_SKIP;
-    } else if(hnd != NULL &&
-        (hnd->flags & private_handle_t::PRIV_FLAGS_NONCONTIGUOUS_MEM )) {
-        flags |= MDPCOMP_LAYER_UNSUPPORTED_MEM;
-    }
-
-    if(layer->blending != HWC_BLENDING_NONE)
-        flags |= MDPCOMP_LAYER_BLEND;
-
-    int dst_w, dst_h;
-    getLayerResolution(layer, dst_w, dst_h);
-
-    hwc_rect_t sourceCrop = layer->sourceCrop;
-    const int src_w = sourceCrop.right - sourceCrop.left;
-    const int src_h = sourceCrop.bottom - sourceCrop.top;
-    if(((src_w > dst_w) || (src_h > dst_h))) {
-        flags |= MDPCOMP_LAYER_DOWNSCALE;
-    }
+        if(type == MDPCOMP_OV_RGB) {
+            //Requested only for RGB pipe
+            return -1;
+        }
+    case  MDPCOMP_OV_VG:
+        mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, HWC_DISPLAY_PRIMARY);
+        if(mdp_pipe != ovutils::OV_INVALID) {
+            return mdp_pipe;
+        }
+        return -1;
+    default:
+        ALOGE("%s: Invalid pipe type",__FUNCTION__);
+        return -1;
+    };
 }
 
-int MDPComp::mark_layers(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list, layer_mdp_info* layer_info,
-        frame_info& current_frame) {
-
-    int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
-
-    if(layer_count > sMaxLayers) {
-        if(!sPipeMgr.req_for_pipe(PIPE_REQ_FB)) {
-            ALOGE("%s: binding var pipe to FB failed!!", __FUNCTION__);
-            return 0;
-        }
-    }
-
-    //Parse layers from higher z-order
-    for(int index = layer_count - 1 ; index >= 0; index-- ) {
-        hwc_layer_1_t* layer = &list->hwLayers[index];
-
-        int layer_prop = 0;
-        get_layer_info(layer, layer_prop);
-
-        ALOGD_IF(isDebug(),"%s: prop for layer [%d]: %x", __FUNCTION__,
-                                                             index, layer_prop);
-
-        //Both in cases of NON-CONTIGUOUS memory or SKIP layer,
-        //current version of mdp composition falls back completely to FB
-        //composition.
-        //TO DO: Support dual mode composition
-
-        if(layer_prop & MDPCOMP_LAYER_UNSUPPORTED_MEM) {
-            ALOGD_IF(isDebug(), "%s: Non contigous memory",__FUNCTION__);
-            return MDPCOMP_ABORT;
-        }
-
-        if(layer_prop & MDPCOMP_LAYER_SKIP) {
-            ALOGD_IF(isDebug(), "%s:skip layer",__FUNCTION__);
-            return MDPCOMP_ABORT;
-        }
-
-        //Request for MDP pipes
-        int pipe_pref = PIPE_REQ_VG;
-
-        if((layer_prop & MDPCOMP_LAYER_DOWNSCALE) &&
-                        (layer_prop & MDPCOMP_LAYER_BLEND)) {
-            pipe_pref = PIPE_REQ_RGB;
-         }
-
-        int allocated_pipe = sPipeMgr.req_for_pipe( pipe_pref);
-        if(allocated_pipe) {
-          layer_info[index].can_use_mdp = true;
-          layer_info[index].pipe_pref = allocated_pipe;
-          current_frame.count++;
-        }else {
-            ALOGE("%s: pipe marking in mark layer fails for : %d",
-                                          __FUNCTION__, allocated_pipe);
-            return MDPCOMP_FAILURE;
-        }
-    }
-    return MDPCOMP_SUCCESS;
-}
-
-void MDPComp::reset_layer_mdp_info(layer_mdp_info* layer_info, int count) {
-    for(int i = 0 ; i < count; i++ ) {
-        layer_info[i].can_use_mdp = false;
-        layer_info[i].pipe_pref = PIPE_NONE;
-    }
-}
-
-bool MDPComp::alloc_layer_pipes(hwc_context_t *ctx,
+bool MDPComp::allocLayerPipes(hwc_context_t *ctx,
         hwc_display_contents_1_t* list,
-        layer_mdp_info* layer_info, frame_info& current_frame) {
+        FrameInfo& currentFrame) {
+
+    overlay::Overlay& ov = *ctx->mOverlay;
 
     int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
-    int mdp_count = current_frame.count;
-    int fallback_count = layer_count - mdp_count;
-    int frame_pipe_count = 0;
 
-    ALOGD_IF(isDebug(), "%s:  dual mode: %d  total count: %d \
-                                mdp count: %d fallback count: %d",
-                            __FUNCTION__, (layer_count != mdp_count),
-                            layer_count, mdp_count, fallback_count);
+    currentFrame.count = layer_count;
+
+    currentFrame.pipeLayer = (PipeLayerPair*)
+                          malloc(sizeof(PipeLayerPair) * currentFrame.count);
+
+    if(isYuvPresent(ctx)) {
+        int nYuvIndex = ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex;
+        hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
+        PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
+        MdpPipeInfo& pipe_info = info.pipeIndex;
+        pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
+        if(pipe_info.index < 0) {
+            ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
+                                                          __FUNCTION__);
+            return false;
+        }
+        pipe_info.zOrder = nYuvIndex;
+    }
 
     for(int index = 0 ; index < layer_count ; index++ ) {
+        if(index  == ctx->listStats[HWC_DISPLAY_PRIMARY].yuvIndex )
+            continue;
+
         hwc_layer_1_t* layer = &list->hwLayers[index];
-
-        if(layer_info[index].can_use_mdp) {
-             pipe_layer_pair& info = current_frame.pipe_layer[frame_pipe_count];
-             mdp_pipe_info& pipe_info = info.pipe_index;
-
-             pipe_info.index = sPipeMgr.assign_pipe(layer_info[index].pipe_pref);
-             pipe_info.isVG = (layer_info[index].pipe_pref == PIPE_REQ_VG);
-             pipe_info.isFG = (frame_pipe_count == 0);
-             /* if VAR pipe is attached to FB, FB will be updated with
-                VSYNC WAIT flag, so no need to set VSYNC WAIT for any
-                bypass pipes. if not, set VSYNC WAIT to the last updating pipe*/
-             pipe_info.vsync_wait =
-                 (sPipeMgr.getStatus(VAR_INDEX) == PIPE_IN_FB_MODE) ? false:
-                                      (frame_pipe_count == (mdp_count - 1));
-             /* All the layers composed on FB will have MDP zorder 0, so start
-                assigning from  1*/
-                pipe_info.z_order = index -
-                        (fallback_count ? fallback_count - 1 : fallback_count);
-
-             info.layer_index = index;
-             frame_pipe_count++;
+        PipeLayerPair& info = currentFrame.pipeLayer[index];
+        MdpPipeInfo& pipe_info = info.pipeIndex;
+        pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_ANY);
+        if(pipe_info.index < 0) {
+            ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
+            return false;
         }
+        pipe_info.zOrder = index;
     }
-    return 1;
-}
-
-//returns array of layers and their allocated pipes
-bool MDPComp::parse_and_allocate(hwc_context_t* ctx,
-        hwc_display_contents_1_t* list, frame_info& current_frame ) {
-
-    int layer_count = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
-
-    /* clear pipe status */
-    sPipeMgr.reset();
-
-    layer_mdp_info* bp_layer_info = (layer_mdp_info*)
-                                   malloc(sizeof(layer_mdp_info)* layer_count);
-
-    reset_layer_mdp_info(bp_layer_info, layer_count);
-
-    /* iterate through layer list to mark candidate */
-    if(mark_layers(ctx, list, bp_layer_info, current_frame) == MDPCOMP_ABORT) {
-        free(bp_layer_info);
-        current_frame.count = 0;
-        ALOGE_IF(isDebug(), "%s:mark_layers failed!!", __FUNCTION__);
-        return false;
-    }
-    current_frame.pipe_layer = (pipe_layer_pair*)
-                          malloc(sizeof(pipe_layer_pair) * current_frame.count);
-
-    /* allocate MDP pipes for marked layers */
-    alloc_layer_pipes(ctx, list, bp_layer_info, current_frame);
-
-    free(bp_layer_info);
     return true;
 }
-#if SUPPORT_4LAYER
-int MDPComp::configure_var_pipe(hwc_context_t* ctx) {
-
-    if(!ctx) {
-       ALOGE("%s: invalid context", __FUNCTION__);
-       return -1;
-    }
-
-    framebuffer_device_t *fbDev = ctx->fbDev;
-    if (!fbDev) {
-        ALOGE("%s: fbDev is NULL", __FUNCTION__);
-        return -1;
-    }
-
-    int new_mode = -1, cur_mode;
-    fbDev->perform(fbDev,EVENT_GET_VAR_PIPE_MODE, (void*)&cur_mode);
-
-    if(sPipeMgr.getStatus(VAR_INDEX) == PIPE_IN_FB_MODE) {
-        new_mode = VAR_PIPE_FB_ATTACH;
-    } else if(sPipeMgr.getStatus(VAR_INDEX) == PIPE_IN_BYP_MODE) {
-        new_mode = VAR_PIPE_FB_DETACH;
-        fbDev->perform(fbDev,EVENT_WAIT_POSTBUFFER,NULL);
-    }
-
-    ALOGD_IF(isDebug(),"%s: old_mode: %d new_mode: %d", __FUNCTION__,
-                                                      cur_mode, new_mode);
-
-    if((new_mode != cur_mode) && (new_mode >= 0)) {
-       if(fbDev->perform(fbDev,EVENT_SET_VAR_PIPE_MODE,(void*)&new_mode) < 0) {
-           ALOGE("%s: Setting var pipe mode failed", __FUNCTION__);
-       }
-    }
-
-    return 0;
-}
-#endif
 
 bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
     int nPipeIndex, vsync_wait, isFG;
     int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
 
-    frame_info &current_frame = sCurrentFrame;
-    current_frame.count = 0;
+    FrameInfo &currentFrame = sCurrentFrame;
+    currentFrame.count = 0;
 
-    if(current_frame.pipe_layer) {
-        free(current_frame.pipe_layer);
-        current_frame.pipe_layer = NULL;
+    if(currentFrame.pipeLayer) {
+        free(currentFrame.pipeLayer);
+        currentFrame.pipeLayer = NULL;
     }
 
     if(!ctx) {
@@ -613,125 +392,93 @@
        return -1;
     }
 
-    framebuffer_device_t *fbDev = ctx->mFbDev;
-    if (!fbDev) {
-        ALOGE("%s: fbDev is NULL", __FUNCTION__);
-        return -1;
+    if(!allocLayerPipes(ctx, list, currentFrame)) {
+        //clean current frame data
+        currentFrame.count = 0;
+
+        if(currentFrame.pipeLayer) {
+            free(currentFrame.pipeLayer);
+            currentFrame.pipeLayer = NULL;
+        }
+
+        ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
+        return false;
     }
 
-    if(!parse_and_allocate(ctx, list, current_frame)) {
-#if SUPPORT_4LAYER
-       int mode = VAR_PIPE_FB_ATTACH;
-       if(fbDev->perform(fbDev,EVENT_SET_VAR_PIPE_MODE,(void*)&mode) < 0 ) {
-           ALOGE("%s: setting var pipe mode failed", __FUNCTION__);
-       }
-#endif
-       ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
-       return false;
-    }
-#if SUPPORT_4LAYER
-    configure_var_pipe(ctx);
-#endif
-
-    overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_PRIMARY]);
-    ovutils::eOverlayState state = ov.getState();
-
-    if (current_frame.count == 1) {
-         state = ovutils::OV_BYPASS_1_LAYER;
-    } else if (current_frame.count == 2) {
-         state = ovutils::OV_BYPASS_2_LAYER;
-    } else if (current_frame.count == 3) {
-         state = ovutils::OV_BYPASS_3_LAYER;
-   }
-
-      ov.setState(state);
-
-
-    for (int index = 0 ; index < current_frame.count; index++) {
-        int layer_index = current_frame.pipe_layer[index].layer_index;
-        hwc_layer_1_t* layer = &list->hwLayers[layer_index];
-        mdp_pipe_info& cur_pipe = current_frame.pipe_layer[index].pipe_index;
+    for (int index = 0 ; index < currentFrame.count; index++) {
+        hwc_layer_1_t* layer = &list->hwLayers[index];
+        MdpPipeInfo& cur_pipe = currentFrame.pipeLayer[index].pipeIndex;
 
         if( prepare(ctx, layer, cur_pipe) != 0 ) {
            ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \
                                     layer %d with pipe index:%d",__FUNCTION__,
                                     index, cur_pipe.index);
            return false;
-         } else {
-            setLayerIndex(layer, index);
          }
     }
     return true;
 }
 
-void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx, hwc_display_contents_1_t* list)
+void MDPComp::unsetMDPCompLayerFlags(hwc_context_t* ctx,
+                                     hwc_display_contents_1_t* list)
 {
+    LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
+
     for (int index = 0 ; index < sCurrentFrame.count; index++) {
-        int l_index = sCurrentFrame.pipe_layer[index].layer_index;
-        if(list->hwLayers[l_index].flags & HWC_MDPCOMP) {
-            list->hwLayers[l_index].flags &= ~HWC_MDPCOMP;
+        if(layerProp[index].mFlags & HWC_MDPCOMP) {
+            layerProp[index].mFlags &= ~HWC_MDPCOMP;
         }
 
-        if(list->hwLayers[l_index].compositionType == HWC_OVERLAY) {
-            list->hwLayers[l_index].compositionType = HWC_FRAMEBUFFER;
+        if(list->hwLayers[index].compositionType == HWC_OVERLAY) {
+            list->hwLayers[index].compositionType = HWC_FRAMEBUFFER;
         }
     }
 }
 
-int MDPComp::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
+bool MDPComp::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
 
-    if(!isEnabled()) {
-        ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled",__FUNCTION__);
-        return 0;
+    if(!isEnabled() || !isUsed()) {
+        ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
+        return true;
      }
 
     if(!ctx || !list) {
         ALOGE("%s: invalid contxt or list",__FUNCTION__);
-        return -1;
+        return false;
     }
 
-    overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_PRIMARY]);
+    /* reset Invalidator */
+    if(idleInvalidator)
+        idleInvalidator->markForSleep();
+
+    overlay::Overlay& ov = *ctx->mOverlay;
+    LayerProp *layerProp = ctx->layerProp[HWC_DISPLAY_PRIMARY];
 
     int numHwLayers = ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers;
     for(int i = 0; i < numHwLayers; i++ )
     {
         hwc_layer_1_t *layer = &list->hwLayers[i];
 
-        if(!(layer->flags & HWC_MDPCOMP)) {
-            ALOGD_IF(isDebug(), "%s: Layer Not flagged for MDP comp",
-                                                                __FUNCTION__);
+        if(!(layerProp[i].mFlags & HWC_MDPCOMP)) {
             continue;
         }
 
-        int data_index = getLayerIndex(layer);
-        mdp_pipe_info& pipe_info =
-                          sCurrentFrame.pipe_layer[data_index].pipe_index;
+        MdpPipeInfo& pipe_info =
+                        sCurrentFrame.pipeLayer[i].pipeIndex;
         int index = pipe_info.index;
 
         if(index < 0) {
             ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, index);
-            return -1;
+            return false;
         }
 
-        /* reset Invalidator */
-        if(idleInvalidator)
-           idleInvalidator->markForSleep();
-
-        ovutils::eDest dest;
-
-        if (index == 0) {
-            dest = ovutils::OV_PIPE0;
-        } else if (index == 1) {
-            dest = ovutils::OV_PIPE1;
-        } else if (index == 2) {
-            dest = ovutils::OV_PIPE2;
-        }
+        ovutils::eDest dest = (ovutils::eDest)index;
 
         if (ctx ) {
             private_handle_t *hnd = (private_handle_t *)layer->handle;
             if(!hnd) {
                 ALOGE("%s handle null", __FUNCTION__);
-                return -1;
+                return false;
             }
 
             ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
@@ -740,45 +487,75 @@
 
             if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
                 ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
-                return -1;
+                return false;
             }
         }
-        layer->flags &= ~HWC_MDPCOMP;
-        layer->flags |= HWC_MDPCOMP_INDEX_MASK;
+
+        layerProp[i].mFlags &= ~HWC_MDPCOMP;
     }
-    return 0;
+    return true;
 }
 
-bool MDPComp::init(hwc_context_t *dev) {
+/*
+ * Sets up BORDERFILL as default base pipe and detaches RGB0.
+ * Framebuffer is always updated using PLAY ioctl.
+ */
 
-    if(!dev) {
+bool MDPComp::setupBasePipe(hwc_context_t *ctx) {
+
+    int fb_stride = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride;
+    int fb_width = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
+    int fb_height = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
+    int fb_fd = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].fd;
+
+    mdp_overlay ovInfo;
+    msmfb_overlay_data ovData;
+    memset(&ovInfo, 0, sizeof(mdp_overlay));
+    memset(&ovData, 0, sizeof(msmfb_overlay_data));
+
+    ovInfo.src.format = MDP_RGB_BORDERFILL;
+    ovInfo.src.width  = fb_width;
+    ovInfo.src.height = fb_height;
+    ovInfo.src_rect.w = fb_width;
+    ovInfo.src_rect.h = fb_height;
+    ovInfo.dst_rect.w = fb_width;
+    ovInfo.dst_rect.h = fb_height;
+    ovInfo.id = MSMFB_NEW_REQUEST;
+
+    if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) {
+        ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
+                  strerror(errno));
+        return false;
+    }
+
+    ovData.id = ovInfo.id;
+    if (ioctl(fb_fd, MSMFB_OVERLAY_PLAY, &ovData) < 0) {
+        ALOGE("Failed to call ioctl MSMFB_OVERLAY_PLAY err=%s",
+                   strerror(errno));
+        return false;
+    }
+    return true;
+}
+
+bool MDPComp::init(hwc_context_t *ctx) {
+
+    if(!ctx) {
         ALOGE("%s: Invalid hwc context!!",__FUNCTION__);
         return false;
     }
 
-#if SUPPORT_4LAYER
-    if(MAX_MDPCOMP_LAYERS > MAX_STATIC_PIPES) {
-        framebuffer_device_t *fbDev = dev->fbDevice;
-        if(fbDev == NULL) {
-            ALOGE("%s: FATAL: framebuffer device is NULL", __FUNCTION__);
-            return false;
-        }
-
-        //Receive VAR pipe object from framebuffer
-        if(fbDev->perform(fbDev,EVENT_GET_VAR_PIPE,(void*)&ov) < 0) {
-            ALOGE("%s: FATAL: getVariablePipe failed!!", __FUNCTION__);
-            return false;
-        }
-
-        sPipeMgr.setStatus(VAR_INDEX, PIPE_IN_FB_MODE);
+    if(!setupBasePipe(ctx)) {
+        ALOGE("%s: Failed to setup primary base pipe", __FUNCTION__);
+        return false;
     }
-#endif
+
     char property[PROPERTY_VALUE_MAX];
 
-    sMaxLayers = 0;
-    if(property_get("debug.mdpcomp.maxlayer", property, NULL) > 0) {
-        if(atoi(property) != 0)
-           sMaxLayers = atoi(property);
+    sEnabled = false;
+    if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
+                      (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+                      (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+           sEnabled = true;
     }
 
     sDebugLogs = false;
@@ -799,25 +576,29 @@
     if(idleInvalidator == NULL) {
        ALOGE("%s: failed to instantiate idleInvalidator  object", __FUNCTION__);
     } else {
-       idleInvalidator->init(timeout_handler, dev, idle_timeout);
+       idleInvalidator->init(timeout_handler, ctx, idle_timeout);
     }
     return true;
 }
 
-bool MDPComp::configure(hwc_context_t *ctx,  hwc_display_contents_1_t* list) {
+bool MDPComp::configure(hwc_context_t *ctx,
+                        hwc_display_contents_1_t* list) {
 
     if(!isEnabled()) {
-        ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
+        ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
         return false;
     }
 
+    overlay::Overlay& ov = *ctx->mOverlay;
+
+    sActiveMax = ov.availablePipes();
+
     bool isMDPCompUsed = true;
-    bool doable = is_doable(ctx, list);
+    bool doable = isDoable(ctx, list);
 
     if(doable) {
         if(setup(ctx, list)) {
-            setMDPCompLayerFlags(list);
-            sMDPCompState = MDPCOMP_ON;
+            setMDPCompLayerFlags(ctx, list);
         } else {
             ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__);
             isMDPCompUsed = false;
@@ -834,7 +615,7 @@
          reset(ctx, list);
      }
 
-     sIdleFallBack = false;
+     sMDPCompState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF;
 
      return isMDPCompUsed;
 }
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 7fd6cee..2821f07 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -24,126 +24,47 @@
 #include <cutils/properties.h>
 #include <overlay.h>
 
-#define MAX_STATIC_PIPES 3
-#define MDPCOMP_INDEX_OFFSET 4
 #define DEFAULT_IDLE_TIME 2000
 
-#define MAX_VG 2
-#define MAX_RGB 2
-#define VAR_INDEX 3
-#define MAX_PIPES (MAX_VG + MAX_RGB)
-#define HWC_MDPCOMP_INDEX_MASK 0x00000030
-
-
-//struct hwc_context_t;
-
 namespace qhwc {
-
-// pipe status
-enum {
-    PIPE_UNASSIGNED = 0,
-    PIPE_IN_FB_MODE,
-    PIPE_IN_COMP_MODE,
-};
-
-// pipe request
-enum {
-    PIPE_NONE = 0,
-    PIPE_REQ_VG,
-    PIPE_REQ_RGB,
-    PIPE_REQ_FB,
-};
-
-// MDP Comp Status
-enum {
-    MDPCOMP_SUCCESS = 0,
-    MDPCOMP_FAILURE,
-    MDPCOMP_ABORT,
-};
-
-//This class manages the status of 4 MDP pipes and keeps
-//track of Variable pipe mode.
-class PipeMgr {
-
-public:
-    PipeMgr() { reset();}
-    //reset pipemgr params
-    void reset();
-
-    //Based on the preference received, pipe mgr
-    //allocates the best available pipe to handle
-    //the case
-    int req_for_pipe(int pipe_req);
-
-    //Allocate requested pipe and update availablity
-    int assign_pipe(int pipe_pref);
-
-    // Get/Set pipe status
-    void setStatus(int pipe_index, int pipe_status) {
-        mStatus[pipe_index] = pipe_status;
-    }
-    int getStatus(int pipe_index) {
-        return mStatus[pipe_index];
-    }
-private:
-    int mVGPipes;
-    int mVGUsed;
-    int mVGIndex;
-    int mRGBPipes;
-    int mRGBUsed;
-    int mRGBIndex;
-    int mTotalAvail;
-    int mStatus[MAX_PIPES];
-};
-
+namespace ovutils = overlay::utils;
 
 class MDPComp {
-    enum State {
+    enum eState {
         MDPCOMP_ON = 0,
         MDPCOMP_OFF,
-        MDPCOMP_OFF_PENDING,
     };
 
-    enum {
-        MDPCOMP_LAYER_BLEND = 1,
-        MDPCOMP_LAYER_DOWNSCALE = 2,
-        MDPCOMP_LAYER_SKIP = 4,
-        MDPCOMP_LAYER_UNSUPPORTED_MEM = 8,
+    enum ePipeType {
+        MDPCOMP_OV_RGB = ovutils::OV_MDP_PIPE_RGB,
+        MDPCOMP_OV_VG = ovutils::OV_MDP_PIPE_VG,
+        MDPCOMP_OV_ANY,
     };
 
-    struct mdp_pipe_info {
+    struct MdpPipeInfo {
         int index;
-        int z_order;
-        bool isVG;
-        bool isFG;
-        bool vsync_wait;
+        int zOrder;
     };
 
-    struct pipe_layer_pair {
-        int layer_index;
-        mdp_pipe_info pipe_index;
+    struct PipeLayerPair {
+        MdpPipeInfo pipeIndex;
         native_handle_t* handle;
     };
 
-    struct frame_info {
+    struct FrameInfo {
         int count;
-        struct pipe_layer_pair* pipe_layer;
+        struct PipeLayerPair* pipeLayer;
 
     };
 
-    struct layer_mdp_info {
-        bool can_use_mdp;
-        int pipe_pref;
-    };
-
-    static State sMDPCompState;
+    static eState sMDPCompState;
     static IdleInvalidator *idleInvalidator;
-    static struct frame_info sCurrentFrame;
-    static PipeMgr sPipeMgr;
-    static int sSkipCount;
-    static int sMaxLayers;
+    static struct FrameInfo sCurrentFrame;
+    static bool sEnabled;
     static bool sDebugLogs;
     static bool sIdleFallBack;
+    static int sActiveMax;
+    static bool sSecuredVid;
 
 public:
     /* Handler to invoke frame redraw on Idle Timer expiry */
@@ -152,24 +73,19 @@
     /* configure/tear-down MDPComp params*/
     static bool init(hwc_context_t *ctx);
     static bool deinit();
+    static bool isUsed() { return (sMDPCompState == MDPCOMP_ON); };
 
     /*sets up mdp comp for the current frame */
-    static bool configure(hwc_context_t *ctx,  hwc_display_contents_1_t* list);
+    static bool configure(hwc_context_t *ctx,
+                            hwc_display_contents_1_t* list);
 
     /* draw */
-    static int draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-
-    /* store frame stats */
-    static void setStats(int skipCt) { sSkipCount  = skipCt;};
+    static bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
 
 private:
-
-    /* get/set pipe index associated with overlay layers */
-    static void setLayerIndex(hwc_layer_1_t* layer, const int pipe_index);
-    static int  getLayerIndex(hwc_layer_1_t* layer);
-
     /* set/reset flags for MDPComp */
-    static void setMDPCompLayerFlags(hwc_display_contents_1_t* list);
+    static void setMDPCompLayerFlags(hwc_context_t *ctx,
+                                       hwc_display_contents_1_t* list);
     static void unsetMDPCompLayerFlags(hwc_context_t* ctx,
                                        hwc_display_contents_1_t* list);
 
@@ -177,45 +93,42 @@
 
     /* configure's overlay pipes for the frame */
     static int  prepare(hwc_context_t *ctx, hwc_layer_1_t *layer,
-                        mdp_pipe_info& mdp_info);
+                        MdpPipeInfo& mdp_info);
 
     /* checks for conditions where mdpcomp is not possible */
-    static bool is_doable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
+    static bool isDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
 
     static bool setup(hwc_context_t* ctx, hwc_display_contents_1_t* list);
 
-    /* parses layer for properties affecting mdp comp */
-    static void get_layer_info(hwc_layer_1_t* layer, int& flags);
-
-    /* iterates through layer list to choose candidate to use overlay */
-    static int  mark_layers(hwc_context_t *ctx, hwc_display_contents_1_t* list,
-            layer_mdp_info* layer_info, frame_info& current_frame);
-
-    static bool parse_and_allocate(hwc_context_t* ctx, hwc_display_contents_1_t* list,
-                                                  frame_info& current_frame );
-
-    /* clears layer info struct */
-    static void reset_layer_mdp_info(layer_mdp_info* layer_mdp_info,int count);
-
     /* allocates pipes to selected candidates */
-    static bool alloc_layer_pipes(hwc_context_t *ctx,
+    static bool allocLayerPipes(hwc_context_t *ctx,
             hwc_display_contents_1_t* list,
-            layer_mdp_info* layer_info,
-            frame_info& current_frame);
-    /* updates variable pipe mode for the current frame */
-    static int  configure_var_pipe(hwc_context_t* ctx);
+            FrameInfo& current_frame);
 
     /* get/set states */
-    static State get_state() { return sMDPCompState; };
-    static void set_state(State state) { sMDPCompState = state; };
+    static eState getState() { return sMDPCompState; };
 
     /* reset state */
     static void reset( hwc_context_t *ctx, hwc_display_contents_1_t* list );
 
     /* Is feature enabled */
-    static bool isEnabled() { return sMaxLayers ? true : false; };
+    static bool isEnabled() { return sEnabled; };
+
     /* Is debug enabled */
     static bool isDebug() { return sDebugLogs ? true : false; };
+
+    /* check layer state */
+    static bool isSkipPresent (hwc_context_t *ctx);
+    static bool isYuvPresent (hwc_context_t *ctx);
+
+    /* configure MDP flags for video buffers */
+    static void setVidInfo(hwc_layer_1_t *layer, ovutils::eMdpFlags &mdpFlags);
+
+    /* set up Border fill as Base pipe */
+    static bool setupBasePipe(hwc_context_t*);
+
+    /* allocate MDP pipes from overlay */
+    static int getMdpPipe(hwc_context_t *ctx, ePipeType type);
 };
 }; //namespace
 #endif
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index dea82df..ac9a7dc 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -22,6 +22,7 @@
 #include <fb_priv.h>
 #include <overlay.h>
 #include "hwc_utils.h"
+#include "hwc_mdpcomp.h"
 #include "mdp_version.h"
 #include "external.h"
 #include "QService.h"
@@ -37,6 +38,8 @@
         private_module_t* m = reinterpret_cast<private_module_t*>(
                 ctx->mFbDev->common.module);
         //xres, yres may not be 32 aligned
+        ctx->dpyAttr[HWC_DISPLAY_PRIMARY].stride = m->finfo.line_length /
+                                                (m->info.xres/8);
         ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = m->info.xres;
         ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = m->info.yres;
         ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xdpi = ctx->mFbDev->xdpi;
@@ -58,6 +61,7 @@
     ctx->mMDP.panel = qdutils::MDPVersion::getInstance().getPanelType();
     ctx->mExtDisplay = new ExternalDisplay(ctx);
     ctx->mLayerCache = new LayerCache();
+    MDPComp::init(ctx);
 
     pthread_mutex_init(&(ctx->vstate.lock), NULL);
     pthread_cond_init(&(ctx->vstate.cond), NULL);
@@ -151,6 +155,16 @@
     }
 }
 
+bool isSecuring(hwc_context_t* ctx) {
+    if((ctx->mMDP.version < qdutils::MDSS_V5) &&
+       (ctx->mMDP.version > qdutils::MDP_V3_0) &&
+        ctx->mSecuring) {
+        return true;
+    }
+    return false;
+}
+
+
 //Crops source buffer against destination and FB boundaries
 void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
         const int fbWidth, const int fbHeight, int orient) {
@@ -214,8 +228,7 @@
     for(uint32_t i = 0; i < list->numHwLayers; i++) {
         if((list->hwLayers[i].compositionType == HWC_OVERLAY ||
             list->hwLayers[i].compositionType == HWC_FRAMEBUFFER_TARGET) &&
-            list->hwLayers[i].acquireFenceFd != -1 &&
-            (list->hwLayers[i].flags & HWC_MDPCOMP)) {
+            list->hwLayers[i].acquireFenceFd != -1 ){
             acquireFd[count++] = list->hwLayers[i].acquireFenceFd;
         }
     }
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index e594b32..d2445d1 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -58,6 +58,7 @@
     uint32_t vsync_period; //nanos
     uint32_t xres;
     uint32_t yres;
+    uint32_t stride;
     float xdpi;
     float ydpi;
     int fd;
@@ -76,10 +77,15 @@
     int yuvIndex;
 };
 
+
+struct LayerProp {
+    uint32_t mFlags; //qcom specific layer flags
+    LayerProp():mFlags(0) {};
+};
+
+// LayerProp::flag values
 enum {
-    HWC_MDPCOMP = 0x00000002,
-    HWC_LAYER_RESERVED_0 = 0x00000004,
-    HWC_LAYER_RESERVED_1 = 0x00000008
+    HWC_MDPCOMP = 0x00000001,
 };
 
 class LayerCache {
@@ -103,6 +109,8 @@
 };
 
 
+
+
 // -----------------------------------------------------------------------------
 // Utility functions - implemented in hwc_utils.cpp
 void dumpLayer(hwc_layer_1_t const* l);
@@ -113,7 +121,7 @@
 //Crops source buffer against destination and FB boundaries
 void calculate_crop_rects(hwc_rect_t& crop, hwc_rect_t& dst,
         const int fbWidth, const int fbHeight, int orient);
-
+bool isSecuring(hwc_context_t* ctx);
 bool isExternalActive(hwc_context_t* ctx);
 
 //Sync point impl.
@@ -196,33 +204,24 @@
 struct hwc_context_t {
     hwc_composer_device_1_t device;
     const hwc_procs_t* proc;
-
     //Framebuffer device
     framebuffer_device_t *mFbDev;
-
     //Overlay object - NULL for non overlay devices
     overlay::Overlay *mOverlay;
-
     //QService object
     qService::QService *mQService;
-
     // External display related information
     qhwc::ExternalDisplay *mExtDisplay;
-
     qhwc::MDPInfo mMDP;
-
     qhwc::DisplayAttributes dpyAttr[HWC_NUM_DISPLAY_TYPES];
-
     qhwc::ListStats listStats[HWC_NUM_DISPLAY_TYPES];
-
     qhwc::LayerCache *mLayerCache;
+    qhwc::LayerProp *layerProp[HWC_NUM_DISPLAY_TYPES];
 
     //Securing in progress indicator
     bool mSecuring;
-
     //Display in secure mode indicator
     bool mSecureMode;
-
     //Lock to prevent set from being called while blanking
     mutable Locker mBlankLock;
     //Lock to protect set when detaching external disp
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
index 5fba951..48cb165 100644
--- a/libhwcomposer/hwc_video.cpp
+++ b/libhwcomposer/hwc_video.cpp
@@ -40,6 +40,11 @@
        return false;
     }
 
+    if(isSecuring(ctx)) {
+       ALOGD_IF(VIDEO_DEBUG,"%s: MDP Secure is active", __FUNCTION__);
+       return false;
+    }
+
     if(yuvIndex == -1 || ctx->listStats[dpy].yuvCount != 1) {
         return false;
     }
@@ -106,13 +111,9 @@
         isFgFlag = ovutils::IS_FG_SET;
     }
 
-    //TODO change to 1 always when primary FB uses overlay.
-    const ovutils::eZorder zorder = (dpy == HWC_DISPLAY_PRIMARY) ?
-            ovutils::ZORDER_0 : ovutils::ZORDER_1;
-
     ovutils::PipeArgs parg(mdpFlags,
             info,
-            zorder,
+            ovutils::ZORDER_1,
             isFgFlag,
             ovutils::ROT_FLAG_DISABLED);