Merge "overlay: Remove defines of log2f"
diff --git a/libhwcomposer/hwc_ad.cpp b/libhwcomposer/hwc_ad.cpp
index be3793a..fdf6e67 100644
--- a/libhwcomposer/hwc_ad.cpp
+++ b/libhwcomposer/hwc_ad.cpp
@@ -182,8 +182,12 @@
         return false;
     }
 
-    ovutils::eDest dest = ctx->mOverlay->nextPipe(ovutils::OV_MDP_PIPE_VG,
-            overlay::Overlay::DPY_WRITEBACK, Overlay::MIXER_DEFAULT);
+    Overlay::PipeSpecs pipeSpecs;
+    pipeSpecs.formatClass = Overlay::FORMAT_YUV;
+    pipeSpecs.dpy = overlay::Overlay::DPY_WRITEBACK;
+    pipeSpecs.fb = false;
+
+    ovutils::eDest dest = ctx->mOverlay->getPipe(pipeSpecs);
     if(dest == OV_INVALID) {
         ALOGE("%s failed: No VG pipe available", __func__);
         mDoable = false;
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index d69d68e..74e6da4 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -139,14 +139,14 @@
                 ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
                     mTileEnabled));
 
-        //Request a pipe
-        ovutils::eMdpPipeType type = ovutils::OV_MDP_PIPE_ANY;
-        if((qdutils::MDPVersion::getInstance().is8x26() ||
-                   qdutils::MDPVersion::getInstance().is8x16()) && mDpy) {
-            //For 8x26 external always use DMA pipe
-            type = ovutils::OV_MDP_PIPE_DMA;
-        }
-        ovutils::eDest dest = ov.nextPipe(type, mDpy, Overlay::MIXER_DEFAULT);
+        Overlay::PipeSpecs pipeSpecs;
+        pipeSpecs.formatClass = Overlay::FORMAT_RGB;
+        pipeSpecs.needsScaling = qhwc::needsScaling(layer);
+        pipeSpecs.dpy = mDpy;
+        pipeSpecs.mixer = Overlay::MIXER_DEFAULT;
+        pipeSpecs.fb = true;
+
+        ovutils::eDest dest = ov.getPipe(pipeSpecs);
         if(dest == ovutils::OV_INVALID) { //None available
             ALOGE("%s: No pipes available to configure fb for dpy %d",
                 __FUNCTION__, mDpy);
@@ -308,10 +308,16 @@
         hwc_rect_t displayFrame = fbUpdatingRect;
 
         ret = true;
+        Overlay::PipeSpecs pipeSpecs;
+        pipeSpecs.formatClass = Overlay::FORMAT_RGB;
+        pipeSpecs.needsScaling = qhwc::needsScaling(layer);
+        pipeSpecs.dpy = mDpy;
+        pipeSpecs.fb = true;
+
         /* Configure left pipe */
         if(displayFrame.left < lSplit) {
-            ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
-                                               Overlay::MIXER_LEFT);
+            pipeSpecs.mixer = Overlay::MIXER_LEFT;
+            ovutils::eDest destL = ov.getPipe(pipeSpecs);
             if(destL == ovutils::OV_INVALID) { //None available
                 ALOGE("%s: No pipes available to configure fb for dpy %d's left"
                       " mixer", __FUNCTION__, mDpy);
@@ -344,8 +350,8 @@
 
         /* Configure right pipe */
         if(displayFrame.right > lSplit) {
-            ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
-                                               Overlay::MIXER_RIGHT);
+            pipeSpecs.mixer = Overlay::MIXER_RIGHT;
+            ovutils::eDest destR = ov.getPipe(pipeSpecs);
             if(destR == ovutils::OV_INVALID) { //None available
                 ALOGE("%s: No pipes available to configure fb for dpy %d's"
                       " right mixer", __FUNCTION__, mDpy);
@@ -455,8 +461,13 @@
     hwc_rect_t cropR = fbUpdatingRect;
 
     //Request left pipe (or 1 by default)
-    ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
-            Overlay::MIXER_DEFAULT);
+    Overlay::PipeSpecs pipeSpecs;
+    pipeSpecs.formatClass = Overlay::FORMAT_RGB;
+    pipeSpecs.needsScaling = qhwc::needsScaling(layer);
+    pipeSpecs.dpy = mDpy;
+    pipeSpecs.mixer = Overlay::MIXER_DEFAULT;
+    pipeSpecs.fb = true;
+    ovutils::eDest destL = ov.getPipe(pipeSpecs);
     if(destL == ovutils::OV_INVALID) {
         ALOGE("%s: No pipes available to configure fb for dpy %d's left"
                 " mixer", __FUNCTION__, mDpy);
@@ -468,8 +479,7 @@
     //Request right pipe (2 pipes needed only if dim > 2048)
     if((fbUpdatingRect.right - fbUpdatingRect.left) >
             qdutils::MAX_DISPLAY_DIM) {
-        destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
-                Overlay::MIXER_DEFAULT);
+        destR = ov.getPipe(pipeSpecs);
         if(destR == ovutils::OV_INVALID) {
             ALOGE("%s: No pipes available to configure fb for dpy %d's right"
                     " mixer", __FUNCTION__, mDpy);
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 1222dcf..992c043 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -393,37 +393,6 @@
     return true;
 }
 
-ovutils::eDest MDPComp::getMdpPipe(hwc_context_t *ctx, ePipeType type,
-        int mixer) {
-    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, mDpy, mixer);
-        if(mdp_pipe != ovutils::OV_INVALID) {
-            return mdp_pipe;
-        }
-    case MDPCOMP_OV_ANY:
-    case MDPCOMP_OV_RGB:
-        mdp_pipe = ov.nextPipe(ovutils::OV_MDP_PIPE_RGB, mDpy, mixer);
-        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, mDpy, mixer);
-    default:
-        ALOGE("%s: Invalid pipe type",__FUNCTION__);
-        return ovutils::OV_INVALID;
-    };
-    return ovutils::OV_INVALID;
-}
-
 bool MDPComp::isFrameDoable(hwc_context_t *ctx) {
     bool ret = true;
 
@@ -1342,18 +1311,23 @@
     info.pipeInfo = new MdpYUVPipeInfo;
     info.rot = NULL;
     MdpYUVPipeInfo& pipe_info = *(MdpYUVPipeInfo*)info.pipeInfo;
-    ePipeType type =  MDPCOMP_OV_VG;
 
     pipe_info.lIndex = ovutils::OV_INVALID;
     pipe_info.rIndex = ovutils::OV_INVALID;
 
-    pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
+    Overlay::PipeSpecs pipeSpecs;
+    pipeSpecs.formatClass = Overlay::FORMAT_YUV;
+    pipeSpecs.needsScaling = true;
+    pipeSpecs.dpy = mDpy;
+    pipeSpecs.fb = false;
+
+    pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
     if(pipe_info.lIndex == ovutils::OV_INVALID){
         bRet = false;
         ALOGD_IF(isDebug(),"%s: allocating first VG pipe failed",
                 __FUNCTION__);
     }
-    pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
+    pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
     if(pipe_info.rIndex == ovutils::OV_INVALID){
         bRet = false;
         ALOGD_IF(isDebug(),"%s: allocating second VG pipe failed",
@@ -1423,28 +1397,20 @@
         info.pipeInfo = new MdpPipeInfoNonSplit;
         info.rot = NULL;
         MdpPipeInfoNonSplit& pipe_info = *(MdpPipeInfoNonSplit*)info.pipeInfo;
-        ePipeType type = MDPCOMP_OV_ANY;
 
-        if(isYuvBuffer(hnd)) {
-            type = MDPCOMP_OV_VG;
-        } else if(qdutils::MDPVersion::getInstance().is8x26() &&
-                (ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024)) {
-            if(qhwc::needsScaling(layer))
-                type = MDPCOMP_OV_RGB;
-        } else if(!qhwc::needsScaling(layer)
-            && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
-            && ctx->mMDP.version >= qdutils::MDSS_V5) {
-            type = MDPCOMP_OV_DMA;
-        } else if(qhwc::needsScaling(layer) &&
-                !(ctx->listStats[mDpy].yuvCount) &&
-                ! qdutils::MDPVersion::getInstance().isRGBScalarSupported()){
-            type = MDPCOMP_OV_VG;
-        }
+        Overlay::PipeSpecs pipeSpecs;
+        pipeSpecs.formatClass = isYuvBuffer(hnd) ?
+                Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
+        pipeSpecs.needsScaling = qhwc::needsScaling(layer) or
+                (qdutils::MDPVersion::getInstance().is8x26() and
+                ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres > 1024);
+        pipeSpecs.dpy = mDpy;
+        pipeSpecs.fb = false;
 
-        pipe_info.index = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
+        pipe_info.index = ctx->mOverlay->getPipe(pipeSpecs);
+
         if(pipe_info.index == ovutils::OV_INVALID) {
-            ALOGD_IF(isDebug(), "%s: Unable to get pipe type = %d",
-                __FUNCTION__, (int) type);
+            ALOGD_IF(isDebug(), "%s: Unable to get pipe", __FUNCTION__);
             return false;
         }
     }
@@ -1607,22 +1573,31 @@
 }
 
 bool MDPCompSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
-        MdpPipeInfoSplit& pipe_info,
-        ePipeType type) {
-    const int lSplit = getLeftSplit(ctx, mDpy);
+        MdpPipeInfoSplit& pipe_info) {
 
+    const int lSplit = getLeftSplit(ctx, mDpy);
+    private_handle_t *hnd = (private_handle_t *)layer->handle;
     hwc_rect_t dst = layer->displayFrame;
     pipe_info.lIndex = ovutils::OV_INVALID;
     pipe_info.rIndex = ovutils::OV_INVALID;
 
+    Overlay::PipeSpecs pipeSpecs;
+    pipeSpecs.formatClass = isYuvBuffer(hnd) ?
+            Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
+    pipeSpecs.needsScaling = qhwc::needsScalingWithSplit(ctx, layer, mDpy);
+    pipeSpecs.dpy = mDpy;
+    pipeSpecs.mixer = Overlay::MIXER_LEFT;
+    pipeSpecs.fb = false;
+
     if (dst.left < lSplit) {
-        pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_LEFT);
+        pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
         if(pipe_info.lIndex == ovutils::OV_INVALID)
             return false;
     }
 
     if(dst.right > lSplit) {
-        pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_RIGHT);
+        pipeSpecs.mixer = Overlay::MIXER_RIGHT;
+        pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
         if(pipe_info.rIndex == ovutils::OV_INVALID)
             return false;
     }
