Merge "gralloc: Mark buffers used by HWC"
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index b1ee2da..3b08fc5 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -13,7 +13,6 @@
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdhwcomposer\"
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps)
 LOCAL_SRC_FILES               := hwc.cpp          \
-                                 hwc_video.cpp    \
                                  hwc_utils.cpp    \
                                  hwc_uevents.cpp  \
                                  hwc_vsync.cpp    \
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index a81e761..42f5c85 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -30,7 +30,6 @@
 #include <overlayRotator.h>
 #include <mdp_version.h>
 #include "hwc_utils.h"
-#include "hwc_video.h"
 #include "hwc_fbupdate.h"
 #include "hwc_mdpcomp.h"
 #include "external.h"
@@ -102,8 +101,6 @@
 
         if(ctx->mFBUpdate[i])
             ctx->mFBUpdate[i]->reset();
-        if(ctx->mVidOv[i])
-            ctx->mVidOv[i]->reset();
         if(ctx->mCopyBit[i])
             ctx->mCopyBit[i]->reset();
     }
@@ -139,21 +136,18 @@
         uint32_t last = list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
         if(fbLayer->handle) {
-            if(list->numHwLayers > MAX_NUM_LAYERS) {
-                ctx->mFBUpdate[dpy]->prepare(ctx, list);
-                return 0;
-            }
             setListStats(ctx, list, dpy);
-            bool ret = ctx->mMDPComp->prepare(ctx, list);
-            if(!ret) {
-                // IF MDPcomp fails use this route
-                ctx->mVidOv[dpy]->prepare(ctx, list);
-                ctx->mFBUpdate[dpy]->prepare(ctx, list);
-                // Use Copybit, when MDP comp fails
-                if(ctx->mCopyBit[dpy])
-                    ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
-                ctx->mLayerCache[dpy]->updateLayerCache(list);
-            }
+            int fbZOrder = ctx->mMDPComp[dpy]->prepare(ctx, list);
+            if(fbZOrder >= 0)
+                ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZOrder);
+
+            /* Temporarily commenting out C2D until we support partial
+               copybit composition for mixed mode MDP
+
+            // Use Copybit, when MDP comp fails
+            if((fbZOrder >= 0) && ctx->mCopyBit[dpy])
+                ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
+            */
         }
     }
     return 0;
@@ -172,16 +166,17 @@
         if(!ctx->dpyAttr[dpy].isPause) {
             if(fbLayer->handle) {
                 ctx->mExtDispConfiguring = false;
-                if(list->numHwLayers > MAX_NUM_LAYERS) {
-                    ctx->mFBUpdate[dpy]->prepare(ctx, list);
-                    return 0;
-                }
                 setListStats(ctx, list, dpy);
-                ctx->mVidOv[dpy]->prepare(ctx, list);
-                ctx->mFBUpdate[dpy]->prepare(ctx, list);
-                ctx->mLayerCache[dpy]->updateLayerCache(list);
-                if(ctx->mCopyBit[dpy])
+                int fbZOrder = ctx->mMDPComp[dpy]->prepare(ctx, list);
+                if(fbZOrder >= 0)
+                    ctx->mFBUpdate[dpy]->prepare(ctx, list, fbZOrder);
+
+                /* Temporarily commenting out C2D until we support partial
+                   copybit composition for mixed mode MDP
+
+                if((fbZOrder >= 0) && ctx->mCopyBit[dpy])
                     ctx->mCopyBit[dpy]->prepare(ctx, list, dpy);
+                */
             }
         } else {
             // External Display is in Pause state.
@@ -299,7 +294,8 @@
                 // so that any pipe unsets gets committed
                 if (display_commit(ctx, dpy) < 0) {
                     ret = -1;
-                    ALOGE("%s:post failed for external display !! ", __FUNCTION__);
+                    ALOGE("%s:post failed for external display !! ",
+                          __FUNCTION__);
                 }
             } else {
             }
@@ -360,11 +356,8 @@
             copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
         if(list->numHwLayers > 1)
             hwc_sync(ctx, list, dpy, fd);
-        if (!ctx->mVidOv[dpy]->draw(ctx, list)) {
-            ALOGE("%s: VideoOverlay draw failed", __FUNCTION__);
-            ret = -1;
-        }
-        if (!ctx->mMDPComp->draw(ctx, list)) {
+
+        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
             ALOGE("%s: MDPComp draw failed", __FUNCTION__);
             ret = -1;
         }
@@ -413,8 +406,8 @@
         if(list->numHwLayers > 1)
             hwc_sync(ctx, list, dpy, fd);
 
-        if (!ctx->mVidOv[dpy]->draw(ctx, list)) {
-            ALOGE("%s: VideoOverlay::draw fail!", __FUNCTION__);
+        if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
+            ALOGE("%s: MDPComp draw failed", __FUNCTION__);
             ret = -1;
         }
 
@@ -558,7 +551,10 @@
     dumpsys_log(aBuf, "Qualcomm HWC state:\n");
     dumpsys_log(aBuf, "  MDPVersion=%d\n", ctx->mMDP.version);
     dumpsys_log(aBuf, "  DisplayPanel=%c\n", ctx->mMDP.panel);
-    ctx->mMDPComp->dump(aBuf);
+    for(int dpy = 0; dpy < MAX_DISPLAYS; dpy++) {
+        if(ctx->mMDPComp[dpy])
+            ctx->mMDPComp[dpy]->dump(aBuf);
+    }
     char ovDump[2048] = {'\0'};
     ctx->mOverlay->getDump(ovDump, 2048);
     dumpsys_log(aBuf, ovDump);
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 6d0b85f..f1f81c1 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -21,7 +21,6 @@
 #define DEBUG_FBUPDATE 0
 #include <gralloc_priv.h>
 #include "hwc_fbupdate.h"
-#include "hwc_video.h"
 
 namespace qhwc {
 
@@ -38,16 +37,6 @@
     mModeOn = false;
 }
 
-bool IFBUpdate::needFbUpdate(hwc_context_t *ctx,
-        const hwc_display_contents_1_t *list, int dpy) {
-    // if Video Overlay is on and and YUV layers are passed through overlay
-    // , no need to configure FB layer.
-    if(ctx->mVidOv[dpy]->isModeOn() &&
-        (ctx->listStats[dpy].yuvCount == ctx->listStats[dpy].numAppLayers))
-        return false;
-
-    return true;
-}
 //================= Low res====================================
 FBUpdateLowRes::FBUpdateLowRes(const int& dpy): IFBUpdate(dpy) {}
 
@@ -56,79 +45,65 @@
     mDest = ovutils::OV_INVALID;
 }
 
-bool FBUpdateLowRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list)
-{
+bool FBUpdateLowRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
+                             int fbZorder) {
     if(!ctx->mMDP.hasOverlay) {
         ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
-                __FUNCTION__);
-       return false;
+                 __FUNCTION__);
+        return false;
     }
-    mModeOn = configure(ctx, list);
-    ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
+    mModeOn = configure(ctx, list, fbZorder);
     return mModeOn;
 }
 
 // Configure
-bool FBUpdateLowRes::configure(hwc_context_t *ctx,
-                               hwc_display_contents_1 *list)
-{
+bool FBUpdateLowRes::configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
+                               int fbZorder) {
     bool ret = false;
     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
     if (LIKELY(ctx->mOverlay)) {
-        // When Video overlay is in use and there are no UI layers to
-        // be composed to FB , no need to configure FbUpdate.
-        if(!needFbUpdate(ctx, list, mDpy))
-            return false;
-
         overlay::Overlay& ov = *(ctx->mOverlay);
         private_handle_t *hnd = (private_handle_t *)layer->handle;
         ovutils::Whf info(hnd->width, hnd->height,
-                ovutils::getMdpFormat(hnd->format), hnd->size);
+                          ovutils::getMdpFormat(hnd->format), hnd->size);
 
         //Request an RGB pipe
-        ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
+        ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy);
         if(dest == ovutils::OV_INVALID) { //None available
             return false;
         }
 
         mDest = dest;
 
-        ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
-        // If any of the layers has pre-multiplied alpha, set Pre multiplied
-        // Flag as the compositied output is alpha pre-multiplied.
-        if(ctx->listStats[mDpy].preMultipliedAlpha == true)
-               ovutils::setMdpFlags(mdpFlags, ovutils::OV_MDP_BLEND_FG_PREMULT);
+        ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_BLEND_FG_PREMULT;
 
-        ovutils::eZorder z_order =
-              ctx->mVidOv[mDpy]->isModeOn()?ovutils::ZORDER_1:ovutils::ZORDER_0;
-        ovutils::eIsFg is_fg =
-           ctx->mVidOv[mDpy]->isModeOn()? ovutils::IS_FG_OFF:ovutils::IS_FG_SET;
+        ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
 
         ovutils::PipeArgs parg(mdpFlags,
-                info,
-                z_order,
-                is_fg,
-                ovutils::ROT_FLAGS_NONE);
+                               info,
+                               zOrder,
+                               ovutils::IS_FG_OFF,
+                               ovutils::ROT_FLAGS_NONE);
         ov.setSource(parg, dest);
 
         hwc_rect_t sourceCrop;
         getNonWormholeRegion(list, sourceCrop);
         // x,y,w,h
         ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
-                sourceCrop.right - sourceCrop.left,
-                sourceCrop.bottom - sourceCrop.top);
+                           sourceCrop.right - sourceCrop.left,
+                           sourceCrop.bottom - sourceCrop.top);
         ov.setCrop(dcrop, dest);
 
         int transform = layer->transform;
         ovutils::eTransform orient =
-                static_cast<ovutils::eTransform>(transform);
+            static_cast<ovutils::eTransform>(transform);
         ov.setTransform(orient, dest);
 
         hwc_rect_t displayFrame = sourceCrop;
         ovutils::Dim dpos(displayFrame.left,
-                displayFrame.top,
-                displayFrame.right - displayFrame.left,
-                displayFrame.bottom - displayFrame.top);
+                          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);
@@ -167,34 +142,28 @@
     mDestRight = ovutils::OV_INVALID;
 }
 
-bool FBUpdateHighRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list)
-{
+bool FBUpdateHighRes::prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
+                              int fbZorder) {
     if(!ctx->mMDP.hasOverlay) {
         ALOGD_IF(DEBUG_FBUPDATE, "%s, this hw doesnt support overlays",
-                __FUNCTION__);
-       return false;
+                 __FUNCTION__);
+        return false;
     }
     ALOGD_IF(DEBUG_FBUPDATE, "%s, mModeOn = %d", __FUNCTION__, mModeOn);
