hwc/overlay: Dynamic pipe tracking.

Remove state based pipe handling and make pipes tracked dynamically.
Add the configStart, configDone, nextPipe availablePipes APIs.
Remove setState API.

-configStart marks all pipes available.
-configDone garbage-collects unused pipe objects.
-nextPipe returns the index of next available pipe and create a corresponding
pipe object if not present
-availablePipes returns total of "unallocated" pipes. (Pipes could be allocated
but unused)

Changes in hwc adapt to the new overlay APIs.
Compile out MDP comp.
Remove unused files in overlay and hwc.
Update licenses.

Conflicts:

	libhwcomposer/hwc.cpp
	libhwcomposer/hwc_utils.cpp

Bug: 7626586
Change-Id: Id8e56901d34e5dc0fd088260d05e3e46f68ff090
Signed-off-by: Saurabh Shah <saurshah@codeaurora.org>
Signed-off-by: Iliyan Malchev <malchev@google.com>
diff --git a/libhwcomposer/Android.mk b/libhwcomposer/Android.mk
index 25946ff..76dc45f 100644
--- a/libhwcomposer/Android.mk
+++ b/libhwcomposer/Android.mk
@@ -16,7 +16,6 @@
                                  hwc_utils.cpp    \
                                  hwc_uevents.cpp  \
                                  hwc_vsync.cpp    \
-                                 hwc_mdpcomp.cpp  \
-                                 hwc_uimirror.cpp \
+                                 hwc_fbupdate.cpp \
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index a63aed7..f331f84 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -27,12 +27,11 @@
 #include <mdp_version.h>
 #include "hwc_utils.h"
 #include "hwc_video.h"
-#include "hwc_uimirror.h"
+#include "hwc_fbupdate.h"
 #include "external.h"
-#include "hwc_mdpcomp.h"
 
-#define VSYNC_DEBUG 0
 using namespace qhwc;
+#define VSYNC_DEBUG 0
 
 static int hwc_device_open(const struct hw_module_t* module,
                            const char* name,
@@ -81,7 +80,6 @@
                   hwc_display_contents_1_t** displays) {
     memset(ctx->listStats, 0, sizeof(ctx->listStats));
     for(int i = 0; i < HWC_NUM_DISPLAY_TYPES; i++){
-        ctx->overlayInUse[i] = false;
         ctx->listStats[i].yuvIndex = -1;
         hwc_display_contents_1_t *list = displays[i];
         // XXX:SurfaceFlinger no longer guarantees that this
@@ -95,6 +93,8 @@
             }
         }
     }
+    VideoOverlay::reset();
+    FBUpdate::reset();
 }
 
 static int hwc_prepare_primary(hwc_composer_device_1 *dev,
@@ -108,14 +108,8 @@
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
         if(fbLayer->handle) {
             setListStats(ctx, list, HWC_DISPLAY_PRIMARY);
-            if(VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY)) {
-                ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = true;
-            } else if(MDPComp::configure(ctx, list)) {
-                ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = true;
-            } else {
-                ctx->overlayInUse[HWC_DISPLAY_PRIMARY] = false;
-            }
             ctx->mLayerCache->updateLayerCache(list);
+            VideoOverlay::prepare(ctx, list, HWC_DISPLAY_PRIMARY);
         }
     }
     return 0;
@@ -134,16 +128,8 @@
         uint32_t last = list->numHwLayers - 1;
         hwc_layer_1_t *fbLayer = &list->hwLayers[last];
         if(fbLayer->handle) {
-            if(UIMirrorOverlay::prepare(ctx, fbLayer)) {
-                ctx->overlayInUse[HWC_DISPLAY_EXTERNAL] = true;
-            }
-
-            if(VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL)) {
-                ctx->overlayInUse[HWC_DISPLAY_EXTERNAL] = true;
-            } else {
-                ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->setState(
-                        ovutils::OV_UI_MIRROR);
-            }
+            FBUpdate::prepare(ctx, fbLayer, HWC_DISPLAY_EXTERNAL);
+            VideoOverlay::prepare(ctx, list, HWC_DISPLAY_EXTERNAL);
         }
     }
     return 0;
@@ -154,24 +140,31 @@
 {
     int ret = 0;
     hwc_context_t* ctx = (hwc_context_t*)(dev);
+    Locker::Autolock _l(ctx->mBlankLock);
     reset(ctx, numDisplays, displays);
 
-    //If securing of h/w in progress skip comp using overlay.
-    if(ctx->mSecuring == true) return 0;
+    ctx->mOverlay->configBegin();
 
-    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;
+    //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;
+            }
         }
     }
+
+    ctx->mOverlay->configDone();
+
     return ret;
 }
 
@@ -205,13 +198,14 @@
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     private_module_t* m = reinterpret_cast<private_module_t*>(
         ctx->mFbDev->common.module);