@@ -1652,19 +1627,10 @@
         info.pipeInfo = new MdpPipeInfoSplit;
         info.rot = NULL;
         MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
-        ePipeType type = MDPCOMP_OV_ANY;
 
-        if(isYuvBuffer(hnd)) {
-            type = MDPCOMP_OV_VG;
-        } else if(!qhwc::needsScalingWithSplit(ctx, layer, mDpy)
-            && Overlay::getDMAMode() != Overlay::DMA_BLOCK_MODE
-            && ctx->mMDP.version >= qdutils::MDSS_V5) {
-            type = MDPCOMP_OV_DMA;
-        }
-
-        if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
-            ALOGD_IF(isDebug(), "%s: Unable to get pipe for type = %d",
-                    __FUNCTION__, (int) type);
+        if(!acquireMDPPipes(ctx, layer, pipe_info)) {
+            ALOGD_IF(isDebug(), "%s: Unable to get pipe for type",
+                    __FUNCTION__);
             return false;
         }
     }
@@ -1848,7 +1814,7 @@
 
 //================MDPCompSrcSplit==============================================
 bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
-        MdpPipeInfoSplit& pipe_info, ePipeType type) {
+        MdpPipeInfoSplit& pipe_info) {
     private_handle_t *hnd = (private_handle_t *)layer->handle;
     hwc_rect_t dst = layer->displayFrame;
     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
@@ -1859,32 +1825,25 @@
     //should have a higher priority than the right one. Pipe priorities are
     //starting with VG0, VG1 ... , RGB0 ..., DMA1
 
+    Overlay::PipeSpecs pipeSpecs;
+    pipeSpecs.formatClass = isYuvBuffer(hnd) ?
+            Overlay::FORMAT_YUV : Overlay::FORMAT_RGB;
+    pipeSpecs.needsScaling = qhwc::needsScaling(layer);
+    pipeSpecs.dpy = mDpy;
+    pipeSpecs.fb = false;
+
     //1 pipe by default for a layer
-    pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
+    pipe_info.lIndex = ctx->mOverlay->getPipe(pipeSpecs);
     if(pipe_info.lIndex == ovutils::OV_INVALID) {
-        if(isYuvBuffer(hnd)) {
-            return false;
-        }
-        pipe_info.lIndex = getMdpPipe(ctx, MDPCOMP_OV_ANY,
-                Overlay::MIXER_DEFAULT);
-        if(pipe_info.lIndex == ovutils::OV_INVALID) {
-            return false;
-        }
+        return false;
     }
 
     //If layer's crop width or dest width > 2048, use 2 pipes
     if((dst.right - dst.left) > qdutils::MAX_DISPLAY_DIM or
             (crop.right - crop.left) > qdutils::MAX_DISPLAY_DIM) {
-        pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
+        pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
         if(pipe_info.rIndex == ovutils::OV_INVALID) {
-            if(isYuvBuffer(hnd)) {
-                return false;
-            }
-            pipe_info.rIndex = getMdpPipe(ctx, MDPCOMP_OV_ANY,
-                    Overlay::MIXER_DEFAULT);
-            if(pipe_info.rIndex == ovutils::OV_INVALID) {
-                return false;
-            }
+            return false;
         }
 
         // Return values
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index 470ce12..beb858b 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -132,8 +132,6 @@
     /* allocates pipe from pipe book */
     virtual bool allocLayerPipes(hwc_context_t *ctx,
                                  hwc_display_contents_1_t* list) = 0;
-    /* allocate MDP pipes from overlay */
-    ovutils::eDest getMdpPipe(hwc_context_t *ctx, ePipeType type, int mixer);
     /* configures MPD pipes */
     virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
                           PipeLayerPair& pipeLayerPair) = 0;
@@ -279,7 +277,7 @@
     };
 
     virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