-    mModeOn = configure(ctx, list);
+    mModeOn = configure(ctx, list, fbZorder);
     return mModeOn;
 }
 
 // Configure
 bool FBUpdateHighRes::configure(hwc_context_t *ctx,
-                                hwc_display_contents_1 *list)
-{
+                                hwc_display_contents_1 *list, int fbZorder) {
     bool ret = false;
     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
     if (LIKELY(ctx->mOverlay)) {
-        // When Video overlay is in use and there are no UI layers to
-        // be composed to FB , no need to configure FbUpdate.
-        if(!needFbUpdate(ctx, list, mDpy))
-            return false;
-
         overlay::Overlay& ov = *(ctx->mOverlay);
         private_handle_t *hnd = (private_handle_t *)layer->handle;
         ovutils::Whf info(hnd->width, hnd->height,
-                ovutils::getMdpFormat(hnd->format), hnd->size);
+                          ovutils::getMdpFormat(hnd->format), hnd->size);
 
         //Request left RGB pipe
         ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
@@ -210,49 +179,42 @@
         mDestLeft = destL;
         mDestRight = destR;
 
-        ovutils::eMdpFlags mdpFlagsL = ovutils::OV_MDP_FLAGS_NONE;
-        //If any layer has pre-multiplied alpha, set Pre multiplied
-        //Flag as the compositied output is alpha pre-multiplied.
-        if(ctx->listStats[mDpy].preMultipliedAlpha == true)
-            ovutils::setMdpFlags(mdpFlagsL, ovutils::OV_MDP_BLEND_FG_PREMULT);
+        ovutils::eMdpFlags mdpFlagsL = ovutils::OV_MDP_BLEND_FG_PREMULT;
 
-        ovutils::eZorder z_order =
-              ctx->mVidOv[mDpy]->isModeOn()?ovutils::ZORDER_1:ovutils::ZORDER_0;
-        ovutils::eIsFg is_fg =
-           ctx->mVidOv[mDpy]->isModeOn()? ovutils::IS_FG_OFF:ovutils::IS_FG_SET;
+        ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
 
         ovutils::PipeArgs pargL(mdpFlagsL,
-                info,
-                z_order,
-                is_fg,
-                ovutils::ROT_FLAGS_NONE);
+                                info,
+                                zOrder,
+                                ovutils::IS_FG_OFF,
+                                ovutils::ROT_FLAGS_NONE);
         ov.setSource(pargL, destL);
 
         ovutils::eMdpFlags mdpFlagsR = mdpFlagsL;
         ovutils::setMdpFlags(mdpFlagsR, ovutils::OV_MDSS_MDP_RIGHT_MIXER);
         ovutils::PipeArgs pargR(mdpFlagsR,
-                info,
-                z_order,
-                is_fg,
-                ovutils::ROT_FLAGS_NONE);
+                                info,
+                                zOrder,
+                                ovutils::IS_FG_OFF,
+                                ovutils::ROT_FLAGS_NONE);
         ov.setSource(pargR, destR);
 
         hwc_rect_t sourceCrop;
         getNonWormholeRegion(list, sourceCrop);
         ovutils::Dim dcropL(sourceCrop.left, sourceCrop.top,
-                (sourceCrop.right - sourceCrop.left) / 2,
-                sourceCrop.bottom - sourceCrop.top);
+                            (sourceCrop.right - sourceCrop.left) / 2,
+                            sourceCrop.bottom - sourceCrop.top);
         ovutils::Dim dcropR(
-                sourceCrop.left + (sourceCrop.right - sourceCrop.left) / 2,
-                sourceCrop.top,
-                (sourceCrop.right - sourceCrop.left) / 2,
-                sourceCrop.bottom - sourceCrop.top);
+            sourceCrop.left + (sourceCrop.right - sourceCrop.left) / 2,
+            sourceCrop.top,
+            (sourceCrop.right - sourceCrop.left) / 2,
+            sourceCrop.bottom - sourceCrop.top);
         ov.setCrop(dcropL, destL);
         ov.setCrop(dcropR, destR);
 
         int transform = layer->transform;
         ovutils::eTransform orient =
-                static_cast<ovutils::eTransform>(transform);
+            static_cast<ovutils::eTransform>(transform);
         ov.setTransform(orient, destL);
         ov.setTransform(orient, destR);
 
@@ -260,14 +222,14 @@
         //For FB left, top will always be 0
         //That should also be the case if using 2 mixers for single display
         ovutils::Dim dposL(displayFrame.left,
-                displayFrame.top,
-                (displayFrame.right - displayFrame.left) / 2,
-                displayFrame.bottom - displayFrame.top);
+                           displayFrame.top,
+                           (displayFrame.right - displayFrame.left) / 2,
+                           displayFrame.bottom - displayFrame.top);
         ov.setPosition(dposL, destL);
         ovutils::Dim dposR(0,
-                displayFrame.top,
-                (displayFrame.right - displayFrame.left) / 2,
-                displayFrame.bottom - displayFrame.top);
+                           displayFrame.top,
+                           (displayFrame.right - displayFrame.left) / 2,
+                           displayFrame.bottom - displayFrame.top);
         ov.setPosition(dposR, destR);
 
         ret = true;
@@ -294,12 +256,12 @@
     ovutils::eDest destR = mDestRight;
     if (!ov.queueBuffer(hnd->fd, hnd->offset, destL)) {
         ALOGE("%s: queue failed for left of dpy = %d",
-                __FUNCTION__, mDpy);
+              __FUNCTION__, mDpy);
         ret = false;
     }
     if (!ov.queueBuffer(hnd->fd, hnd->offset, destR)) {
         ALOGE("%s: queue failed for right of dpy = %d",
-                __FUNCTION__, mDpy);
+              __FUNCTION__, mDpy);
         ret = false;
     }
     return ret;
diff --git a/libhwcomposer/hwc_fbupdate.h b/libhwcomposer/hwc_fbupdate.h
index ddd24d7..4291a50 100644
--- a/libhwcomposer/hwc_fbupdate.h
+++ b/libhwcomposer/hwc_fbupdate.h
@@ -34,17 +34,15 @@
     explicit IFBUpdate(const int& dpy) : mDpy(dpy) {}
     virtual ~IFBUpdate() {};
     // Sets up members and prepares overlay if conditions are met
-    virtual bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list) = 0;
+    virtual bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
+                                                       int fbZorder) = 0;
     // Draws layer
     virtual bool draw(hwc_context_t *ctx, private_handle_t *hnd) = 0;
     //Reset values
     virtual void reset();
     //Factory method that returns a low-res or high-res version
     static IFBUpdate *getObject(const int& width, const int& dpy);
-    //To know if configuring FbUpdate is needed.
-    static bool needFbUpdate(hwc_context_t *ctx,
-           const hwc_display_contents_1_t *list,
-                                       int dpy);
+
 protected:
     const int mDpy; // display to update
     bool mModeOn; // if prepare happened
@@ -55,12 +53,13 @@
 public:
     explicit FBUpdateLowRes(const int& dpy);
     virtual ~FBUpdateLowRes() {};
-    bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list);
-
+    bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
+                                                          int fbZorder);
     bool draw(hwc_context_t *ctx, private_handle_t *hnd);
     void reset();
 private:
-    bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list);
+    bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
+                                                               int fbZorder);
     ovutils::eDest mDest; //pipe to draw on
 };
 
@@ -69,11 +68,13 @@
 public:
     explicit FBUpdateHighRes(const int& dpy);
     virtual ~FBUpdateHighRes() {};
-    bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list);
+    bool prepare(hwc_context_t *ctx, hwc_display_contents_1 *list,
+                                                             int fbZorder);
     bool draw(hwc_context_t *ctx, private_handle_t *hnd);
     void reset();
 private:
-    bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list);
+    bool configure(hwc_context_t *ctx, hwc_display_contents_1 *list,
+                                                            int fbZorder);
     ovutils::eDest mDestLeft; //left pipe to draw on
     ovutils::eDest mDestRight; //right pipe to draw on
 };
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index e8559ac..30178a0 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -35,20 +35,44 @@
 bool MDPComp::sIdleFallBack = false;
 bool MDPComp::sDebugLogs = false;
 bool MDPComp::sEnabled = false;
+int MDPComp::sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
 