+    Locker::Autolock _l(ctx->mBlankLock);
     int ret = 0;
     ALOGD("%s: Doing Dpy=%d, blank=%d", __FUNCTION__, dpy, blank);
     switch(dpy) {
         case HWC_DISPLAY_PRIMARY:
             if(blank) {
-                Locker::Autolock _l(ctx->mBlankLock);
-                ctx->mOverlay[dpy]->setState(ovutils::OV_CLOSED);
+                ctx->mOverlay->configBegin();
+                ctx->mOverlay->configDone();
                 ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_POWERDOWN);
             } else {
                 ret = ioctl(m->framebuffer->fd, FBIOBLANK, FB_BLANK_UNBLANK);
@@ -280,10 +274,6 @@
             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) {
@@ -317,8 +307,8 @@
         private_handle_t *hnd = (private_handle_t *)fbLayer->handle;
         if(fbLayer->compositionType == HWC_FRAMEBUFFER_TARGET &&
                 !(fbLayer->flags & HWC_SKIP_LAYER) && hnd) {
-            if (!UIMirrorOverlay::draw(ctx, fbLayer)) {
-                ALOGE("%s: UIMirrorOverlay::draw fail!", __FUNCTION__);
+            if (!FBUpdate::draw(ctx, fbLayer, HWC_DISPLAY_EXTERNAL)) {
+                ALOGE("%s: FBUpdate::draw fail!", __FUNCTION__);
                 ret = -1;
             }
         }
@@ -338,11 +328,6 @@
     hwc_context_t* ctx = (hwc_context_t*)(dev);
     Locker::Autolock _l(ctx->mBlankLock);
 
-    for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
-        if(!ctx->overlayInUse[i])
-            ctx->mOverlay[i]->setState(ovutils::OV_CLOSED);
-    }
-
     for (uint32_t i = 0; i < numDisplays; i++) {
         hwc_display_contents_1_t* list = displays[i];
         switch(i) {
diff --git a/libhwcomposer/hwc_extonly.cpp b/libhwcomposer/hwc_extonly.cpp
deleted file mode 100644
index 3be9d81..0000000
--- a/libhwcomposer/hwc_extonly.cpp
+++ /dev/null
@@ -1,153 +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.
- */
-
-#include "hwc_extonly.h"
-#include "external.h"
-
-namespace qhwc {
-
-#define EXTONLY_DEBUG 0
-
-//Static Members
-ovutils::eOverlayState ExtOnly::sState = ovutils::OV_CLOSED;
-int ExtOnly::sExtCount = 0;
-int ExtOnly::sExtIndex = -1;
-bool ExtOnly::sIsExtBlock = false;
-bool ExtOnly::sIsModeOn = false;
-
-//Cache stats, figure out the state, config overlay
-bool ExtOnly::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list) {
-    sIsModeOn = false;
-    if(!ctx->mMDP.hasOverlay) {
-       ALOGD_IF(EXTONLY_DEBUG,"%s, this hw doesnt support overlay",
-            __FUNCTION__);
-       return false;
-    }
-    if(sExtIndex == -1) {
-        return false;
-    }
-    chooseState(ctx);
-    //if the state chosen above is CLOSED, skip this block.
-    if(sState != ovutils::OV_CLOSED) {
-        hwc_layer_1_t *extLayer = &list->hwLayers[sExtIndex];
-        if(configure(ctx, extLayer)) {
-            markFlags(extLayer);
-            sIsModeOn = true;
-        }
-    }
-
-    ALOGD_IF(EXTONLY_DEBUG, "%s: stats: extCount = %d, extIndex = %d,"
-            "IsExtBlock = %d, IsModeOn = %d",
-            __func__, sExtCount, sExtIndex,
-            sIsExtBlock, sIsModeOn);
-
-    return sIsModeOn;
-}
-
-void ExtOnly::chooseState(hwc_context_t *ctx) {
-    ALOGD_IF(EXTONLY_DEBUG, "%s: old state = %s", __FUNCTION__,
-            ovutils::getStateString(sState));
-
-    ovutils::eOverlayState newState = ovutils::OV_CLOSED;
-
-    if(sExtCount > 0 &&
-        ctx->mExtDisplay->getExternalDisplay()) {
-            newState = ovutils::OV_DUAL_DISP;
-    }
-
-    sState = newState;
-    ALOGD_IF(EXTONLY_DEBUG, "%s: new chosen state = %s", __FUNCTION__,
-            ovutils::getStateString(sState));
-}
-
-void ExtOnly::markFlags(hwc_layer_1_t *layer) {
-    switch(sState) {
-        case ovutils::OV_DUAL_DISP:
-            layer->compositionType = HWC_OVERLAY;
-            break;
-        default:
-            break;
-    }
-}
-
-bool ExtOnly::configure(hwc_context_t *ctx, hwc_layer_1_t *layer) {
-
-    overlay::Overlay& ov = *(ctx->mOverlay);
-    ov.setState(sState);
-    private_handle_t *hnd = (private_handle_t *)layer->handle;
-    ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
-    ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
-    ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
-    ovutils::PipeArgs parg(mdpFlags,
-            info,
-            ovutils::ZORDER_0,
-            isFgFlag,
-            ovutils::ROT_FLAG_DISABLED);
-    ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
-    ov.setSource(pargs, ovutils::OV_PIPE0);
-
-    hwc_rect_t sourceCrop = layer->sourceCrop;
-    // x,y,w,h
-    ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
-            sourceCrop.right - sourceCrop.left,
-            sourceCrop.bottom - sourceCrop.top);
-    ov.setCrop(dcrop, ovutils::OV_PIPE0);
-
-    ov.setTransform(0, ovutils::OV_PIPE0);
-
-    //Setting position same as crop
-    //FIXME stretch to full screen
-    ov.setPosition(dcrop, ovutils::OV_PIPE0);
-
-    if (!ov.commit(ovutils::OV_PIPE0)) {
-        ALOGE("%s: commit fails", __FUNCTION__);
-        return false;
-    }
-    return true;
-}
-
-bool ExtOnly::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list)
-{
-    if(!sIsModeOn || sExtIndex == -1) {
-        return true;
-    }
-
-    private_handle_t *hnd = (private_handle_t *)
-            list->hwLayers[sExtIndex].handle;
-
-    bool ret = true;
-    overlay::Overlay& ov = *(ctx->mOverlay);
-    ovutils::eOverlayState state = ov.getState();
-
-    switch (state) {
-        case ovutils::OV_DUAL_DISP:
-            // Play external
-            if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) {
-                ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
-                ret = false;
-            }
-            break;
-        default:
-            ALOGE("%s Unused state %s", __FUNCTION__,
-                    ovutils::getStateString(state));
-            break;
-    }
-
-    return ret;
-}
-
-}; //namespace qhwc
diff --git a/libhwcomposer/hwc_extonly.h b/libhwcomposer/hwc_extonly.h
deleted file mode 100644
index dccd065..0000000
--- a/libhwcomposer/hwc_extonly.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, Code Aurora Forum. 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_EXTONLY_H
-#define HWC_EXTONLY_H
-
-#include <overlay.h>
-#include "hwc_utils.h"
-
-#define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
-#define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
-
-namespace qhwc {
-//Feature for using overlay to display external-only layers on HDTV
-class ExtOnly {
-public:
-    //Sets up members and prepares overlay if conditions are met
-    static bool prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-    //Draws layer if this feature is on
-    static bool draw(hwc_context_t *ctx, hwc_display_contents_1_t *list);
-    //Receives data from hwc
-    static void setStats(int extCount, int extIndex, bool isExtBlock);
-    //resets values
-    static void reset();
-private:
-    //Choose an appropriate overlay state based on conditions
-    static void chooseState(hwc_context_t *ctx);
-    //Configures overlay
-    static bool configure(hwc_context_t *ctx, hwc_layer_1_t *layer);
-    //Marks layer flags if this feature is used
-    static void markFlags(hwc_layer_1_t *layer);
-    //returns ext-only count
-    static int getExtCount();
-
-    //The chosen overlay state.
-    static ovutils::eOverlayState sState;
-    //Number of ext-only layers in this drawing round. Used for stats/debugging.
-    //This does not reflect the closed caption layer count even though its
-    //ext-only.
-    static int sExtCount;
-    //Index of ext-only layer. If there are 2 such layers with 1 marked as BLOCK
-    //then this will hold the index of BLOCK layer.
-    static int sExtIndex;
-    //Flags if ext-only layer is BLOCK, which means only this layer (sExtIndex)
-    //is displayed even if other ext-only layers are present to block their
-    //content. This is used for stats / debugging only.
-    static bool sIsExtBlock;
-    //Flags if this feature is on.
-    static bool sIsModeOn;
-};
-
-inline void ExtOnly::setStats(int extCount, int extIndex, bool isExtBlock) {
-    sExtCount = extCount;
-    sExtIndex = extIndex;
-    sIsExtBlock = isExtBlock;
-}
-
-inline int ExtOnly::getExtCount() { return sExtCount; }
-inline void ExtOnly::reset() {
-    sExtCount = 0;
-    sExtIndex = -1;
-    sIsExtBlock = false;
-    sIsModeOn = false;
-    sState = ovutils::OV_CLOSED;
-}
-
-}; //namespace qhwc
-
-#endif //HWC_EXTONLY_H
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
new file mode 100644
index 0000000..0d0787e
--- /dev/null
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2012, 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 HWC_FB_UPDATE 0
+#include <gralloc_priv.h>
+#include <fb_priv.h>
+#include "hwc_fbupdate.h"
+#include "external.h"
+
+namespace qhwc {
+
+namespace ovutils = overlay::utils;
+
+//Static Members
+bool FBUpdate::sModeOn[] = {false};
+ovutils::eDest FBUpdate::sDest[] = {ovutils::OV_INVALID};
+
+void FBUpdate::reset() {
+    sModeOn[HWC_DISPLAY_PRIMARY] = false;
+    sModeOn[HWC_DISPLAY_EXTERNAL] = false;
+    sDest[HWC_DISPLAY_PRIMARY] = ovutils::OV_INVALID;
+    sDest[HWC_DISPLAY_EXTERNAL] = ovutils::OV_INVALID;
+}
+
+bool FBUpdate::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer, int dpy) {
+    if(!ctx->mMDP.hasOverlay) {
+        ALOGD_IF(HWC_FB_UPDATE, "%s, this hw doesnt support mirroring",
+                __FUNCTION__);
+       return false;
+    }
+
+    return (sModeOn[dpy] = configure(ctx, fblayer, dpy));
+
+}
+
+// Configure
+bool FBUpdate::configure(hwc_context_t *ctx, hwc_layer_1_t *layer, int dpy)
+{
+    bool ret = false;
+    if (LIKELY(ctx->mOverlay)) {
+        overlay::Overlay& ov = *(ctx->mOverlay);
+        private_handle_t *hnd = (private_handle_t *)layer->handle;
+        if (!hnd) {
+            ALOGE("%s:NULL private handle for layer!", __FUNCTION__);
+            return false;
+        }
+        ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
+
+        //Request an RGB pipe
+        ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, dpy);
+        if(dest == ovutils::OV_INVALID) { //None available
+            return false;
+        }
+
+        sDest[dpy] = dest;
+
+        ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
+        if(ctx->mSecureMode) {
+            ovutils::setMdpFlags(mdpFlags,
+                    ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
+        }
+
+        ovutils::PipeArgs parg(mdpFlags,
+                info,
+                ovutils::ZORDER_0,
+                ovutils::IS_FG_SET,
+                ovutils::ROT_FLAG_DISABLED);
+        ov.setSource(parg, dest);
+
+        hwc_rect_t sourceCrop = layer->sourceCrop;
+        // x,y,w,h
+        ovutils::Dim dcrop(sourceCrop.left, 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);
+        ov.setTransform(orient, dest);
+
+        hwc_rect_t displayFrame = layer->displayFrame;
+        ovutils::Dim dpos(displayFrame.left,
+                displayFrame.top,
+                displayFrame.right - displayFrame.left,
+                displayFrame.bottom - displayFrame.top);
+        ov.setPosition(dpos, dest);
+
+        ret = true;
+        if (!ov.commit(dest)) {
+            ALOGE("%s: commit fails", __FUNCTION__);
+            ret = false;
+        }
+    }
+    return ret;
+}
+
+bool FBUpdate::draw(hwc_context_t *ctx, hwc_layer_1_t *layer, int dpy)
+{
+    if(!sModeOn[dpy]) {
+        return true;
+    }
+    bool ret = true;
+    overlay::Overlay& ov = *(ctx->mOverlay);
+    ovutils::eDest dest = sDest[dpy];
+    private_handle_t *hnd = (private_handle_t *)layer->handle;
+    if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
+        ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
+        ret = false;
+    }
+    return ret;
+}
+
+//---------------------------------------------------------------------
+}; //namespace qhwc
diff --git a/libhwcomposer/hwc_uimirror.h b/libhwcomposer/hwc_fbupdate.h
similarity index 81%
rename from libhwcomposer/hwc_uimirror.h
rename to libhwcomposer/hwc_fbupdate.h
index c164d42..708eb6f 100644
--- a/libhwcomposer/hwc_uimirror.h
+++ b/libhwcomposer/hwc_fbupdate.h
@@ -17,8 +17,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#ifndef HWC_UIMIRROR_H
-#define HWC_UIMIRROR_H
+#ifndef HWC_FBUPDATE_H
+#define HWC_FBUPDATE_H
 #include "hwc_utils.h"
 #include "overlay.h"
 