-                         MdpPipeInfoSplit& pipe_info, ePipeType type);
+                         MdpPipeInfoSplit& pipe_info);
 
     /* configure's overlay pipes for the frame */
     virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
@@ -306,7 +304,7 @@
     virtual ~MDPCompSrcSplit(){};
 private:
     virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
-            MdpPipeInfoSplit& pipe_info, ePipeType type);
+            MdpPipeInfoSplit& pipe_info);
 
     virtual int configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
             PipeLayerPair& pipeLayerPair);
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index 7e7f275..c1757ad 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -42,7 +42,7 @@
 
 namespace overlay {
 using namespace utils;
-
+using namespace qdutils;
 
 Overlay::Overlay() {
     int numPipes = qdutils::MDPVersion::getInstance().getTotalPipes();
@@ -158,6 +158,103 @@
     return dest;
 }
 
+utils::eDest Overlay::getPipe(const PipeSpecs& pipeSpecs) {
+    if(MDPVersion::getInstance().is8x26()) {
+        return getPipe_8x26(pipeSpecs);
+    } else if(MDPVersion::getInstance().is8x16()) {
+        return getPipe_8x16(pipeSpecs);
+    }
+
+    eDest dest = OV_INVALID;
+
+    //The default behavior is to assume RGB and VG pipes have scalars
+    if(pipeSpecs.formatClass == FORMAT_YUV) {
+        return nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+    } else if(pipeSpecs.fb == false) { //RGB App layers
+        if(not pipeSpecs.needsScaling) {
+            dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+        }
+        if(dest == OV_INVALID) {
+            dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+        }
+        if(dest == OV_INVALID) {
+            dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+        }
+    } else { //FB layer
+        dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+        if(dest == OV_INVALID) {
+            dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+        }
+        //Some features can cause FB to have scaling as well.
+        //If we ever come to this block with FB needing scaling,
+        //the screen will be black for a frame, since the FB won't get a pipe
+        //but atleast this will prevent a hang
+        if(dest == OV_INVALID and (not pipeSpecs.needsScaling)) {
+            dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+        }
+    }
+    return dest;
+}
+
+utils::eDest Overlay::getPipe_8x26(const PipeSpecs& pipeSpecs) {
+    //Use this to hide all the 8x26 requirements that cannot be humanly
+    //described in a generic way
+    eDest dest = OV_INVALID;
+    if(pipeSpecs.formatClass == FORMAT_YUV) { //video
+        return nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+    } else if(pipeSpecs.fb == false) { //RGB app layers
+        if(not pipeSpecs.needsScaling) {
+            dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+        }
+        if(dest == OV_INVALID) {
+            dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+        }
+        if(dest == OV_INVALID) {
+            dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+        }
+    } else { //FB layer
+        //For 8x26 Secondary we use DMA always for FB for inline rotation
+        if(pipeSpecs.dpy == DPY_PRIMARY) {
+            dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+            if(dest == OV_INVALID) {
+                dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+            }
+        }
+        if(dest == OV_INVALID and (not pipeSpecs.needsScaling)) {
+            dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+        }
+    }
+    return dest;
+}
+
+utils::eDest Overlay::getPipe_8x16(const PipeSpecs& pipeSpecs) {
+    //Having such functions help keeping the interface generic but code specific
+    //and rife with assumptions
+    eDest dest = OV_INVALID;
+    if(pipeSpecs.formatClass == FORMAT_YUV or pipeSpecs.needsScaling) {
+        return nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+    } else if(pipeSpecs.fb == false) { //RGB app layers
+        //Since this is a specific func, we can assume stuff like RGB pipe not
+        //having scalar blocks
+        dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+        if(dest == OV_INVALID) {
+            dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+        }
+    } else {
+        //For 8x16 Secondary we use DMA always for FB for inline rotation
+        if(pipeSpecs.dpy == DPY_PRIMARY) {
+            dest = nextPipe(OV_MDP_PIPE_RGB, pipeSpecs.dpy, pipeSpecs.mixer);
+            if(dest == OV_INVALID) {
+                dest = nextPipe(OV_MDP_PIPE_VG, pipeSpecs.dpy, pipeSpecs.mixer);
+            }
+        }
+        if(dest == OV_INVALID) {
+            dest = nextPipe(OV_MDP_PIPE_DMA, pipeSpecs.dpy, pipeSpecs.mixer);
+        }
+    }
+    return dest;
+}
+
 void Overlay::endAllSessions() {
     for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
         if(mPipeBook[i].valid() && mPipeBook[i].mSession==PipeBook::START)
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 44193be..fa19dc3 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -53,6 +53,17 @@
     enum { MIXER_LEFT, MIXER_RIGHT, MIXER_UNUSED };
     enum { MIXER_DEFAULT = MIXER_LEFT, MIXER_MAX = MIXER_UNUSED };
     enum { MAX_FB_DEVICES = DPY_MAX };
+    enum { FORMAT_YUV, FORMAT_RGB };
+
+    struct PipeSpecs {
+        PipeSpecs() : formatClass(FORMAT_RGB), needsScaling(false), fb(false),
+                dpy(DPY_PRIMARY), mixer(MIXER_DEFAULT) {}
+        int formatClass;
+        bool needsScaling;
+        bool fb;
+        int dpy;
+        int mixer;
+    };
 
     /* dtor close */
     ~Overlay();
@@ -69,14 +80,10 @@
      */
     void configDone();
 
-    /* Returns an available pipe based on the type of pipe requested. When ANY
-     * is requested, the first available VG or RGB is returned. If no pipe is
-     * available for the display "dpy" then INV is returned. Note: If a pipe is
-     * assigned to a certain display, then it cannot be assigned to another
-     * display without being garbage-collected once. To add if a pipe is
-     * asisgned to a mixer within a display it cannot be reused for another
-     * mixer without being UNSET once*/
-    utils::eDest nextPipe(utils::eMdpPipeType, int dpy, int mixer);
+    /* Get a pipe that supported the specified format class (yuv, rgb) and has
+     * scaling capabilities.
+     */
+    utils::eDest getPipe(const PipeSpecs& pipeSpecs);
     /* Returns the eDest corresponding to an already allocated pipeid.
      * Useful for the reservation case, when libvpu reserves the pipe at its
      * end, and expect the overlay to allocate a given pipe for a layer.
@@ -147,6 +154,18 @@
     void validate(int index);
     static void setDMAMultiplexingSupported();
     void dump() const;
+    /* Returns an available pipe based on the type of pipe requested. When ANY
+     * is requested, the first available VG or RGB is returned. If no pipe is
+     * available for the display "dpy" then INV is returned. Note: If a pipe is
+     * assigned to a certain display, then it cannot be assigned to another
+     * display without being garbage-collected once. To add if a pipe is
+     * asisgned to a mixer within a display it cannot be reused for another
+     * mixer without being UNSET once*/
+    utils::eDest nextPipe(utils::eMdpPipeType, int dpy, int mixer);
+    /* Helpers that enfore target specific policies while returning pipes */
+    utils::eDest getPipe_8x26(const PipeSpecs& pipeSpecs);
+    utils::eDest getPipe_8x16(const PipeSpecs& pipeSpecs);
+
     /* Returns the scalar object */
     static scale::Scale *getScalar();
     /* Creates a scalar object using libscale.so */
diff --git a/libvirtual/virtual.cpp b/libvirtual/virtual.cpp
index 5453e3a..bed5e4c 100644
--- a/libvirtual/virtual.cpp
+++ b/libvirtual/virtual.cpp
@@ -177,12 +177,12 @@
         uint32_t priW = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].xres;
         uint32_t priH = mHwcContext->dpyAttr[HWC_DISPLAY_PRIMARY].yres;
 
-        initResolution(extW, extH);
-
         // Dynamic Resolution Change depends on MDP downscaling.
         // MDP downscale property will be ignored to exercise DRC use case.
         // If DRC is in progress, ext WxH will have non-zero values.
-        bool isDRC = (extW > 0) && (extH > 0);
+        bool isDRC = (extW > mVInfo.xres) && (extH > mVInfo.yres);
+
+        initResolution(extW, extH);
 
         if(!qdutils::MDPVersion::getInstance().is8x26()
                 && (mHwcContext->mMDPDownscaleEnabled || isDRC)) {