-MDPComp* MDPComp::getObject(const int& width) {
+MDPComp* MDPComp::getObject(const int& width, int dpy) {
     if(width <= MAX_DISPLAY_DIM) {
-        return new MDPCompLowRes();
+        return new MDPCompLowRes(dpy);
     } else {
-        return new MDPCompHighRes();
+        return new MDPCompHighRes(dpy);
     }
 }
 
+MDPComp::MDPComp(int dpy):mDpy(dpy){};
+
 void MDPComp::dump(android::String8& buf)
 {
-    dumpsys_log(buf, "  MDP Composition: ");
-    dumpsys_log(buf, "MDPCompState=%d\n", mState);
-    //XXX: Log more info
+    dumpsys_log(buf,"HWC Map for Dpy: %s \n",
+                mDpy ? "\"EXTERNAL\"" : "\"PRIMARY\"");
+    dumpsys_log(buf,"PREV_FRAME: layerCount:%2d    mdpCount:%2d \
+                cacheCount:%2d \n", mCachedFrame.layerCount,
+                mCachedFrame.mdpCount, mCachedFrame.cacheCount);
+    dumpsys_log(buf,"CURR_FRAME: layerCount:%2d    mdpCount:%2d \
+                fbCount:%2d \n", mCurrentFrame.layerCount,
+                mCurrentFrame.mdpCount, mCurrentFrame.fbCount);
+    dumpsys_log(buf,"needsFBRedraw:%3s  pipesUsed:%2d  MaxPipesPerMixer: %d \n",
+                (mCurrentFrame.needsRedraw? "YES" : "NO"),
+                mCurrentFrame.mdpCount, sMaxPipesPerMixer);
+    dumpsys_log(buf," ---------------------------------------------  \n");
+    dumpsys_log(buf," listIdx | cached? | mdpIndex | comptype  |  Z  \n");
+    dumpsys_log(buf," ---------------------------------------------  \n");
+    for(int index = 0; index < mCurrentFrame.layerCount; index++ )
+        dumpsys_log(buf," %7d | %7s | %8d | %9s | %2d \n",
+                    index,
+                    (mCurrentFrame.isFBComposed[index] ? "YES" : "NO"),
+                    mCurrentFrame.layerToMDP[index],
+                    (mCurrentFrame.isFBComposed[index] ?
+                     (mCurrentFrame.needsRedraw ? "GLES" : "CACHE") : "MDP"),
+                    (mCurrentFrame.isFBComposed[index] ? mCurrentFrame.fbZ :
+    mCurrentFrame.mdpToLayer[mCurrentFrame.layerToMDP[index]].pipeInfo->zOrder));
+    dumpsys_log(buf,"\n");
 }
 
 bool MDPComp::init(hwc_context_t *ctx) {
@@ -67,8 +91,8 @@
 
     sEnabled = false;
     if((property_get("persist.hwc.mdpcomp.enable", property, NULL) > 0) &&
-            (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
-             (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
+       (!strncmp(property, "1", PROPERTY_VALUE_MAX ) ||
+        (!strncasecmp(property,"true", PROPERTY_VALUE_MAX )))) {
         sEnabled = true;
     }
 
@@ -78,6 +102,12 @@
             sDebugLogs = true;
     }
 
+    sMaxPipesPerMixer = MAX_PIPES_PER_MIXER;
+    if(property_get("debug.mdpcomp.maxpermixer", property, NULL) > 0) {
+        if(atoi(property) != 0)
+            sMaxPipesPerMixer = true;
+    }
+
     unsigned long idle_timeout = DEFAULT_IDLE_TIME;
     if(property_get("debug.mdpcomp.idletime", property, NULL) > 0) {
         if(atoi(property) != 0)
@@ -88,7 +118,7 @@
     idleInvalidator = IdleInvalidator::getInstance();
 
     if(idleInvalidator == NULL) {
-        ALOGE("%s: failed to instantiate idleInvalidator  object", __FUNCTION__);
+        ALOGE("%s: failed to instantiate idleInvalidator object", __FUNCTION__);
     } else {
         idleInvalidator->init(timeout_handler, ctx, idle_timeout);
     }
@@ -113,33 +143,24 @@
 }
 
 void MDPComp::setMDPCompLayerFlags(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list) {
-    const int dpy = HWC_DISPLAY_PRIMARY;
-    LayerProp *layerProp = ctx->layerProp[dpy];
+                                   hwc_display_contents_1_t* list) {
+    LayerProp *layerProp = ctx->layerProp[mDpy];
 
-    for(int index = 0; index < ctx->listStats[dpy].numAppLayers; index++ ) {
+    for(int index = 0; index < ctx->listStats[mDpy].numAppLayers; 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::unsetMDPCompLayerFlags(hwc_context_t* ctx,
-        hwc_display_contents_1_t* list) {
-    const int dpy = HWC_DISPLAY_PRIMARY;
-    LayerProp *layerProp = ctx->layerProp[dpy];
-
-    for (int index = 0 ;
-            index < ctx->listStats[dpy].numAppLayers; index++) {
-        if(layerProp[index].mFlags & HWC_MDPCOMP) {
-            layerProp[index].mFlags &= ~HWC_MDPCOMP;
-        }
-
-        if(list->hwLayers[index].compositionType == HWC_OVERLAY) {
-            list->hwLayers[index].compositionType = HWC_FRAMEBUFFER;
+        if(!mCurrentFrame.isFBComposed[index]) {
+            layerProp[index].mFlags |= HWC_MDPCOMP;
+            layer->compositionType = HWC_OVERLAY;
+            layer->hints |= HWC_HINT_CLEAR_FB;
+            mCachedFrame.hnd[index] = NULL;
+        } else {
+            if(!mCurrentFrame.needsRedraw)
+                layer->compositionType = HWC_OVERLAY;
         }
     }
+    mCachedFrame.mdpCount = mCurrentFrame.mdpCount;
+    mCachedFrame.cacheCount = mCurrentFrame.fbCount;
+    mCachedFrame.layerCount = ctx->listStats[mDpy].numAppLayers;
 }
 
 /*
@@ -169,41 +190,58 @@
 
     if (ioctl(fb_fd, MSMFB_OVERLAY_SET, &ovInfo) < 0) {
         ALOGE("Failed to call ioctl MSMFB_OVERLAY_SET err=%s",
-                strerror(errno));
+              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));
+              strerror(errno));
         return false;
     }
     return true;
 }
+MDPComp::FrameInfo::FrameInfo() {
+    layerCount = 0;
+    reset();
+}
 
-void MDPComp::reset(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list ) {
-    //Reset flags and states
-    unsetMDPCompLayerFlags(ctx, list);
-    if(mCurrentFrame.pipeLayer) {
-        for(int i = 0 ; i < mCurrentFrame.count; i++ ) {
-            if(mCurrentFrame.pipeLayer[i].pipeInfo) {
-                delete mCurrentFrame.pipeLayer[i].pipeInfo;
-                mCurrentFrame.pipeLayer[i].pipeInfo = NULL;
-                //We dont own the rotator
-                mCurrentFrame.pipeLayer[i].rot = NULL;
-            }
+void MDPComp::FrameInfo::reset() {
+
+    for(int i = 0 ; i < MAX_PIPES_PER_MIXER && layerCount; i++ ) {
+        if(mdpToLayer[i].pipeInfo) {
+            delete mdpToLayer[i].pipeInfo;
+            mdpToLayer[i].pipeInfo = NULL;
+            //We dont own the rotator
+            mdpToLayer[i].rot = NULL;
         }
-        free(mCurrentFrame.pipeLayer);
-        mCurrentFrame.pipeLayer = NULL;
     }
-    mCurrentFrame.count = 0;
+
+    memset(&mdpToLayer, 0, sizeof(mdpToLayer));
+    memset(&layerToMDP, -1, sizeof(layerToMDP));
+    memset(&isFBComposed, 0, sizeof(isFBComposed));
+
+    layerCount = 0;
+    mdpCount = 0;
+    fbCount = 0;
+    needsRedraw = false;
+    fbZ = 0;
+}
+
+MDPComp::LayerCache::LayerCache() {
+    reset();
+}
+
+void MDPComp::LayerCache::reset() {
+    memset(&hnd, 0, sizeof(buffer_handle_t));
+    mdpCount = 0;
+    cacheCount = 0;
+    layerCount = 0;
 }
 
 bool MDPComp::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) {
@@ -211,8 +249,8 @@
         return false;
     }
 
-    int hw_w = ctx->dpyAttr[dpy].xres;
-    int hw_h = ctx->dpyAttr[dpy].yres;
+    int hw_w = ctx->dpyAttr[mDpy].xres;
+    int hw_h = ctx->dpyAttr[mDpy].yres;
 
     hwc_rect_t sourceCrop = layer->sourceCrop;
     hwc_rect_t displayFrame = layer->displayFrame;
@@ -226,98 +264,107 @@
     int dst_h = dst.bottom - dst.top;
 
     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 };
-       qhwc::calculate_crop_rects(crop, dst, scissor, layer->transform);
-       crop_w = crop.right - crop.left;
-       crop_h = crop.bottom - crop.top;
+        hwc_rect_t scissor = {0, 0, hw_w, hw_h };
+        qhwc::calculate_crop_rects(crop, dst, scissor, 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
+    /* 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 or height
+     * less than 5 pixels
+     * */
 
-    if(crop_w < 5)
+    if((crop_w < 5)||(crop_h < 5))
         return false;
 
     return true;
 }
 
 ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type) {
-    const int dpy = HWC_DISPLAY_PRIMARY;
     overlay::Overlay& ov = *ctx->mOverlay;
     ovutils::eDest mdp_pipe = ovutils::OV_INVALID;
 
     switch(type) {
-        case MDPCOMP_OV_DMA:
-            mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, dpy);
-            if(mdp_pipe != ovutils::OV_INVALID) {
-                ctx->mDMAInUse = true;
-                return mdp_pipe;
-            }
-        case MDPCOMP_OV_ANY:
-        case MDPCOMP_OV_RGB:
-            mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, dpy);
-            if(mdp_pipe != ovutils::OV_INVALID) {
-                return mdp_pipe;
-            }
+    case MDPCOMP_OV_DMA:
+        mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_DMA, mDpy);
+        if(mdp_pipe != ovutils::OV_INVALID) {
+            ctx->mDMAInUse = true;
+            return mdp_pipe;
+        }
+    case MDPCOMP_OV_ANY:
+    case MDPCOMP_OV_RGB:
+        mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy);
+        if(mdp_pipe != ovutils::OV_INVALID) {
+            return mdp_pipe;
+        }
 
-            if(type == MDPCOMP_OV_RGB) {
-                //Requested only for RGB pipe
-                break;
-            }
-        case  MDPCOMP_OV_VG:
-            return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy);
-        default:
-            ALOGE("%s: Invalid pipe type",__FUNCTION__);
-            return ovutils::OV_INVALID;
+        if(type == MDPCOMP_OV_RGB) {
+            //Requested only for RGB pipe
+            break;
+        }
+    case  MDPCOMP_OV_VG:
+        return ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
+    default:
+        ALOGE("%s: Invalid pipe type",__FUNCTION__);
+        return ovutils::OV_INVALID;
     };
     return ovutils::OV_INVALID;
 }
 