@@ -26,24 +26,26 @@
 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
 
 namespace qhwc {
-//Feature for Mirroring UI on the External display
-class UIMirrorOverlay {
+namespace ovutils = overlay::utils;
+
+//Framebuffer update
+class FBUpdate {
     public:
         // Sets up members and prepares overlay if conditions are met
-        static bool prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer);
+        static bool prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer, int dpy);
         // Draws layer if this feature is on
-        static bool draw(hwc_context_t *ctx, hwc_layer_1_t *fblayer);
+        static bool draw(hwc_context_t *ctx, hwc_layer_1_t *fblayer, int dpy);
         //Reset values
         static void reset();
     private:
         //Configures overlay
-        static bool configure(hwc_context_t *ctx, hwc_layer_1_t *fblayer);
-        //The chosen overlay state.
-        static ovutils::eOverlayState sState;
+        static bool configure(hwc_context_t *ctx, hwc_layer_1_t *fblayer,
+            int dpy);
         //Flags if this feature is on.
-        static bool sIsUiMirroringOn;
+        static bool sModeOn[HWC_NUM_DISPLAY_TYPES];
+        static ovutils::eDest sDest[HWC_NUM_DISPLAY_TYPES];
 };
 
 }; //namespace qhwc
 
-#endif //HWC_UIMIRROR_H
+#endif //HWC_FBUPDATE_H
diff --git a/libhwcomposer/hwc_qbuf.h b/libhwcomposer/hwc_qbuf.h
deleted file mode 100644
index 90f7143..0000000
--- a/libhwcomposer/hwc_qbuf.h
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, Code Aurora Forum. 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.
- */
-
-#include <gralloc_priv.h>
-
-#ifndef USE_FENCE_SYNC
-#include <genlock.h>
-#endif
-
-// -----------------------------------------------------------------------------
-// QueuedBufferStore
-//This class holds currently and previously queued buffers.
-//Provides utilities to store, lock, remove, unlock.
-
-namespace qhwc{
-static const int MAX_QUEUED_BUFS = 4;
-class QueuedBufferStore {
-    public:
-    QueuedBufferStore() {
-        clearCurrent();
-        clearPrevious();
-    }
-    ~QueuedBufferStore() {}
-    void lockAndAdd(private_handle_t*);
-    //Unlocks only previous and makes the current as previous
-    void unlockAllPrevious();
-    //Unlocks previous as well as current, useful in suspend case
-    void unlockAll();
-
-    private:
-    QueuedBufferStore& operator=(const QueuedBufferStore&);
-    QueuedBufferStore(const QueuedBufferStore&);
-    bool lockBuffer(private_handle_t *hnd);
-    void unlockBuffer(private_handle_t *hnd);
-    void clearCurrent();
-    void clearPrevious();
-    void mvCurrToPrev();
-
-    //members
-    private_handle_t *current[MAX_QUEUED_BUFS]; //holds buf being queued
-    private_handle_t *previous[MAX_QUEUED_BUFS]; //holds bufs queued in prev round
-    int curCount;
-    int prevCount;
-};
-
-//Store and lock current drawing round buffers
-inline void QueuedBufferStore::lockAndAdd(private_handle_t *hnd) {
-#ifndef USE_FENCE_SYNC
-    if(lockBuffer(hnd))
-        current[curCount++] = hnd;
-#endif
-}
-
-//Unlock all previous drawing round buffers
-inline void QueuedBufferStore::unlockAllPrevious() {
-#ifndef USE_FENCE_SYNC
-    //Unlock
-    for(int i = 0; i < prevCount; i++) {
-        unlockBuffer(previous[i]);
-        previous[i] = NULL;
-    }
-    //Move current hnd to previous
-    mvCurrToPrev();
-    //Clear current
-    clearCurrent();
-#endif
-}
-
-inline void QueuedBufferStore::unlockAll() {
-#ifndef USE_FENCE_SYNC
-    //Unlocks prev and moves current to prev
-    unlockAllPrevious();
-    //Unlocks the newly populated prev if any.
-    unlockAllPrevious();
-#endif
-}
-
-//Clear currentbuf store
-inline void QueuedBufferStore::clearCurrent() {
-#ifndef USE_FENCE_SYNC
-    for(int i = 0; i < MAX_QUEUED_BUFS; i++)
-        current[i] = NULL;
-    curCount = 0;
-#endif
-}
-
-//Clear previousbuf store
-inline void QueuedBufferStore::clearPrevious() {
-#ifndef USE_FENCE_SYNC
-    for(int i = 0; i < MAX_QUEUED_BUFS; i++)
-        previous[i] = NULL;
-    prevCount = 0;
-#endif
-}
-
-//Copy from current to previous
-inline void QueuedBufferStore::mvCurrToPrev() {
-#ifndef USE_FENCE_SYNC
-    for(int i = 0; i < curCount; i++)
-        previous[i] = current[i];
-    prevCount = curCount;
-#endif
-}
-
-inline bool QueuedBufferStore::lockBuffer(private_handle_t *hnd) {
-#ifndef USE_FENCE_SYNC
-    if (GENLOCK_FAILURE == genlock_lock_buffer(hnd, GENLOCK_READ_LOCK,
-                                               GENLOCK_MAX_TIMEOUT)) {
-        ALOGE("%s: genlock_lock_buffer(READ) failed", __func__);
-        return false;
-    }
-#endif
-    return true;
-}
-
-inline void QueuedBufferStore::unlockBuffer(private_handle_t *hnd) {
-#ifndef USE_FENCE_SYNC
-    //Check if buffer is still around
-    if(private_handle_t::validate(hnd) != 0) {
-        ALOGE("%s Invalid Handle", __func__);
-        return;
-    }
-    //Actually try to unlock
-    if (GENLOCK_FAILURE == genlock_unlock_buffer(hnd)) {
-        ALOGE("%s: genlock_unlock_buffer failed", __func__);
-        return;
-    }
-#endif
-}
-// -----------------------------------------------------------------------------
-};//namespace
-
diff --git a/libhwcomposer/hwc_uimirror.cpp b/libhwcomposer/hwc_uimirror.cpp
deleted file mode 100644
index dd96efe..0000000
--- a/libhwcomposer/hwc_uimirror.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, 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 HWC_UI_MIRROR 0
-#include <gralloc_priv.h>
-#include <fb_priv.h>
-#include "hwc_uimirror.h"
-#include "external.h"
-
-namespace qhwc {
-
-//Static Members
-ovutils::eOverlayState UIMirrorOverlay::sState = ovutils::OV_CLOSED;
-bool UIMirrorOverlay::sIsUiMirroringOn = false;
-
-void UIMirrorOverlay::reset() {
-    sIsUiMirroringOn = false;
-    sState = ovutils::OV_CLOSED;
-}
-
-//Prepare the overlay for the UI mirroring
-bool UIMirrorOverlay::prepare(hwc_context_t *ctx, hwc_layer_1_t *fblayer) {
-    reset();
-
-    if(!ctx->mMDP.hasOverlay) {
-        ALOGD_IF(HWC_UI_MIRROR, "%s, this hw doesnt support mirroring",
-                __FUNCTION__);
-       return false;
-    }
-
-    sState = ovutils::OV_UI_MIRROR;
-    ovutils::eOverlayState newState = ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->getState();
-    if(newState == ovutils::OV_UI_VIDEO_TV) {
-        sState = newState;
-    }
-
-    configure(ctx, fblayer);
-    return sIsUiMirroringOn;
-}
-
-// Configure
-bool UIMirrorOverlay::configure(hwc_context_t *ctx, hwc_layer_1_t *layer)
-{
-    if (LIKELY(ctx->mOverlay[HWC_DISPLAY_EXTERNAL])) {
-        overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]);
-        // Set overlay state
-        ov.setState(sState);
-        private_handle_t *hnd = (private_handle_t *)layer->handle;
-        if (!hnd) {
-            ALOGE("%s:NULL private handle for layer!", __FUNCTION__);
-            return false;
-        }
-        ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
-        // Determine the RGB pipe for UI depending on the state
-        ovutils::eDest dest = ovutils::OV_PIPE0;
-
-        ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
-        if(ctx->mSecureMode) {
-            ovutils::setMdpFlags(mdpFlags,
-                    ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
-        }
-
-        ovutils::PipeArgs parg(mdpFlags,
-                info,
-                ovutils::ZORDER_0,
-                ovutils::IS_FG_OFF,
-                ovutils::ROT_FLAG_DISABLED);
-        ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
-        ov.setSource(pargs, dest);
-
-        hwc_rect_t sourceCrop = layer->sourceCrop;
-        // x,y,w,h
-        ovutils::Dim dcrop(sourceCrop.left, 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);
-        ov.setTransform(orient, dest);
-
-        hwc_rect_t displayFrame = layer->displayFrame;
-        ovutils::Dim dpos(displayFrame.left,
-                displayFrame.top,
-                displayFrame.right - displayFrame.left,
-                displayFrame.bottom - displayFrame.top);
-        ov.setPosition(dpos, dest);
-
-        if (!ov.commit(dest)) {
-            ALOGE("%s: commit fails", __FUNCTION__);
-            sIsUiMirroringOn = false;
-            return false;
-        }
-        sIsUiMirroringOn = true;
-    }
-    return sIsUiMirroringOn;
-}
-
-bool UIMirrorOverlay::draw(hwc_context_t *ctx, hwc_layer_1_t *layer)
-{
-    if(!sIsUiMirroringOn) {
-        return true;
-    }
-    bool ret = true;
-    overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]);
-    ovutils::eOverlayState state = ov.getState();
-    ovutils::eDest dest = ovutils::OV_PIPE0;
-    private_handle_t *hnd = (private_handle_t *)layer->handle;
-    switch (state) {
-        case ovutils::OV_UI_MIRROR:
-        case ovutils::OV_UI_VIDEO_TV:
-            if (!ov.queueBuffer(hnd->fd, hnd->offset, dest)) {
-                ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
-                ret = false;
-            }
-            break;
-        default:
-            break;
-    }
-    return ret;
-}
-
-//---------------------------------------------------------------------
-}; //namespace qhwc
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index a6a6f3e..dea82df 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -15,16 +15,15 @@
  * limitations under the License.
  */
 