-bool MDPComp::isDoable(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list) {
-    //Number of layers
-    const int dpy = HWC_DISPLAY_PRIMARY;
-    int numAppLayers = ctx->listStats[dpy].numAppLayers;
-    int numDMAPipes = qdutils::MDPVersion::getInstance().getDMAPipes();
+bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
+    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
 
-    overlay::Overlay& ov = *ctx->mOverlay;
-    int availablePipes = ov.availablePipes(dpy);
-
-    if(ctx->mNeedsRotator)
-        availablePipes -= numDMAPipes;
-
-    if(numAppLayers < 1 || numAppLayers > MAX_PIPES_PER_MIXER ||
-                           pipesNeeded(ctx, list) > availablePipes) {
-        ALOGD_IF(isDebug(), "%s: Unsupported number of layers",__FUNCTION__);
+    if(!isEnabled()) {
+        ALOGD_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
         return false;
     }
 
     if(ctx->mExtDispConfiguring) {
         ALOGD_IF( isDebug(),"%s: External Display connection is pending",
-                __FUNCTION__);
+                  __FUNCTION__);
         return false;
     }
 
-    if(isSecuring(ctx)) {
-        ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
-        return false;
-    }
-
-    if(ctx->mSecureMode)
-        return false;
-
-    //Check for skip layers
-    if(isSkipPresent(ctx, dpy)) {
-        ALOGD_IF(isDebug(), "%s: Skip layers are present",__FUNCTION__);
-        return false;
-    }
-
-    if(ctx->listStats[dpy].needsAlphaScale
-                     && ctx->mMDP.version < qdutils::MDSS_V5) {
+    if(ctx->listStats[mDpy].needsAlphaScale
+       && ctx->mMDP.version < qdutils::MDSS_V5) {
         ALOGD_IF(isDebug(), "%s: frame needs alpha downscaling",__FUNCTION__);
         return false;
     }
 
+    return true;
+}
+
+/* Checks for conditions where all the layers marked for MDP comp cannot be
+ * bypassed. On such conditions we try to bypass atleast YUV layers */
+bool MDPComp::isFullFrameDoable(hwc_context_t *ctx,
+                                hwc_display_contents_1_t* list){
+
+    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
+    int mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount;
+    int fbNeeded = int(mCurrentFrame.fbCount != 0);
+
+    if(mDpy > HWC_DISPLAY_PRIMARY){
+        ALOGD_IF(isDebug(), "%s: Cannot support External display(s)",
+                 __FUNCTION__);
+        return false;
+    }
+
+    if(mdpCount > (sMaxPipesPerMixer-fbNeeded)) {
+        ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
+        return false;
+    }
+
+    if(pipesNeeded(ctx, list) > getAvailablePipes(ctx)) {
+        ALOGD_IF(isDebug(), "%s: Insufficient MDP pipes",__FUNCTION__);
+        return false;
+    }
+
+    if(isSkipPresent(ctx, mDpy)) {
+        ALOGD_IF(isDebug(), "%s: Skip layers present",__FUNCTION__);
+        return false;
+    }
+
     //FB composition on idle timeout
     if(sIdleFallBack) {
         sIdleFallBack = false;
@@ -325,11 +372,6 @@
         return false;
     }
 
-    if(ctx->mNeedsRotator && ctx->mDMAInUse) {
-        ALOGD_IF(isDebug(), "%s: DMA not available for Rotator",__FUNCTION__);
-        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
@@ -350,65 +392,258 @@
     return true;
 }
 
-bool MDPComp::setup(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
-    const int dpy = HWC_DISPLAY_PRIMARY;
-    if(!ctx) {
-        ALOGE("%s: invalid context", __FUNCTION__);
-        return -1;
-    }
+/* Checks for conditions where YUV layers cannot be bypassed */
+bool MDPComp::isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer) {
 
-    ctx->mDMAInUse = false;
-    if(!allocLayerPipes(ctx, list, mCurrentFrame)) {
-        ALOGD_IF(isDebug(), "%s: Falling back to FB", __FUNCTION__);
+    if(isSkipLayer(layer)) {
+        ALOGE("%s: Unable to bypass skipped YUV", __FUNCTION__);
         return false;
     }
 
-    for (int index = 0 ; index < mCurrentFrame.count; index++) {
-        hwc_layer_1_t* layer = &list->hwLayers[index];
-        if(configure(ctx, layer, mCurrentFrame.pipeLayer[index]) != 0 ) {
-            ALOGD_IF(isDebug(), "%s: MDPComp failed to configure overlay for \
-                    layer %d",__FUNCTION__, index);
+    if(ctx->mNeedsRotator && ctx->mDMAInUse) {
+        ALOGE("%s: No DMA for Rotator",__FUNCTION__);
+        return false;
+    }
+
+    if(isSecuring(ctx, layer)) {
+        ALOGD_IF(isDebug(), "%s: MDP securing is active", __FUNCTION__);
+        return false;
+    }
+
+    /* Workaround for downscales larger than 4x. Will be removed once decimator
+     * block is enabled for MDSS*/
+    if(ctx->mMDP.version == qdutils::MDSS_V5) {
+        hwc_rect_t crop = layer->sourceCrop;
+        hwc_rect_t dst = layer->displayFrame;
+
+        int cWidth = crop.right - crop.left;
+        int cHeight = crop.bottom - crop.top;
+        int dWidth = dst.right - dst.left;
+        int dHeight = dst.bottom - dst.top;
+
+        if((cWidth/dWidth) > 4 || (cHeight/dHeight) > 4)
             return false;
-        }
     }
     return true;
 }
 
-bool MDPComp::prepare(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list) {
-    if(!isEnabled()) {
-        ALOGE_IF(isDebug(),"%s: MDP Comp. not enabled.", __FUNCTION__);
-        return false;
+void  MDPComp::batchLayers() {
+    /* Idea is to keep as many contiguous non-updating(cached) layers in FB and
+     * send rest of them through MDP. NEVER mark an updating layer for caching.
+     * But cached ones can be marked for MDP*/
+
+    int maxBatchStart = -1;
+    int maxBatchCount = 0;
+
+    /* All or Nothing is cached. No batching needed */
+    if(!mCurrentFrame.fbCount ||
+       (mCurrentFrame.fbCount ==  mCurrentFrame.layerCount))
+        return;
+
+    /* Search for max number of contiguous (cached) layers */
+    int i = 0;
+    while (i < mCurrentFrame.layerCount) {
+        int count = 0;
+        while(mCurrentFrame.isFBComposed[i] && i < mCurrentFrame.layerCount) {
+            count++; i++;
+        }
+        if(count > maxBatchCount) {
+            maxBatchCount = count;
+            maxBatchStart = i - count;
+        }
+        if(i < mCurrentFrame.layerCount) i++;
     }
 
+    /* reset rest of the layers for MDP comp */
+    for(int i = 0; i < mCurrentFrame.layerCount; i++) {
+        if(i != maxBatchStart){
+            mCurrentFrame.isFBComposed[i] = false;
+        } else {
+            i += maxBatchCount;
+        }
+    }
+
+    mCurrentFrame.fbCount = maxBatchCount;
+
+    ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
+             mCurrentFrame.fbCount);
+}
+void MDPComp::updateLayerCache(hwc_context_t* ctx,
+                               hwc_display_contents_1_t* list) {
+
+    int numAppLayers = ctx->listStats[mDpy].numAppLayers;
+    int numCacheableLayers = 0;
+
+    if((list->flags & HWC_GEOMETRY_CHANGED) || (isSkipPresent(ctx, mDpy))) {
+        ALOGD_IF(isDebug(),"%s: No Caching: \
+                 GEOMETRY change: %d SKIP present: %d", __FUNCTION__,
+                 (list->flags & HWC_GEOMETRY_CHANGED),isSkipPresent(ctx, mDpy));
+        mCachedFrame.reset();
+        return;
+    }
+
+    for(int i = 0; i < numAppLayers; i++) {
+        if (mCachedFrame.hnd[i] == list->hwLayers[i].handle) {
+            numCacheableLayers++;
+            mCurrentFrame.isFBComposed[i] = true;
+        } else {
+            mCachedFrame.hnd[i] = list->hwLayers[i].handle;
+        }
+    }
+    mCurrentFrame.fbCount = numCacheableLayers;
+    ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, numCacheableLayers);
+}
+
+int MDPComp::getAvailablePipes(hwc_context_t* ctx) {
+    int numDMAPipes = qdutils::MDPVersion::getInstance().getDMAPipes();
     overlay::Overlay& ov = *ctx->mOverlay;
-    bool isMDPCompUsed = true;
+
+    int numAvailable = ov.availablePipes(mDpy);
+
+    //Reserve DMA for rotator
+    if(ctx->mNeedsRotator)
+        numAvailable -= numDMAPipes;
+
+    //Reserve pipe(s)for FB
+    if(mCurrentFrame.fbCount)
+        numAvailable -= pipesForFB();
+
+    return numAvailable;
+}
+
+void MDPComp::resetFrameForFB(hwc_context_t* ctx,
+                              hwc_display_contents_1_t* list) {
+    mCurrentFrame.fbCount = mCurrentFrame.layerCount;
+    memset(&mCurrentFrame.isFBComposed, 1,
+           sizeof(mCurrentFrame.isFBComposed));
+    mCurrentFrame.needsRedraw = true;
+}
+
+void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
+
+    int nYuvCount = ctx->listStats[mDpy].yuvCount;
+    for(int index = 0;index < nYuvCount; index++){
+        int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
+        hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
+
+        if(!isYUVDoable(ctx, layer)) {
+            if(!mCurrentFrame.isFBComposed[nYuvIndex]) {
+                mCurrentFrame.isFBComposed[nYuvIndex] = true;
+                mCurrentFrame.fbCount++;
+            }
+        } else {
+            if(mCurrentFrame.isFBComposed[nYuvIndex]) {
+                mCurrentFrame.isFBComposed[nYuvIndex] = false;
+                mCurrentFrame.fbCount--;
+            }
+        }
+    }
+    ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__,
+             mCurrentFrame.fbCount);
+}
+
+int MDPComp::programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
+    int fbZOrder = -1;
+    ctx->mDMAInUse = false;
+
+    if(!allocLayerPipes(ctx, list)) {
+        ALOGD_IF(isDebug(), "%s: Unable to allocate MDP pipes", __FUNCTION__);
+        goto fn_exit;
+    }
+
+    for (int index = 0, mdpNextZOrder = 0; index < mCurrentFrame.layerCount;
+                                                                      index++) {
+        if(!mCurrentFrame.isFBComposed[index]) {
+
+            int mdpIndex = mCurrentFrame.layerToMDP[index];
+            hwc_layer_1_t* layer = &list->hwLayers[index];
+
+            MdpPipeInfo* cur_pipe = mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
+            cur_pipe->zOrder = mdpNextZOrder++;
+
+            if(configure(ctx, layer, mCurrentFrame.mdpToLayer[mdpIndex]) != 0 ){
+                ALOGD_IF(isDebug(), "%s: Failed to configure overlay for \
+                         layer %d",__FUNCTION__, index);
+                goto fn_exit;
+            }
+        } else if(fbZOrder < 0) {
+            fbZOrder = mdpNextZOrder++;
+        };
+    }
+
+    return fbZOrder;
+
+ fn_exit:
+        //Complete fallback to FB
+        resetFrameForFB(ctx, list);
+        return 0;
+}
+
+int MDPComp::prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
 
     //reset old data
-    reset(ctx, list);
+    mCurrentFrame.reset();
 
-    bool doable = isDoable(ctx, list);
-    if(doable) {
-        if(setup(ctx, list)) {
-            setMDPCompLayerFlags(ctx, list);
-        } else {
-            ALOGD_IF(isDebug(),"%s: MDP Comp Failed",__FUNCTION__);
-            isMDPCompUsed = false;
+    if(!isFrameDoable(ctx)) {
+        ALOGD_IF( isDebug(),"%s: MDP Comp not possible for this frame",
+                  __FUNCTION__);
+        return 0;
+    }
+
+    mCurrentFrame.layerCount = ctx->listStats[mDpy].numAppLayers;
+
+    //Iterate layer list for cached layers
+    updateLayerCache(ctx, list);
+
+    //Add YUV layers to cached list
+    updateYUV(ctx, list);
+
+    //Optimze for bypass
+    batchLayers();
+
+    //list is already parsed / batched for optimal mixed mode composition.
+    //Check whether layers marked for MDP Composition is actually doable.
+    if(!isFullFrameDoable(ctx, list)){
+        //All layers marked for MDP comp cannot be bypassed.
+        //Try to compose atleast YUV layers through MDP comp and let
+        //all the RGB layers compose in FB
+        resetFrameForFB(ctx, list);
+        updateYUV(ctx, list);
+    }
+
+    mCurrentFrame.mdpCount = mCurrentFrame.layerCount -
+                             mCurrentFrame.fbCount;
+
+    if(mCurrentFrame.mdpCount) {
+        // populate layer and MDP maps
+        for(int idx = 0, mdpIdx = 0; idx < mCurrentFrame.layerCount; idx++) {
+            if(!mCurrentFrame.isFBComposed[idx]) {
+                mCurrentFrame.mdpToLayer[mdpIdx].listIndex = idx;
+                mCurrentFrame.layerToMDP[idx] = mdpIdx++;
+            }
         }
-    } else {
-        ALOGD_IF( isDebug(),"%s: MDP Comp not possible[%d]",__FUNCTION__,
-                doable);
-        isMDPCompUsed = false;
+        //Acquire and Program MDP pipes
+        mCurrentFrame.fbZ = programMDP(ctx, list);
     }
 
-    //Reset states
-    if(!isMDPCompUsed) {
-        //Reset current frame
-        reset(ctx, list);
+    /* Any change in composition types needs an FB refresh*/
+    if(mCurrentFrame.fbCount &&
+       ((mCurrentFrame.mdpCount != mCachedFrame.mdpCount) ||
+       (mCurrentFrame.fbCount != mCachedFrame.cacheCount) ||
+       !mCurrentFrame.mdpCount)) {
+        mCurrentFrame.needsRedraw = true;
     }
 
-    mState = isMDPCompUsed ? MDPCOMP_ON : MDPCOMP_OFF;
-    return isMDPCompUsed;
+    //UpdateLayerFlags
+    setMDPCompLayerFlags(ctx, list);
+
+    if(isDebug()) {
+        android::String8 sDump("");
+        dump(sDump);
+        ALOGE("%s",sDump.string());
+    }
+
+    return mCurrentFrame.fbZ;
 }
 
 //=============MDPCompLowRes===================================================
@@ -417,64 +652,66 @@
  * Configures pipe(s) for MDP composition
  */
 int MDPCompLowRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
-        PipeLayerPair& pipeLayerPair) {
-    const int dpy = HWC_DISPLAY_PRIMARY;
+                             PipeLayerPair& PipeLayerPair) {
     MdpPipeInfoLowRes& mdp_info =
-            *(static_cast<MdpPipeInfoLowRes*>(pipeLayerPair.pipeInfo));
+        *(static_cast<MdpPipeInfoLowRes*>(PipeLayerPair.pipeInfo));
     eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
     eIsFg isFg = IS_FG_OFF;
     eDest dest = mdp_info.index;
 
-    return configureLowRes(ctx, layer, dpy, mdpFlags, zOrder, isFg, dest,
-            &pipeLayerPair.rot);
+    ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipe: %d",
+             __FUNCTION__, layer, zOrder, dest);
+
+    return configureLowRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
+                           &PipeLayerPair.rot);
 }
 
 int MDPCompLowRes::pipesNeeded(hwc_context_t *ctx,
-                        hwc_display_contents_1_t* list) {
-    const int dpy = HWC_DISPLAY_PRIMARY;
-    return ctx->listStats[dpy].numAppLayers;
+                               hwc_display_contents_1_t* list) {
+    return mCurrentFrame.mdpCount;
 }
 
 bool MDPCompLowRes::allocLayerPipes(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list,
-        FrameInfo& currentFrame) {
-    const int dpy = HWC_DISPLAY_PRIMARY;
-    overlay::Overlay& ov = *ctx->mOverlay;
-    int layer_count = ctx->listStats[dpy].numAppLayers;
+                                    hwc_display_contents_1_t* list) {
+    if(isYuvPresent(ctx, mDpy)) {
+        int nYuvCount = ctx->listStats[mDpy].yuvCount;
 
-    currentFrame.count = layer_count;
-    currentFrame.pipeLayer = (PipeLayerPair*)
-            malloc(sizeof(PipeLayerPair) * currentFrame.count);
+        for(int index = 0; index < nYuvCount ; index ++) {
+            int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
 
-    if(isYuvPresent(ctx, dpy)) {
-        int nYuvCount = ctx->listStats[dpy].yuvCount;
+            if(mCurrentFrame.isFBComposed[nYuvIndex])
+                continue;
 
-        for(int index = 0; index < nYuvCount; index ++) {
-            int nYuvIndex = ctx->listStats[dpy].yuvIndices[index];
             hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
-            PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
+
+            int mdpIndex = mCurrentFrame.layerToMDP[nYuvIndex];
+
+            PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
             info.pipeInfo = new MdpPipeInfoLowRes;
             info.rot = NULL;
             MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo;
+
             pipe_info.index = getMdpPipe(ctx, MDPCOMP_OV_VG);
             if(pipe_info.index == ovutils::OV_INVALID) {
                 ALOGD_IF(isDebug(), "%s: Unable to get pipe for Videos",
-                        __FUNCTION__);
+                         __FUNCTION__);
                 return false;
             }
-            pipe_info.zOrder = nYuvIndex;
         }
     }
 
-    for(int index = 0 ; index < layer_count ; index++ ) {
+    for(int index = 0 ; index < mCurrentFrame.layerCount; index++ ) {
+        if(mCurrentFrame.isFBComposed[index]) continue;
         hwc_layer_1_t* layer = &list->hwLayers[index];
         private_handle_t *hnd = (private_handle_t *)layer->handle;
 
         if(isYuvBuffer(hnd))
             continue;
 
-        PipeLayerPair& info = currentFrame.pipeLayer[index];
+        int mdpIndex = mCurrentFrame.layerToMDP[index];
+
+        PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
         info.pipeInfo = new MdpPipeInfoLowRes;
         info.rot = NULL;
         MdpPipeInfoLowRes& pipe_info = *(MdpPipeInfoLowRes*)info.pipeInfo;
@@ -482,7 +719,7 @@
         ePipeType type = MDPCOMP_OV_ANY;
 
         if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator
-                             && ctx->mMDP.version >= qdutils::MDSS_V5) {
+           && ctx->mMDP.version >= qdutils::MDSS_V5) {
             type = MDPCOMP_OV_DMA;
         }
 
@@ -491,14 +728,13 @@
             ALOGD_IF(isDebug(), "%s: Unable to get pipe for UI", __FUNCTION__);
             return false;
         }
-        pipe_info.zOrder = index;
     }
     return true;
 }
 
 bool MDPCompLowRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
 
-    if(!isEnabled() || !isUsed()) {
+    if(!isEnabled()) {
         ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
         return true;
     }
@@ -509,16 +745,17 @@
     }
 
     /* reset Invalidator */
-    if(idleInvalidator)
+    if(idleInvalidator && mCurrentFrame.mdpCount)
         idleInvalidator->markForSleep();
 
-    const int dpy = HWC_DISPLAY_PRIMARY;
     overlay::Overlay& ov = *ctx->mOverlay;
-    LayerProp *layerProp = ctx->layerProp[dpy];
+    LayerProp *layerProp = ctx->layerProp[mDpy];
 
-    int numHwLayers = ctx->listStats[dpy].numAppLayers;
-    for(int i = 0; i < numHwLayers; i++ )
+    int numHwLayers = ctx->listStats[mDpy].numAppLayers;
+    for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
     {
+        if(mCurrentFrame.isFBComposed[i]) continue;
+
         hwc_layer_1_t *layer = &list->hwLayers[i];
         private_handle_t *hnd = (private_handle_t *)layer->handle;
         if(!hnd) {
@@ -526,8 +763,10 @@
             return false;
         }
 
+        int mdpIndex = mCurrentFrame.layerToMDP[i];
+
         MdpPipeInfoLowRes& pipe_info =
-                *(MdpPipeInfoLowRes*)mCurrentFrame.pipeLayer[i].pipeInfo;
+            *(MdpPipeInfoLowRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
         ovutils::eDest dest = pipe_info.index;
         if(dest == ovutils::OV_INVALID) {
             ALOGE("%s: Invalid pipe index (%d)", __FUNCTION__, dest);
@@ -539,12 +778,12 @@
         }
 
         ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
-                using  pipe: %d", __FUNCTION__, layer,
-                hnd, dest );
+                 using  pipe: %d", __FUNCTION__, layer,
+                 hnd, dest );
 
         int fd = hnd->fd;
         uint32_t offset = hnd->offset;