+#include <sys/ioctl.h>
 #include <EGL/egl.h>
-#include <overlay.h>
 #include <cutils/properties.h>
 #include <gralloc_priv.h>
 #include <fb_priv.h>
+#include <overlay.h>
 #include "hwc_utils.h"
 #include "mdp_version.h"
-#include "hwc_video.h"
 #include "external.h"
-#include "hwc_mdpcomp.h"
 #include "QService.h"
 
 namespace qhwc {
@@ -52,16 +51,13 @@
 {
     openFramebufferDevice(ctx);
     overlay::Overlay::initOverlay();
-    for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
-        ctx->mOverlay[i] = overlay::Overlay::getInstance(i);
-    }
+    ctx->mOverlay = overlay::Overlay::getInstance();
     ctx->mQService = qService::QService::getInstance(ctx);
     ctx->mMDP.version = qdutils::MDPVersion::getInstance().getMDPVersion();
     ctx->mMDP.hasOverlay = qdutils::MDPVersion::getInstance().hasOverlay();
     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);
@@ -73,11 +69,9 @@
 
 void closeContext(hwc_context_t *ctx)
 {
-    for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
-        if(ctx->mOverlay[i]) {
-            delete ctx->mOverlay[i];
-            ctx->mOverlay[i] = NULL;
-        }
+    if(ctx->mOverlay) {
+        delete ctx->mOverlay;
+        ctx->mOverlay = NULL;
     }
 
     if(ctx->mFbDev) {
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 0f93dd9..e594b32 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -197,13 +197,11 @@
     hwc_composer_device_1_t device;
     const hwc_procs_t* proc;
 
-    int overlayInUse[HWC_NUM_DISPLAY_TYPES];
-
     //Framebuffer device
     framebuffer_device_t *mFbDev;
 
     //Overlay object - NULL for non overlay devices
-    overlay::Overlay *mOverlay[HWC_NUM_DISPLAY_TYPES];
+    overlay::Overlay *mOverlay;
 
     //QService object
     qService::QService *mQService;
diff --git a/libhwcomposer/hwc_video.cpp b/libhwcomposer/hwc_video.cpp
index aad2939..5fba951 100644
--- a/libhwcomposer/hwc_video.cpp
+++ b/libhwcomposer/hwc_video.cpp
@@ -22,11 +22,11 @@
 
 namespace qhwc {
 
-#define FINAL_TRANSFORM_MASK 0x000F
+namespace ovutils = overlay::utils;
 
 //Static Members
-ovutils::eOverlayState VideoOverlay::sState[] = {ovutils::OV_CLOSED};
 bool VideoOverlay::sIsModeOn[] = {false};
+ovutils::eDest VideoOverlay::sDest[] = {ovutils::OV_INVALID};
 
 //Cache stats, figure out the state, config overlay
 bool VideoOverlay::prepare(hwc_context_t *ctx, hwc_display_contents_1_t *list,
@@ -45,9 +45,9 @@
     }
 
     //index guaranteed to be not -1 at this point
-    hwc_layer_1_t *yuvLayer = &list->hwLayers[yuvIndex];
+    hwc_layer_1_t *layer = &list->hwLayers[yuvIndex];
 
-    private_handle_t *hnd = (private_handle_t *)yuvLayer->handle;
+    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"
@@ -61,64 +61,35 @@
             return false;
         }
     }
-    chooseState(ctx, dpy, yuvLayer);
-    if(configure(ctx, dpy, yuvLayer)) {
-        markFlags(yuvLayer);
+    if(configure(ctx, dpy, layer)) {
+        markFlags(layer);
         sIsModeOn[dpy] = true;
     }
 
     return sIsModeOn[dpy];
 }
 
-void VideoOverlay::chooseState(hwc_context_t *ctx, int dpy,
-        hwc_layer_1_t *yuvLayer) {
-    ALOGD_IF(VIDEO_DEBUG, "%s: old state = %s", __FUNCTION__,
-            ovutils::getStateString(sState[dpy]));
-
-    private_handle_t *hnd = NULL;
-    if(yuvLayer) {
-        hnd = (private_handle_t *)yuvLayer->handle;
-    }
-    ovutils::eOverlayState newState = ovutils::OV_CLOSED;
-    switch(dpy) {
-        case HWC_DISPLAY_PRIMARY:
-            if(ctx->listStats[dpy].yuvCount == 1) {
-                newState = ovutils::OV_2D_VIDEO_ON_PANEL;
-                if(isSkipLayer(yuvLayer) && !isSecureBuffer(hnd)) {
-                    newState = ovutils::OV_CLOSED;
-                }
-            }
-            break;
-        case HWC_DISPLAY_EXTERNAL:
-            newState = ctx->mOverlay[HWC_DISPLAY_EXTERNAL]->getState(); //If we are here, external is active
-            if(ctx->listStats[dpy].yuvCount == 1) {
-                if(!isSkipLayer(yuvLayer) || isSecureBuffer(hnd)) {
-                    newState = ovutils::OV_UI_VIDEO_TV;
-                }
-            }
-            break;
-        default:
-            break;
-    }
-
-    sState[dpy] = newState;
-    ALOGD_IF(VIDEO_DEBUG, "%s: new chosen state = %s", __FUNCTION__,
-            ovutils::getStateString(sState[dpy]));
-}
-
-void VideoOverlay::markFlags(hwc_layer_1_t *yuvLayer) {
-    if(yuvLayer) {
-        yuvLayer->compositionType = HWC_OVERLAY;
-        yuvLayer->hints |= HWC_HINT_CLEAR_FB;
+void VideoOverlay::markFlags(hwc_layer_1_t *layer) {
+    if(layer) {
+        layer->compositionType = HWC_OVERLAY;
+        layer->hints |= HWC_HINT_CLEAR_FB;
     }
 }
 
-/* Helpers */
-bool configPrimVid(hwc_context_t *ctx, hwc_layer_1_t *layer) {
-    overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_PRIMARY]);
+bool VideoOverlay::configure(hwc_context_t *ctx, int dpy,
+        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, hnd->format, hnd->size);
 
+    //Request a VG pipe
+    ovutils::eDest dest = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, dpy);
+    if(dest == ovutils::OV_INVALID) { //None available
+        return false;
+    }
+
+    sDest[dpy] = dest;
+
     ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
     if (isSecureBuffer(hnd)) {
         ovutils::setMdpFlags(mdpFlags,
@@ -131,19 +102,23 @@
     }
 
     ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
-    if (ctx->listStats[HWC_DISPLAY_PRIMARY].numAppLayers == 1) {
+    if (ctx->listStats[dpy].numAppLayers == 1) {
         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,
-            ovutils::ZORDER_0,
+            zorder,
             isFgFlag,
             ovutils::ROT_FLAG_DISABLED);
-    ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
-    ov.setSource(pargs, ovutils::OV_PIPE0);
 
-    int transform = layer->transform & FINAL_TRANSFORM_MASK;
+    ov.setSource(parg, dest);
+
+    int transform = layer->transform;
     ovutils::eTransform orient =
             static_cast<ovutils::eTransform>(transform);
 
@@ -152,8 +127,8 @@
 
     //Calculate the rect for primary based on whether the supplied position
     //is within or outside bounds.
-    const int fbWidth = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
-    const int fbHeight = ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
+    const int fbWidth = ctx->dpyAttr[dpy].xres;
+    const int fbHeight = ctx->dpyAttr[dpy].yres;
 
     if( displayFrame.left < 0 ||
             displayFrame.top < 0 ||
@@ -168,127 +143,24 @@
             sourceCrop.right - sourceCrop.left,
             sourceCrop.bottom - sourceCrop.top);
     //Only for Primary
-    ov.setCrop(dcrop, ovutils::OV_PIPE0);
+    ov.setCrop(dcrop, dest);
 
-    ov.setTransform(orient, ovutils::OV_PIPE0);
+    ov.setTransform(orient, dest);
 
     // position x,y,w,h
     ovutils::Dim dpos(displayFrame.left,
             displayFrame.top,
             displayFrame.right - displayFrame.left,
             displayFrame.bottom - displayFrame.top);
-    ov.setPosition(dpos, ovutils::OV_PIPE0);
+    ov.setPosition(dpos, dest);
 
-    if (!ov.commit(ovutils::OV_PIPE0)) {
+    if (!ov.commit(dest)) {
         ALOGE("%s: commit fails", __FUNCTION__);
         return false;
     }
     return true;
 }
 
-bool configExtVid(hwc_context_t *ctx, hwc_layer_1_t *layer) {
-    overlay::Overlay& ov = *(ctx->mOverlay[HWC_DISPLAY_EXTERNAL]);
-    private_handle_t *hnd = (private_handle_t *)layer->handle;
-    ovutils::Whf info(hnd->width, hnd->height, hnd->format, hnd->size);
-
-    ovutils::eMdpFlags mdpFlags = ovutils::OV_MDP_FLAGS_NONE;
-    if (isSecureBuffer(hnd)) {
-        ovutils::setMdpFlags(mdpFlags,
-                ovutils::OV_MDP_SECURE_OVERLAY_SESSION);
-    }
-
-    if(layer->blending == HWC_BLENDING_PREMULT) {
-        ovutils::setMdpFlags(mdpFlags,
-                ovutils::OV_MDP_BLEND_FG_PREMULT);
-    }
-
-    ovutils::eIsFg isFgFlag = ovutils::IS_FG_OFF;
-    if (ctx->listStats[HWC_DISPLAY_EXTERNAL].numAppLayers == 1) {
-        isFgFlag = ovutils::IS_FG_SET;
-    }
-
-    ovutils::PipeArgs parg(mdpFlags,
-            info,
-            ovutils::ZORDER_1,
-            isFgFlag,
-            ovutils::ROT_FLAG_DISABLED);
-    ovutils::PipeArgs pargs[ovutils::MAX_PIPES] = { parg, parg, parg };
-    ov.setSource(pargs, ovutils::OV_PIPE1);
-
-    int transform = layer->transform;
-    ovutils::eTransform orient =
-            static_cast<ovutils::eTransform>(transform);
-
-    hwc_rect_t sourceCrop = layer->sourceCrop;
-    hwc_rect_t displayFrame = layer->displayFrame;
-
-    //Calculate the rect for primary based on whether the supplied position
-    //is within or outside bounds.
-    const int fbWidth = ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].xres;
-    const int fbHeight = ctx->dpyAttr[HWC_DISPLAY_EXTERNAL].yres;
-
-    if( displayFrame.left < 0 ||
-            displayFrame.top < 0 ||
-            displayFrame.right > fbWidth ||
-            displayFrame.bottom > fbHeight) {
-        calculate_crop_rects(sourceCrop, displayFrame, fbWidth, fbHeight,
-                transform);
-    }
-
-    // x,y,w,h
-    ovutils::Dim dcrop(sourceCrop.left, sourceCrop.top,
-            sourceCrop.right - sourceCrop.left,
-            sourceCrop.bottom - sourceCrop.top);
-    //Only for External
-    ov.setCrop(dcrop, ovutils::OV_PIPE1);
-
-    ov.setTransform(orient, ovutils::OV_PIPE1);
-
-    ovutils::Dim dpos(displayFrame.left,
-            displayFrame.top,
-            (displayFrame.right - displayFrame.left),
-            (displayFrame.bottom - displayFrame.top));
-
-    //Only for External
-    ov.setPosition(dpos, ovutils::OV_PIPE1);
-
-    if (!ov.commit(ovutils::OV_PIPE1)) {
-        ALOGE("%s: commit fails", __FUNCTION__);
-        return false;
-    }
-    return true;
-}
-
-bool VideoOverlay::configure(hwc_context_t *ctx, int dpy,
-        hwc_layer_1_t *yuvLayer) {
-    bool ret = true;
-    overlay::Overlay& ov = *(ctx->mOverlay[dpy]);
-    switch(dpy) {
-        case HWC_DISPLAY_PRIMARY:
-            // Set overlay state
-            ov.setState(sState[dpy]);
-            switch(sState[dpy]) {
-                case ovutils::OV_2D_VIDEO_ON_PANEL:
-                    ret &= configPrimVid(ctx, yuvLayer);
-                    break;
-                default:
-                    return false;
-            }
-            break;
-        case HWC_DISPLAY_EXTERNAL:
-            ov.setState(sState[dpy]);
-            switch(sState[dpy]) {
-                case ovutils::OV_UI_VIDEO_TV:
-                    ret = configExtVid(ctx, yuvLayer);
-                    break;
-                default:
-                    return false;
-            }
-            break;
-    }
-    return ret;
-}
-
 bool VideoOverlay::draw(hwc_context_t *ctx, hwc_display_contents_1_t *list,
         int dpy)
 {
@@ -305,39 +177,14 @@
             list->hwLayers[yuvIndex].handle;
 
     bool ret = true;
-    overlay::Overlay& ov = *(ctx->mOverlay[dpy]);
-    ovutils::eOverlayState state = ov.getState();
+    overlay::Overlay& ov = *(ctx->mOverlay);
 
-    switch(dpy) {
-        case HWC_DISPLAY_PRIMARY:
-            switch (state) {
-                case ovutils::OV_2D_VIDEO_ON_PANEL:
-                    // Play primary
-                    if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE0)) {
-                        ALOGE("%s: queueBuffer failed for primary", __FUNCTION__);
-                        ret = false;
-                    }
-                    break;
-                default:
-                    ret = false;
-                    break;
-            }
-            break;
-        case HWC_DISPLAY_EXTERNAL:
-            switch(state) {
-                case ovutils::OV_UI_VIDEO_TV:
-                    // Play external
-                    if (!ov.queueBuffer(hnd->fd, hnd->offset, ovutils::OV_PIPE1)) {
-                        ALOGE("%s: queueBuffer failed for external", __FUNCTION__);
-                        ret = false;
-                    }
-                    break;
-                default:
-                    ret = false;
-                    break;
-            }
-            break;
+    if (!ov.queueBuffer(hnd->fd, hnd->offset,
+                sDest[dpy])) {
+        ALOGE("%s: queueBuffer failed for dpy=%d", __FUNCTION__, dpy);
+        ret = false;
     }
+
     return ret;
 }
 
diff --git a/libhwcomposer/hwc_video.h b/libhwcomposer/hwc_video.h
index dbfc236..09b24cc 100644
--- a/libhwcomposer/hwc_video.h
+++ b/libhwcomposer/hwc_video.h
@@ -16,12 +16,16 @@
  */
 #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 qhwc {
+namespace ovutils = overlay::utils;
+
 //Feature for using overlay to display videos.
 class VideoOverlay {
 public:
@@ -34,24 +38,21 @@
     //resets values
     static void reset();
 private:
-    //Choose an appropriate overlay state based on conditions
-    static void chooseState(hwc_context_t *ctx, int dpy,
-        hwc_layer_1_t *yuvLayer);
     //Configures overlay for video prim and ext
     static bool configure(hwc_context_t *ctx, int dpy,
             hwc_layer_1_t *yuvlayer);
+
     //Marks layer flags if this feature is used
     static void markFlags(hwc_layer_1_t *yuvLayer);
-    //The chosen overlay state.
-    static ovutils::eOverlayState sState[HWC_NUM_DISPLAY_TYPES];
     //Flags if this feature is on.
     static bool sIsModeOn[HWC_NUM_DISPLAY_TYPES];
+    static ovutils::eDest sDest[HWC_NUM_DISPLAY_TYPES];
 };
 
 inline void VideoOverlay::reset() {
     for(uint32_t i = 0; i < HWC_NUM_DISPLAY_TYPES; i++) {
         sIsModeOn[i] = false;
-        sState[i] = ovutils::OV_CLOSED;
+        sDest[i] = ovutils::OV_INVALID;
     }
 }
 }; //namespace qhwc