-        Rotator *rot = mCurrentFrame.pipeLayer[i].rot;
+        Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
         if(rot) {
             if(!rot->queueBuffer(fd, offset))
                 return false;
@@ -565,77 +804,70 @@
 //=============MDPCompHighRes===================================================
 
 int MDPCompHighRes::pipesNeeded(hwc_context_t *ctx,
-                        hwc_display_contents_1_t* list) {
-    const int dpy = HWC_DISPLAY_PRIMARY;
-    int numAppLayers = ctx->listStats[dpy].numAppLayers;
+                                hwc_display_contents_1_t* list) {
     int pipesNeeded = 0;
+    int hw_w = ctx->dpyAttr[mDpy].xres;
 
-    int hw_w = ctx->dpyAttr[dpy].xres;
-
-    for(int i = 0; i < numAppLayers; ++i) {
-        hwc_layer_1_t* layer = &list->hwLayers[i];
-        hwc_rect_t dst = layer->displayFrame;
-      if(dst.left > hw_w/2) {
-          pipesNeeded++;
-      } else if(dst.right <= hw_w/2) {
-          pipesNeeded++;
-      } else {
-          pipesNeeded += 2;
-      }
+    for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
+        if(!mCurrentFrame.isFBComposed[i]) {
+            hwc_layer_1_t* layer = &list->hwLayers[i];
+            hwc_rect_t dst = layer->displayFrame;
+            if(dst.left > hw_w/2) {
+                pipesNeeded++;
+            } else if(dst.right <= hw_w/2) {
+                pipesNeeded++;
+            } else {
+                pipesNeeded += 2;
+            }
+        }
     }
     return pipesNeeded;
 }
 
 bool MDPCompHighRes::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
-                        MdpPipeInfoHighRes& pipe_info, ePipeType type) {
-     const int dpy = HWC_DISPLAY_PRIMARY;
-     int hw_w = ctx->dpyAttr[dpy].xres;
+                                     MdpPipeInfoHighRes& pipe_info,
+                                     ePipeType type) {
+    int hw_w = ctx->dpyAttr[mDpy].xres;
 
-     hwc_rect_t dst = layer->displayFrame;
-     if(dst.left > hw_w/2) {
-         pipe_info.lIndex = ovutils::OV_INVALID;
-         pipe_info.rIndex = getMdpPipe(ctx, type);
-         if(pipe_info.rIndex == ovutils::OV_INVALID)
-             return false;
-     } else if (dst.right <= hw_w/2) {
-         pipe_info.rIndex = ovutils::OV_INVALID;
-         pipe_info.lIndex = getMdpPipe(ctx, type);
-         if(pipe_info.lIndex == ovutils::OV_INVALID)
-             return false;
-     } else {
-         pipe_info.rIndex = getMdpPipe(ctx, type);
-         pipe_info.lIndex = getMdpPipe(ctx, type);
-         if(pipe_info.rIndex == ovutils::OV_INVALID ||
-            pipe_info.lIndex == ovutils::OV_INVALID)
-             return false;
-     }
-     return true;
+    hwc_rect_t dst = layer->displayFrame;
+    if(dst.left > hw_w/2) {
+        pipe_info.lIndex = ovutils::OV_INVALID;
+        pipe_info.rIndex = getMdpPipe(ctx, type);
+        if(pipe_info.rIndex == ovutils::OV_INVALID)
+            return false;
+    } else if (dst.right <= hw_w/2) {
+        pipe_info.rIndex = ovutils::OV_INVALID;
+        pipe_info.lIndex = getMdpPipe(ctx, type);
+        if(pipe_info.lIndex == ovutils::OV_INVALID)
+            return false;
+    } else {
+        pipe_info.rIndex = getMdpPipe(ctx, type);
+        pipe_info.lIndex = getMdpPipe(ctx, type);
+        if(pipe_info.rIndex == ovutils::OV_INVALID ||
+           pipe_info.lIndex == ovutils::OV_INVALID)
+            return false;
+    }
+    return true;
 }
 
 bool MDPCompHighRes::allocLayerPipes(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list,
-        FrameInfo& currentFrame) {
-    const int dpy = HWC_DISPLAY_PRIMARY;
+                                     hwc_display_contents_1_t* list) {
     overlay::Overlay& ov = *ctx->mOverlay;
-    int layer_count = ctx->listStats[dpy].numAppLayers;
+    int layer_count = ctx->listStats[mDpy].numAppLayers;
 
-    currentFrame.count = layer_count;
-    currentFrame.pipeLayer = (PipeLayerPair*)
-            malloc(sizeof(PipeLayerPair) * currentFrame.count);
-
-    if(isYuvPresent(ctx, dpy)) {
-        int nYuvCount = ctx->listStats[dpy].yuvCount;
+    if(isYuvPresent(ctx, mDpy)) {
+        int nYuvCount = ctx->listStats[mDpy].yuvCount;
 
         for(int index = 0; index < nYuvCount; index ++) {
-            int nYuvIndex = ctx->listStats[dpy].yuvIndices[index];
+            int nYuvIndex = ctx->listStats[mDpy].yuvIndices[index];
             hwc_layer_1_t* layer = &list->hwLayers[nYuvIndex];
-            PipeLayerPair& info = currentFrame.pipeLayer[nYuvIndex];
+            PipeLayerPair& info = mCurrentFrame.mdpToLayer[nYuvIndex];
             info.pipeInfo = new MdpPipeInfoHighRes;
             info.rot = NULL;
             MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo;
             if(!acquireMDPPipes(ctx, layer, pipe_info,MDPCOMP_OV_VG)) {
                 ALOGD_IF(isDebug(),"%s: Unable to get pipe for videos",
-                                                            __FUNCTION__);
+                         __FUNCTION__);
                 //TODO: windback pipebook data on fail
                 return false;
             }
@@ -650,7 +882,7 @@
         if(isYuvBuffer(hnd))
             continue;
 
-        PipeLayerPair& info = currentFrame.pipeLayer[index];
+        PipeLayerPair& info = mCurrentFrame.mdpToLayer[index];
         info.pipeInfo = new MdpPipeInfoHighRes;
         info.rot = NULL;
         MdpPipeInfoHighRes& pipe_info = *(MdpPipeInfoHighRes*)info.pipeInfo;
@@ -658,7 +890,7 @@
         ePipeType type = MDPCOMP_OV_ANY;
 
         if(!qhwc::needsScaling(layer) && !ctx->mNeedsRotator
-                             && ctx->mMDP.version >= qdutils::MDSS_V5)
+           && ctx->mMDP.version >= qdutils::MDSS_V5)
             type = MDPCOMP_OV_DMA;
 
         if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
@@ -674,22 +906,25 @@
  * Configures pipe(s) for MDP composition
  */
 int MDPCompHighRes::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
-        PipeLayerPair& pipeLayerPair) {
-    const int dpy = HWC_DISPLAY_PRIMARY;
+                              PipeLayerPair& PipeLayerPair) {
     MdpPipeInfoHighRes& mdp_info =
-            *(static_cast<MdpPipeInfoHighRes*>(pipeLayerPair.pipeInfo));
+        *(static_cast<MdpPipeInfoHighRes*>(PipeLayerPair.pipeInfo));
     eZorder zOrder = static_cast<eZorder>(mdp_info.zOrder);
     eIsFg isFg = IS_FG_OFF;
     eMdpFlags mdpFlagsL = OV_MDP_BACKEND_COMPOSITION;
     eDest lDest = mdp_info.lIndex;
     eDest rDest = mdp_info.rIndex;
-    return configureHighRes(ctx, layer, dpy, mdpFlagsL, zOrder, isFg, lDest,
-            rDest, &pipeLayerPair.rot);
+
+    ALOGD_IF(isDebug(),"%s: configuring: layer: %p z_order: %d dest_pipeL: %d"
+             "dest_pipeR: %d",__FUNCTION__, layer, zOrder, lDest, rDest);
+
+    return configureHighRes(ctx, layer, mDpy, mdpFlagsL, zOrder, isFg, lDest,
+                            rDest, &PipeLayerPair.rot);
 }
 
 bool MDPCompHighRes::draw(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
 
-    if(!isEnabled() || !isUsed()) {
+    if(!isEnabled()) {
         ALOGD_IF(isDebug(),"%s: MDP Comp not configured", __FUNCTION__);
         return true;
     }
@@ -700,16 +935,17 @@
     }
 
     /* reset Invalidator */
-    if(idleInvalidator)
+    if(idleInvalidator && mCurrentFrame.mdpCount)
         idleInvalidator->markForSleep();
 
-    const int dpy = HWC_DISPLAY_PRIMARY;
     overlay::Overlay& ov = *ctx->mOverlay;
-    LayerProp *layerProp = ctx->layerProp[dpy];
+    LayerProp *layerProp = ctx->layerProp[mDpy];
 
-    int numHwLayers = ctx->listStats[dpy].numAppLayers;
-    for(int i = 0; i < numHwLayers; i++ )
+    int numHwLayers = ctx->listStats[mDpy].numAppLayers;
+    for(int i = 0; i < numHwLayers && mCurrentFrame.mdpCount; i++ )
     {
+        if(mCurrentFrame.isFBComposed[i]) continue;
+
         hwc_layer_1_t *layer = &list->hwLayers[i];
         private_handle_t *hnd = (private_handle_t *)layer->handle;
         if(!hnd) {
@@ -721,12 +957,15 @@
             continue;
         }
 
+        int mdpIndex = mCurrentFrame.layerToMDP[i];
+
         MdpPipeInfoHighRes& pipe_info =
-                *(MdpPipeInfoHighRes*)mCurrentFrame.pipeLayer[i].pipeInfo;
-        Rotator *rot = mCurrentFrame.pipeLayer[i].rot;
+            *(MdpPipeInfoHighRes*)mCurrentFrame.mdpToLayer[mdpIndex].pipeInfo;
+        Rotator *rot = mCurrentFrame.mdpToLayer[mdpIndex].rot;
 
         ovutils::eDest indexL = pipe_info.lIndex;
         ovutils::eDest indexR = pipe_info.rIndex;
+
         int fd = hnd->fd;
         int offset = hnd->offset;
 
@@ -740,7 +979,7 @@
         if(indexL != ovutils::OV_INVALID) {
             ovutils::eDest destL = (ovutils::eDest)indexL;
             ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
-                    using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
+                     using  pipe: %d", __FUNCTION__, layer, hnd, indexL );
             if (!ov.queueBuffer(fd, offset, destL)) {
                 ALOGE("%s: queueBuffer failed for left mixer", __FUNCTION__);
                 return false;
@@ -751,7 +990,7 @@
         if(indexR != ovutils::OV_INVALID) {
             ovutils::eDest destR = (ovutils::eDest)indexR;
             ALOGD_IF(isDebug(),"%s: MDP Comp: Drawing layer: %p hnd: %p \
-                    using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
+                     using  pipe: %d", __FUNCTION__, layer, hnd, indexR );
             if (!ov.queueBuffer(fd, offset, destR)) {
                 ALOGE("%s: queueBuffer failed for right mixer", __FUNCTION__);
                 return false;
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index d847f56..7970cd3 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -29,7 +29,7 @@
 #define MAX_PIPES_PER_MIXER 4
 
 namespace overlay {
-    class Rotator;
+class Rotator;
 };
 
 namespace qhwc {
@@ -37,74 +37,104 @@
 
 class MDPComp {
 public:
+    explicit MDPComp(int);
     virtual ~MDPComp(){};
     /*sets up mdp comp for the current frame */
-    bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list);
+    int prepare(hwc_context_t *ctx, hwc_display_contents_1_t* list);
     /* draw */
     virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list) = 0;
-
+    /* dumpsys */
     void dump(android::String8& buf);
-    bool isUsed() { return (mState == MDPCOMP_ON); };
 
-    static MDPComp* getObject(const int& width);
+    static MDPComp* getObject(const int& width, const int dpy);
     /* Handler to invoke frame redraw on Idle Timer expiry */
     static void timeout_handler(void *udata);
+    /* Initialize MDP comp*/
     static bool init(hwc_context_t *ctx);
 
 protected:
-    enum eState {
-        MDPCOMP_ON = 0,
-        MDPCOMP_OFF,
-    };
-
     enum ePipeType {
         MDPCOMP_OV_RGB = ovutils::OV_MDP_PIPE_RGB,
         MDPCOMP_OV_VG = ovutils::OV_MDP_PIPE_VG,
         MDPCOMP_OV_DMA = ovutils::OV_MDP_PIPE_DMA,
         MDPCOMP_OV_ANY,
     };
+
+    /* mdp pipe data */
     struct MdpPipeInfo {
         int zOrder;
         virtual ~MdpPipeInfo(){};
     };
+
+    /* per layer data */
     struct PipeLayerPair {
         MdpPipeInfo *pipeInfo;
-        native_handle_t* handle;
         overlay::Rotator* rot;
+        int listIndex;
     };
 
-    /* introduced for mixed mode implementation */
+    /* per frame data */
     struct FrameInfo {
-        int count;
-        struct PipeLayerPair* pipeLayer;
+        /* maps layer list to mdp list */
+        int layerCount;
+        int layerToMDP[MAX_NUM_LAYERS];
+
+        /* maps mdp list to layer list */
+        int mdpCount;
+        struct PipeLayerPair mdpToLayer[MAX_PIPES_PER_MIXER];
+
+        /* layer composing on FB? */
+        int fbCount;
+        bool isFBComposed[MAX_NUM_LAYERS];
+
+        bool needsRedraw;
+        int fbZ;
+
+        /* c'tor */
+        FrameInfo();
+        /* clear old frame data */
+        void reset();
     };
 
+    /* cached data */
+    struct LayerCache {
+        int layerCount;
+        int mdpCount;
+        int cacheCount;
+        buffer_handle_t hnd[MAX_NUM_LAYERS];
+
+        /* c'tor */
+        LayerCache();
+        /* clear caching info*/
+        void reset();
+    };
+
+    /* No of pipes needed for Framebuffer */
+    virtual int pipesForFB() = 0;
     /* calculates pipes needed for the panel */
     virtual int pipesNeeded(hwc_context_t *ctx,
                             hwc_display_contents_1_t* list) = 0;
     /* allocates pipe from pipe book */
     virtual bool allocLayerPipes(hwc_context_t *ctx,
-                hwc_display_contents_1_t* list,FrameInfo& current_frame) = 0;
+                                 hwc_display_contents_1_t* list) = 0;
     /* configures MPD pipes */
     virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
-                PipeLayerPair& pipeLayerPair) = 0;
+                          PipeLayerPair& pipeLayerPair) = 0;
 
 
     /* set/reset flags for MDPComp */
     void setMDPCompLayerFlags(hwc_context_t *ctx,
-                                       hwc_display_contents_1_t* list);
-    void unsetMDPCompLayerFlags(hwc_context_t* ctx,
-                                       hwc_display_contents_1_t* list);
-    /* get/set states */
-    eState getState() { return mState; };
-    /* reset state */
-    void reset( hwc_context_t *ctx, hwc_display_contents_1_t* list );
+                              hwc_display_contents_1_t* list);
     /* allocate MDP pipes from overlay */
     ovutils::eDest getMdpPipe(hwc_context_t *ctx, ePipeType type);
+
     /* checks for conditions where mdpcomp is not possible */
-    bool isDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
-    /* sets up MDP comp for current frame */
-    bool setup(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+    bool isFrameDoable(hwc_context_t *ctx);
+    /* checks for conditions where RGB layers cannot be bypassed */
+    bool isFullFrameDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
+    /* checks for conditions where YUV layers cannot be bypassed */
+    bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
+
     /* set up Border fill as Base pipe */
     static bool setupBasePipe(hwc_context_t*);
     /* Is debug enabled */
@@ -113,20 +143,34 @@
     static bool isEnabled() { return sEnabled; };
     /* checks for mdp comp width limitation */
     bool isWidthValid(hwc_context_t *ctx, hwc_layer_1_t *layer);
+    /* tracks non updating layers*/
+    void updateLayerCache(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+    /* resets cache for complete fallback */
+    void resetFrameForFB(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+    /* optimize layers for mdp comp*/
+    void batchLayers();
+    /* gets available pipes for mdp comp */
+    int getAvailablePipes(hwc_context_t* ctx);
+    /* updates cache map with YUV info */
+    void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+    int programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list);
 
-    eState mState;
 
+    int mDpy;
     static bool sEnabled;
     static bool sDebugLogs;
     static bool sIdleFallBack;
+    static int sMaxPipesPerMixer;
     static IdleInvalidator *idleInvalidator;
     struct FrameInfo mCurrentFrame;
+    struct LayerCache mCachedFrame;
 };
 
 class MDPCompLowRes : public MDPComp {
 public:
-     virtual ~MDPCompLowRes(){};
-     virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
+    explicit MDPCompLowRes(int dpy):MDPComp(dpy){};
+    virtual ~MDPCompLowRes(){};
+    virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
 
 private:
     struct MdpPipeInfoLowRes : public MdpPipeInfo {
@@ -134,21 +178,21 @@
         virtual ~MdpPipeInfoLowRes() {};
     };
 
+    virtual int pipesForFB() { return 1; };
     /* configure's overlay pipes for the frame */
     virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
-            PipeLayerPair& pipeLayerPair);
+                          PipeLayerPair& pipeLayerPair);
 
     /* allocates pipes to selected candidates */
     virtual bool allocLayerPipes(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list,
-            FrameInfo& current_frame);
+                                 hwc_display_contents_1_t* list);
 
-    virtual int pipesNeeded(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list);
+    virtual int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list);
 };
 
 class MDPCompHighRes : public MDPComp {
 public:
+    explicit MDPCompHighRes(int dpy):MDPComp(dpy){};
     virtual ~MDPCompHighRes(){};
     virtual bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
 private:
@@ -159,16 +203,16 @@
     };
 
     bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
-                        MdpPipeInfoHighRes& pipe_info, ePipeType type);
+                         MdpPipeInfoHighRes& pipe_info, ePipeType type);
 
+    virtual int pipesForFB() { return 2; };
     /* configure's overlay pipes for the frame */
     virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
-            PipeLayerPair& pipeLayerPair);
+                          PipeLayerPair& pipeLayerPair);
 
     /* allocates pipes to selected candidates */
     virtual bool allocLayerPipes(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list,
-            FrameInfo& current_frame);
+                                 hwc_display_contents_1_t* list);
 
     virtual int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list);
 };
diff --git a/libhwcomposer/hwc_uevents.cpp b/libhwcomposer/hwc_uevents.cpp
index b98db73..eb525a6 100644
--- a/libhwcomposer/hwc_uevents.cpp
+++ b/libhwcomposer/hwc_uevents.cpp
@@ -27,7 +27,7 @@
 #include <stdlib.h>
 #include "hwc_utils.h"
 #include "hwc_fbupdate.h"
-#include "hwc_video.h"
+#include "hwc_mdpcomp.h"
 #include "hwc_copybit.h"
 #include "comptype.h"
 #include "external.h"
@@ -53,12 +53,10 @@
 
 static void setup(hwc_context_t* ctx, int dpy, bool usecopybit)
 {
-    ctx->mFBUpdate[dpy] =
-            IFBUpdate::getObject(ctx->dpyAttr[dpy].xres, dpy);
+    ctx->mFBUpdate[dpy] = IFBUpdate::getObject(ctx->dpyAttr[dpy].xres, dpy);
+    ctx->mMDPComp[dpy] =  MDPComp::getObject(ctx->dpyAttr[dpy].xres, dpy);
     if(usecopybit)
         ctx->mCopyBit[dpy] = new CopyBit();
-    ctx->mVidOv[dpy] =
-            IVideoOverlay::getObject(ctx->dpyAttr[dpy].xres, dpy);
 }
 
 static void clear(hwc_context_t* ctx, int dpy)
@@ -71,9 +69,9 @@
         delete ctx->mCopyBit[dpy];
         ctx->mCopyBit[dpy] = NULL;
     }
-    if(ctx->mVidOv[dpy]) {
-        delete ctx->mVidOv[dpy];
-        ctx->mVidOv[dpy] = NULL;
+    if(ctx->mMDPComp[dpy]) {
+        delete ctx->mMDPComp[dpy];
+        ctx->mMDPComp[dpy] = NULL;
     }
 }
 
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 3245889..57f94fe 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -29,7 +29,6 @@
 #include "hwc_utils.h"
 #include "hwc_mdpcomp.h"
 #include "hwc_fbupdate.h"
-#include "hwc_video.h"
 #include "mdp_version.h"
 #include "hwc_copybit.h"
 #include "external.h"
@@ -118,10 +117,6 @@
         IFBUpdate::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
         HWC_DISPLAY_PRIMARY);
 
-    ctx->mVidOv[HWC_DISPLAY_PRIMARY] =
-        IVideoOverlay::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
-        HWC_DISPLAY_PRIMARY);
-
     // Check if the target supports copybit compostion (dyn/mdp/c2d) to
     // decide if we need to open the copybit module.
     int compositionType =
@@ -134,9 +129,11 @@
     }
 
     ctx->mExtDisplay = new ExternalDisplay(ctx);
-    for (uint32_t i = 0; i < MAX_DISPLAYS; i++)
-        ctx->mLayerCache[i] = new LayerCache();
-    ctx->mMDPComp = MDPComp::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres);
+
+    ctx->mMDPComp[HWC_DISPLAY_PRIMARY] =
+         MDPComp::getObject(ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres,
+         HWC_DISPLAY_PRIMARY);
+
     MDPComp::init(ctx);
 
     pthread_mutex_init(&(ctx->vstate.lock), NULL);
@@ -191,16 +188,12 @@
             delete ctx->mFBUpdate[i];
             ctx->mFBUpdate[i] = NULL;
         }
-        if(ctx->mVidOv[i]) {
-            delete ctx->mVidOv[i];
-            ctx->mVidOv[i] = NULL;
+        if(ctx->mMDPComp[i]) {
+            delete ctx->mMDPComp[i];
+            ctx->mMDPComp[i] = NULL;
         }
     }
 
-    if(ctx->mMDPComp) {
-        delete ctx->mMDPComp;
-        ctx->mMDPComp = NULL;
-    }
 
     pthread_mutex_destroy(&(ctx->vstate.lock));
     pthread_cond_destroy(&(ctx->vstate.cond));
@@ -361,12 +354,28 @@
     }
 }
 
-bool isSecuring(hwc_context_t* ctx) {
+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;
 }
 
@@ -693,12 +702,12 @@
             getMdpFormat(hnd->format), hnd->size);
 
     if(isYuvBuffer(hnd) && ctx->mMDP.version >= qdutils::MDP_V4_2 &&
-                ctx->mMDP.version < qdutils::MDSS_V5) {
-        downscale = getDownscaleFactor(
-                crop.right - crop.left,
-                crop.bottom - crop.top,
-                dst.right - dst.left,
-                dst.bottom - dst.top);
+       ctx->mMDP.version < qdutils::MDSS_V5) {
+        downscale =  getDownscaleFactor(
+            crop.right - crop.left,
+            crop.bottom - crop.top,
+            dst.right - dst.left,
+            dst.bottom - dst.top);
         if(downscale) {
             rotFlags = ROT_DOWNSCALE_ENABLED;
         }
@@ -839,71 +848,4 @@
 
     return 0;
 }
-
-void LayerCache::resetLayerCache(int num) {
-    for(uint32_t i = 0; i < MAX_NUM_LAYERS; i++) {
-        hnd[i] = NULL;
-    }
-    numHwLayers = num;
-}
-
-void LayerCache::updateLayerCache(hwc_display_contents_1_t* list) {
-
-    int numFbLayers = 0;
-    int numCacheableLayers = 0;
-
-    canUseLayerCache = false;
-    //Bail if geometry changed or num of layers changed
-    if(list->flags & HWC_GEOMETRY_CHANGED ||
-       list->numHwLayers != numHwLayers ) {
-        resetLayerCache(list->numHwLayers);
-        return;
-    }
-
-    for(uint32_t i = 0; i < list->numHwLayers; i++) {
-        //Bail on skip layers
-        if(list->hwLayers[i].flags & HWC_SKIP_LAYER) {
-            resetLayerCache(list->numHwLayers);
-            return;
-        }
-
-        if(list->hwLayers[i].compositionType == HWC_FRAMEBUFFER) {
-            numFbLayers++;
-            if(hnd[i] == NULL) {
-                hnd[i] = list->hwLayers[i].handle;
-            } else if (hnd[i] ==
-                       list->hwLayers[i].handle) {
-                numCacheableLayers++;
-            } else {
-                hnd[i] = NULL;
-                return;
-            }
-        } else {
-            hnd[i] = NULL;
-        }
-    }
-    if(numFbLayers == numCacheableLayers)
-        canUseLayerCache = true;
-
-    //XXX: The marking part is separate, if MDP comp wants
-    // to use it in the future. Right now getting MDP comp
-    // to use this is more trouble than it is worth.
-    markCachedLayersAsOverlay(list);
-}
-
-void LayerCache::markCachedLayersAsOverlay(hwc_display_contents_1_t* list) {
-    //This optimization only works if ALL the layer handles
-    //that were on the framebuffer didn't change.
-    if(canUseLayerCache){
-        for(uint32_t i = 0; i < list->numHwLayers; i++) {
-            if (list->hwLayers[i].handle &&
-                list->hwLayers[i].handle == hnd[i] &&
-                list->hwLayers[i].compositionType != HWC_FRAMEBUFFER_TARGET)
-            {
-                list->hwLayers[i].compositionType = HWC_OVERLAY;
-            }
-        }
-    }
-}
-
 };//namespace qhwc
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index e1f0995..9da10f4 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -106,26 +106,6 @@
     HWC_COPYBIT = 0x00000002,
 };
 
-class LayerCache {
-    public:
-    LayerCache() {
-        canUseLayerCache = false;
-        numHwLayers = 0;
-        for(uint32_t i = 0; i < MAX_NUM_LAYERS; i++) {
-            hnd[i] = NULL;
-        }
-    }
-    //LayerCache optimization
-    void updateLayerCache(hwc_display_contents_1_t* list);
-    void resetLayerCache(int num);
-    void markCachedLayersAsOverlay(hwc_display_contents_1_t* list);
-    private:
-    uint32_t numHwLayers;
-    bool canUseLayerCache;
-    buffer_handle_t hnd[MAX_NUM_LAYERS];
-
-};
-
 // -----------------------------------------------------------------------------
 // Utility functions - implemented in hwc_utils.cpp
 void dumpLayer(hwc_layer_1_t const* l);
@@ -138,7 +118,7 @@
                          const hwc_rect_t& scissor, int orient);
 void getNonWormholeRegion(hwc_display_contents_1_t* list,
                               hwc_rect_t& nwr);
-bool isSecuring(hwc_context_t* ctx);
+bool isSecuring(hwc_context_t* ctx, hwc_layer_1_t const* layer);
 bool isSecureModePolicy(int mdpVersion);
 bool isExternalActive(hwc_context_t* ctx);
 bool needsScaling(hwc_layer_1_t const* layer);
@@ -272,15 +252,13 @@
 
     //Primary and external FB updater
     qhwc::IFBUpdate *mFBUpdate[MAX_DISPLAYS];
-    qhwc::IVideoOverlay *mVidOv[MAX_DISPLAYS];
     // External display related information
     qhwc::ExternalDisplay *mExtDisplay;
     qhwc::MDPInfo mMDP;
     qhwc::DisplayAttributes dpyAttr[MAX_DISPLAYS];
     qhwc::ListStats listStats[MAX_DISPLAYS];
-    qhwc::LayerCache *mLayerCache[MAX_DISPLAYS];
     qhwc::LayerProp *layerProp[MAX_DISPLAYS];
-    qhwc::MDPComp *mMDPComp;
+    qhwc::MDPComp *mMDPComp[MAX_DISPLAYS];
 
     //Securing in progress indicator
     bool mSecuring;
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
deleted file mode 100644
index f95456b..0000000
--- a/libhwcomposer/hwc_video.cpp
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2013, 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 VIDEO_DEBUG 0
-#include <overlay.h>
-#include "hwc_video.h"
-#include "hwc_utils.h"
-#include "qdMetaData.h"
-#include "mdp_version.h"
-#include <overlayRotator.h>
-
-using overlay::Rotator;
-
-namespace qhwc {
-
-namespace ovutils = overlay::utils;
-
-//===========IVideoOverlay=========================
-IVideoOverlay* IVideoOverlay::getObject(const int& width, const int& dpy) {
-    if(width > MAX_DISPLAY_DIM) {
-        return new VideoOverlayHighRes(dpy);
-    }
-    return new VideoOverlayLowRes(dpy);
-}
-
-//===========VideoOverlayLowRes=========================
-
-VideoOverlayLowRes::VideoOverlayLowRes(const int& dpy): IVideoOverlay(dpy) {}
-
-//Cache stats, figure out the state, config overlay
-bool VideoOverlayLowRes::prepare(hwc_context_t *ctx,
-        hwc_display_contents_1_t *list) {
-
-    if(ctx->listStats[mDpy].yuvCount > 1)
-        return false;
-
-    int yuvIndex =  ctx->listStats[mDpy].yuvIndices[0];
-    int hw_w = ctx->dpyAttr[mDpy].xres;
-    mModeOn = false;
-
-    if(hw_w > MAX_DISPLAY_DIM) {
-       ALOGD_IF(VIDEO_DEBUG,"%s, \
-                      Cannot use video path for High Res Panels", __FUNCTION__);
-       return false;
-    }
-
-    if(!ctx->mMDP.hasOverlay) {
-       ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__);
-       return false;
-    }
-
-    if(isSecuring(ctx)) {
-       ALOGD_IF(VIDEO_DEBUG,"%s: MDP Secure is active", __FUNCTION__);
-       return false;
-    }
-
-    if(yuvIndex == -1 || ctx->listStats[mDpy].yuvCount != 1) {
-        return false;
-    }
-
-    //index guaranteed to be not -1 at this point
-    hwc_layer_1_t *layer = &list->hwLayers[yuvIndex];
-    if (isSecureModePolicy(ctx->mMDP.version)) {
-        private_handle_t *hnd = (private_handle_t *)layer->handle;
-        if(ctx->mSecureMode) {
-            if (! isSecureBuffer(hnd)) {
-                ALOGD_IF(VIDEO_DEBUG, "%s: Handle non-secure video layer"
-                         "during secure playback gracefully", __FUNCTION__);
-                return false;
-            }
-        } else {
-            if (isSecureBuffer(hnd)) {
-                ALOGD_IF(VIDEO_DEBUG, "%s: Handle secure video layer"
-                         "during non-secure playback gracefully", __FUNCTION__);
-                return false;
-            }
-        }
-    }
-
-    if((layer->transform & HWC_TRANSFORM_ROT_90) && ctx->mDMAInUse) {
-        ctx->mDMAInUse = false;
-        ALOGD_IF(VIDEO_DEBUG, "%s: Rotator not available since \
-                  DMA Pipe(s) are in use",__FUNCTION__);
-        return false;
-    }
-
-    if(configure(ctx, layer)) {
-        markFlags(layer);
-        mModeOn = true;
-    }
-
-    return mModeOn;
-}
-
-void VideoOverlayLowRes::markFlags(hwc_layer_1_t *layer) {
-    if(layer) {
-        layer->compositionType = HWC_OVERLAY;
-        layer->hints |= HWC_HINT_CLEAR_FB;
-    }
-}
-
-bool VideoOverlayLowRes::configure(hwc_context_t *ctx,
-        hwc_layer_1_t *layer) {
-
-    overlay::Overlay& ov = *(ctx->mOverlay);
-    private_handle_t *hnd = (private_handle_t *)layer->handle;
-    ovutils::Whf info(hnd->width, hnd->height,
-            ovutils::getMdpFormat(hnd->format), hnd->size);
-
-    //Request a VG pipe
-    ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
-    if(dest == ovutils::OV_INVALID) { //None available
-        return false;
-    }
-
-    mDest = dest;
-    ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
-    ovutils::eZorder zOrder = ovutils::ZORDER_0;
-    ovutils::eIsFg isFg = ovutils::IS_FG_OFF;
-    if (ctx->listStats[mDpy].numAppLayers == 1) {
-        isFg = ovutils::IS_FG_SET;
-    }
-
-    return (configureLowRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, dest,
-            &mRot) == 0 );
-}
-
-bool VideoOverlayLowRes::draw(hwc_context_t *ctx,
-        hwc_display_contents_1_t *list) {
-    if(!mModeOn) {
-        return true;
-    }
-
-    int yuvIndex = ctx->listStats[mDpy].yuvIndices[0];
-    if(yuvIndex == -1) {
-        return true;
-    }
-
-    private_handle_t *hnd = (private_handle_t *)
-            list->hwLayers[yuvIndex].handle;
-
-    overlay::Overlay& ov = *(ctx->mOverlay);
-    int fd = hnd->fd;
-    uint32_t offset = hnd->offset;
-    Rotator *rot = mRot;
-
-    if(rot) {
-        if(!rot->queueBuffer(fd, offset))
-            return false;
-        fd = rot->getDstMemId();
-        offset = rot->getDstOffset();
-    }
-
-    if (!ov.queueBuffer(fd, offset, mDest)) {
-        ALOGE("%s: queueBuffer failed for dpy=%d", __FUNCTION__, mDpy);
-        return false;
-    }
-
-    return true;
-}
-
-bool VideoOverlayLowRes::isModeOn() {
-    return mModeOn;
-}
-
-//===========VideoOverlayHighRes=========================
-
-VideoOverlayHighRes::VideoOverlayHighRes(const int& dpy): IVideoOverlay(dpy) {}
-
-//Cache stats, figure out the state, config overlay
-bool VideoOverlayHighRes::prepare(hwc_context_t *ctx,
-        hwc_display_contents_1_t *list) {
-
-    int yuvIndex =  ctx->listStats[mDpy].yuvIndices[0];
-    int hw_w = ctx->dpyAttr[mDpy].xres;
-    mModeOn = false;
-
-    if(!ctx->mMDP.hasOverlay) {
-       ALOGD_IF(VIDEO_DEBUG,"%s, this hw doesnt support overlay", __FUNCTION__);
-       return false;
-    }
-
-    if(yuvIndex == -1 || ctx->listStats[mDpy].yuvCount != 1) {
-        return false;
-    }
-
-    //index guaranteed to be not -1 at this point
-    hwc_layer_1_t *layer = &list->hwLayers[yuvIndex];
-    if(configure(ctx, layer)) {
-        markFlags(layer);
-        mModeOn = true;
-    }
-
-    return mModeOn;
-}
-
-void VideoOverlayHighRes::markFlags(hwc_layer_1_t *layer) {
-    if(layer) {
-        layer->compositionType = HWC_OVERLAY;
-        layer->hints |= HWC_HINT_CLEAR_FB;
-    }
-}
-
-bool VideoOverlayHighRes::configure(hwc_context_t *ctx,
-        hwc_layer_1_t *layer) {
-
-    int hw_w = ctx->dpyAttr[mDpy].xres;
-    overlay::Overlay& ov = *(ctx->mOverlay);
-    private_handle_t *hnd = (private_handle_t *)layer->handle;
-    ovutils::Whf info(hnd->width, hnd->height,
-            ovutils::getMdpFormat(hnd->format), hnd->size);
-
-    //Request a VG pipe
-    mDestL = ovutils::OV_INVALID;
-    mDestR = ovutils::OV_INVALID;
-    hwc_rect_t dst = layer->displayFrame;
-    if(dst.left > hw_w/2) {
-        mDestR = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
-        if(mDestR == ovutils::OV_INVALID)
-            return false;
-    } else if (dst.right <= hw_w/2) {
-        mDestL = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
-        if(mDestL == ovutils::OV_INVALID)
-            return false;
-    } else {
-        mDestL = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
-        mDestR = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy);
-        if(mDestL == ovutils::OV_INVALID ||
-                mDestR == ovutils::OV_INVALID)
-            return false;
-    }
-
-    ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
-    ovutils::eZorder zOrder = ovutils::ZORDER_0;
-    ovutils::eIsFg isFg = ovutils::IS_FG_OFF;
-    if (ctx->listStats[mDpy].numAppLayers == 1) {
-        isFg = ovutils::IS_FG_SET;
-    }
-
-    return (configureHighRes(ctx, layer, mDpy, mdpFlags, zOrder, isFg, mDestL,
-            mDestR, &mRot) == 0 );
-}
-
-bool VideoOverlayHighRes::draw(hwc_context_t *ctx,
-        hwc_display_contents_1_t *list) {
-    if(!mModeOn) {
-        return true;
-    }
-
-    int yuvIndex = ctx->listStats[mDpy].yuvIndices[0];
-    if(yuvIndex == -1) {
-        return true;
-    }
-
-    private_handle_t *hnd = (private_handle_t *)
-            list->hwLayers[yuvIndex].handle;
-
-    overlay::Overlay& ov = *(ctx->mOverlay);
-    int fd = hnd->fd;
-    uint32_t offset = hnd->offset;
-    Rotator *rot = mRot;
-
-    if(rot) {
-        if(!rot->queueBuffer(fd, offset))
-            return false;
-        fd = rot->getDstMemId();
-        offset = rot->getDstOffset();
-    }
-
-    if(mDestL != ovutils::OV_INVALID) {
-        if (!ov.queueBuffer(fd, offset, mDestL)) {
-            ALOGE("%s: queueBuffer failed for dpy=%d's left mixer",
-                    __FUNCTION__, mDpy);
-            return false;
-        }
-    }
-
-    if(mDestR != ovutils::OV_INVALID) {
-        if (!ov.queueBuffer(fd, offset, mDestR)) {
-            ALOGE("%s: queueBuffer failed for dpy=%d's right mixer"
-                    , __FUNCTION__, mDpy);
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool VideoOverlayHighRes::isModeOn() {
-    return mModeOn;
-}
-
-}; //namespace qhwc
diff --git a/libhwcomposer/hwc_video.h b/libhwcomposer/hwc_video.h
deleted file mode 100644
index 80a47f1..0000000
--- a/libhwcomposer/hwc_video.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation. All rights reserved.
- *
- * 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.
- */
-#ifndef HWC_VIDEO_H
-#define HWC_VIDEO_H
-
-#include "hwc_utils.h"
-#include "overlayUtils.h"
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-namespace overlay {
-    class Rotator;
-}
-
-namespace qhwc {
-namespace ovutils = overlay::utils;
-
-class IVideoOverlay {
-public:
-    explicit IVideoOverlay(const int& dpy) : mDpy(dpy), mModeOn(false),
-            mRot(NULL) {}
-    virtual ~IVideoOverlay() {};
-    virtual bool prepare(hwc_context_t *ctx,
-            hwc_display_contents_1_t *list) = 0;
-    virtual bool draw(hwc_context_t *ctx,
-            hwc_display_contents_1_t *list) = 0;
-    virtual void reset() = 0;
-    virtual bool isModeOn() = 0;
-    //Factory method that returns a low-res or high-res version
-    static IVideoOverlay *getObject(const int& width, const int& dpy);
-
-protected:
-    const int mDpy; // display to update
-    bool mModeOn; // if prepare happened
-    overlay::Rotator *mRot;
-};
-
-class VideoOverlayLowRes : public IVideoOverlay {
-public:
-    explicit VideoOverlayLowRes(const int& dpy);
-    virtual ~VideoOverlayLowRes() {};
-    bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-    bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-    void reset();
-    bool isModeOn();
-private:
-    //Configures overlay for video prim and ext
-    bool configure(hwc_context_t *ctx, hwc_layer_1_t *yuvlayer);
-    //Marks layer flags if this feature is used
-    void markFlags(hwc_layer_1_t *yuvLayer);
-    //Flags if this feature is on.
-    bool mModeOn;
-    ovutils::eDest mDest;
-};
-
-class VideoOverlayHighRes : public IVideoOverlay {
-public:
-    explicit VideoOverlayHighRes(const int& dpy);
-    virtual ~VideoOverlayHighRes() {};
-    bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-    bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-    void reset();
-    bool isModeOn();
-private:
-    //Configures overlay for video prim and ext
-    bool configure(hwc_context_t *ctx, hwc_layer_1_t *yuvlayer);
-    //Marks layer flags if this feature is used
-    void markFlags(hwc_layer_1_t *yuvLayer);
-    //Flags if this feature is on.
-    bool mModeOn;
-    ovutils::eDest mDestL;
-    ovutils::eDest mDestR;
-};
-
-//=================Inlines======================
-inline void VideoOverlayLowRes::reset() {
-    mModeOn = false;
-    mDest = ovutils::OV_INVALID;
-    mRot = NULL;
-}
-
-inline void VideoOverlayHighRes::reset() {
-    mModeOn = false;
-    mDestL = ovutils::OV_INVALID;
-    mDestR = ovutils::OV_INVALID;
-    mRot = NULL;
-}
-
-}; //namespace qhwc
-
-#endif //HWC_VIDEO_H
diff --git a/liboverlay/overlayMdssRot.cpp b/liboverlay/overlayMdssRot.cpp
index 70bf52b..cf6d6fa 100644
--- a/liboverlay/overlayMdssRot.cpp
+++ b/liboverlay/overlayMdssRot.cpp
@@ -93,6 +93,8 @@
 
 void MdssRot::setTransform(const utils::eTransform& rot)
 {
+    // reset rotation flags to avoid stale orientation values
+    mRotInfo.flags &= ~MDSS_ROT_MASK;
     int flags = utils::getMdpOrient(rot);
     if (flags != -1)
         setRotations(flags);
@@ -117,8 +119,6 @@
         return (mEnabled = false);
     }
     mRotData.id = mRotInfo.id;
-    // reset rotation flags to avoid stale orientation values
-    mRotInfo.flags &= ~MDSS_ROT_MASK;
     return true;
 }