Merge "gralloc: Perform func to return stride and height"
diff --git a/libgralloc/Android.mk b/libgralloc/Android.mk
index ef10f54..18beaf2 100644
--- a/libgralloc/Android.mk
+++ b/libgralloc/Android.mk
@@ -21,7 +21,7 @@
 LOCAL_MODULE_PATH             := $(TARGET_OUT_SHARED_LIBRARIES)/hw
 LOCAL_MODULE_TAGS             := optional
 LOCAL_C_INCLUDES              := $(common_includes) $(kernel_includes)
-LOCAL_SHARED_LIBRARIES        := $(common_libs) libmemalloc
+LOCAL_SHARED_LIBRARIES        := $(common_libs) libmemalloc libqdMetaData
 LOCAL_SHARED_LIBRARIES        += libqdutils libGLESv1_CM
 LOCAL_CFLAGS                  := $(common_flags) -DLOG_TAG=\"qdgralloc\"
 LOCAL_ADDITIONAL_DEPENDENCIES := $(common_deps) $(kernel_deps)
diff --git a/libgralloc/gpu.cpp b/libgralloc/gpu.cpp
index a256db8..19e948a 100644
--- a/libgralloc/gpu.cpp
+++ b/libgralloc/gpu.cpp
@@ -97,9 +97,12 @@
             flags |= private_handle_t::PRIV_FLAGS_EXTERNAL_ONLY;
         }
 
+        ColorSpace_t colorSpace = ITU_R_601;
+        flags |= private_handle_t::PRIV_FLAGS_ITU_R_601;
         if (bufferType == BUFFER_TYPE_VIDEO) {
             if (usage & GRALLOC_USAGE_HW_CAMERA_WRITE) {
 #ifndef MDSS_TARGET
+                colorSpace = ITU_R_601_FR;
                 flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
 #else
                 // Per the camera spec ITU 709 format should be set only for
@@ -108,14 +111,15 @@
                 // camera buffer
                 //
                 if (usage & GRALLOC_USAGE_HW_CAMERA_MASK) {
-                    if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
+                    if (usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) {
                         flags |= private_handle_t::PRIV_FLAGS_ITU_R_709;
-                    else
+                        colorSpace = ITU_R_709;
+                    } else {
                         flags |= private_handle_t::PRIV_FLAGS_ITU_R_601_FR;
+                        colorSpace = ITU_R_601_FR;
+                    }
                 }
 #endif
-            } else {
-                flags |= private_handle_t::PRIV_FLAGS_ITU_R_601;
             }
         }
 
@@ -156,6 +160,7 @@
         hnd->offset = data.offset;
         hnd->base = (uintptr_t)(data.base) + data.offset;
         hnd->gpuaddr = 0;
+        setMetaData(hnd, UPDATE_COLOR_SPACE, (void*) &colorSpace);
 
         *pHandle = hnd;
     }
@@ -265,7 +270,8 @@
 
     //If input format is HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED then based on
     //the usage bits, gralloc assigns a format.
-    if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+    if(format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED ||
+       format == HAL_PIXEL_FORMAT_YCbCr_420_888) {
         if(usage & GRALLOC_USAGE_HW_VIDEO_ENCODER)
             grallocFormat = HAL_PIXEL_FORMAT_NV12_ENCODEABLE; //NV12
         else if((usage & GRALLOC_USAGE_HW_CAMERA_MASK)
diff --git a/libgralloc/gralloc.cpp b/libgralloc/gralloc.cpp
index 2567300..fd4d208 100644
--- a/libgralloc/gralloc.cpp
+++ b/libgralloc/gralloc.cpp
@@ -44,6 +44,11 @@
                         int l, int t, int w, int h,
                         void** vaddr);
 
+extern int gralloc_lock_ycbcr(gralloc_module_t const* module,
+                        buffer_handle_t handle, int usage,
+                        int l, int t, int w, int h,
+                        struct android_ycbcr *ycbcr);
+
 extern int gralloc_unlock(gralloc_module_t const* module,
                           buffer_handle_t handle);
 
@@ -58,36 +63,37 @@
 
 // HAL module methods
 static struct hw_module_methods_t gralloc_module_methods = {
-open: gralloc_device_open
+    open: gralloc_device_open
 };
 
 // HAL module initialize
 struct private_module_t HAL_MODULE_INFO_SYM = {
-base: {
-    common: {
-        tag: HARDWARE_MODULE_TAG,
-             version_major: 1,
-             version_minor: 0,
-             id: GRALLOC_HARDWARE_MODULE_ID,
-             name: "Graphics Memory Allocator Module",
-             author: "The Android Open Source Project",
-             methods: &gralloc_module_methods,
-             dso: 0,
-             reserved: {0},
-            },
-    registerBuffer: gralloc_register_buffer,
-    unregisterBuffer: gralloc_unregister_buffer,
-    lock: gralloc_lock,
-    unlock: gralloc_unlock,
-    perform: gralloc_perform,
-      },
-framebuffer: 0,
-fbFormat: 0,
-flags: 0,
-numBuffers: 0,
-bufferMask: 0,
-lock: PTHREAD_MUTEX_INITIALIZER,
-currentBuffer: 0,
+    base: {
+        common: {
+            tag: HARDWARE_MODULE_TAG,
+            version_major: 1,
+            version_minor: 0,
+            id: GRALLOC_HARDWARE_MODULE_ID,
+            name: "Graphics Memory Allocator Module",
+            author: "The Android Open Source Project",
+            methods: &gralloc_module_methods,
+            dso: 0,
+            reserved: {0},
+        },
+        registerBuffer: gralloc_register_buffer,
+        unregisterBuffer: gralloc_unregister_buffer,
+        lock: gralloc_lock,
+        unlock: gralloc_unlock,
+        perform: gralloc_perform,
+        lock_ycbcr: gralloc_lock_ycbcr,
+    },
+    framebuffer: 0,
+    fbFormat: 0,
+    flags: 0,
+    numBuffers: 0,
+    bufferMask: 0,
+    lock: PTHREAD_MUTEX_INITIALIZER,
+    currentBuffer: 0,
 };
 
 // Open Gralloc device
diff --git a/libgralloc/mapper.cpp b/libgralloc/mapper.cpp
index 62a6ee5..e415b3c 100644
--- a/libgralloc/mapper.cpp
+++ b/libgralloc/mapper.cpp
@@ -56,8 +56,7 @@
 }
 
 static int gralloc_map(gralloc_module_t const* module,
-                       buffer_handle_t handle,
-                       void** vaddr)
+                       buffer_handle_t handle)
 {
     if(!module)
         return -EINVAL;
@@ -78,8 +77,6 @@
         }
 
         hnd->base = intptr_t(mappedAddress) + hnd->offset;
-        //LOGD("gralloc_map() succeeded fd=%d, off=%d, size=%d, vaddr=%p",
-        //        hnd->fd, hnd->offset, hnd->size, mappedAddress);
         mappedAddress = MAP_FAILED;
         size = ROUND_UP_PAGESIZE(sizeof(MetaData_t));
         err = memalloc->map_buffer(&mappedAddress, size,
@@ -92,7 +89,6 @@
         }
         hnd->base_metadata = intptr_t(mappedAddress) + hnd->offset_metadata;
     }
-    *vaddr = (void*)hnd->base;
     return 0;
 }
 
@@ -152,8 +148,7 @@
     private_handle_t* hnd = (private_handle_t*)handle;
     hnd->base = 0;
     hnd->base_metadata = 0;
-    void *vaddr;
-    int err = gralloc_map(module, handle, &vaddr);
+    int err = gralloc_map(module, handle);
     if (err) {
         ALOGE("%s: gralloc_map failed", __FUNCTION__);
         return err;
@@ -212,10 +207,8 @@
     return 0;
 }
 
-int gralloc_lock(gralloc_module_t const* module,
-                 buffer_handle_t handle, int usage,
-                 int /*l*/, int /*t*/, int /*w*/, int /*h*/,
-                 void** vaddr)
+static int gralloc_map_and_invalidate (gralloc_module_t const* module,
+                                       buffer_handle_t handle, int usage)
 {
     if (!module || private_handle_t::validate(handle) < 0)
         return -EINVAL;
@@ -227,10 +220,9 @@
             // we need to map for real
             pthread_mutex_t* const lock = &sMapLock;
             pthread_mutex_lock(lock);
-            err = gralloc_map(module, handle, vaddr);
+            err = gralloc_map(module, handle);
             pthread_mutex_unlock(lock);
         }
-        *vaddr = (void*)hnd->base;
         if (hnd->flags & private_handle_t::PRIV_FLAGS_USES_ION) {
             //Invalidate if reading in software. No need to do this for the
             //metadata buffer as it is only read/written in software.
@@ -249,6 +241,50 @@
     return err;
 }
 
+int gralloc_lock(gralloc_module_t const* module,
+                 buffer_handle_t handle, int usage,
+                 int /*l*/, int /*t*/, int /*w*/, int /*h*/,
+                 void** vaddr)
+{
+    private_handle_t* hnd = (private_handle_t*)handle;
+    int err = gralloc_map_and_invalidate(module, handle, usage);
+    if(!err)
+        *vaddr = (void*)hnd->base;
+    return err;
+}
+
+int gralloc_lock_ycbcr(gralloc_module_t const* module,
+                 buffer_handle_t handle, int usage,
+                 int /*l*/, int /*t*/, int /*w*/, int /*h*/,
+                 struct android_ycbcr *ycbcr)
+{
+    private_handle_t* hnd = (private_handle_t*)handle;
+    int err = gralloc_map_and_invalidate(module, handle, usage);
+    size_t ystride, cstride;
+    if(!err) {
+        //hnd->format holds our implementation defined format
+        //HAL_PIXEL_FORMAT_YCrCb_420_SP is the only one set right now.
+        switch (hnd->format) {
+            case HAL_PIXEL_FORMAT_YCrCb_420_SP:
+                ystride = ALIGN(hnd->width, 16);
+                cstride = ALIGN(hnd->width, 16)/2;
+                ycbcr->y  = (void*)hnd->base;
+                ycbcr->cr = (void*)(hnd->base + ystride * hnd->height);
+                ycbcr->cb = (void*)(hnd->base + ystride * hnd->height + 1);
+                ycbcr->ystride = ystride;
+                ycbcr->cstride = cstride;
+                ycbcr->chroma_step = 2;
+                memset(ycbcr->reserved, 0, sizeof(ycbcr->reserved));
+                break;
+            default:
+                ALOGD("%s: Invalid format passed: 0x%x", __FUNCTION__,
+                      hnd->format);
+                err = -EINVAL;
+        }
+    }
+    return err;
+}
+
 int gralloc_unlock(gralloc_module_t const* module,
                    buffer_handle_t handle)
 {
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index b51b2ea..7042b3f 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -66,8 +66,9 @@
 bool IFBUpdate::prepareAndValidate(hwc_context_t *ctx,
             hwc_display_contents_1 *list, int fbZorder) {
     hwc_layer_1_t *layer = &list->hwLayers[list->numHwLayers - 1];
-    return prepare(ctx, list, layer->displayFrame, fbZorder) &&
+    mModeOn = prepare(ctx, list, layer->displayFrame, fbZorder) &&
             ctx->mOverlay->validateAndSet(mDpy, ctx->dpyAttr[mDpy].fd);
+    return mModeOn;
 }
 
 //================= Low res====================================
@@ -426,35 +427,13 @@
         layer = &list->hwLayers[extOnlyLayerIndex];
         layer->compositionType = HWC_OVERLAY;
     }
+
     overlay::Overlay& ov = *(ctx->mOverlay);
 
     ovutils::Whf info(mAlignedFBWidth,
             mAlignedFBHeight,
             ovutils::getMdpFormat(HAL_PIXEL_FORMAT_RGBA_8888,
                 mTileEnabled));
-    //Request left pipe, VG first owing to higher prio
-    ovutils::eDest destL = ov.nextPipe(ovutils::OV_MDP_PIPE_VG, mDpy,
-            Overlay::MIXER_DEFAULT);
-    if(destL == ovutils::OV_INVALID) {
-        destL = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
-            Overlay::MIXER_DEFAULT);
-        if(destL == ovutils::OV_INVALID) {
-            ALOGE("%s: No pipes available to configure fb for dpy %d's left"
-                    " mixer", __FUNCTION__, mDpy);
-            return false;
-        }
-    }
-    //Request right pipe
-    ovutils::eDest destR = ov.nextPipe(ovutils::OV_MDP_PIPE_ANY, mDpy,
-            Overlay::MIXER_DEFAULT);
-    if(destR == ovutils::OV_INVALID) {
-        ALOGE("%s: No pipes available to configure fb for dpy %d's right"
-                " mixer", __FUNCTION__, mDpy);
-        return false;
-    }
-
-    mDestLeft = destL;
-    mDestRight = destR;
 
     ovutils::eMdpFlags mdpFlags = OV_MDP_BLEND_FG_PREMULT;
     ovutils::eZorder zOrder = static_cast<ovutils::eZorder>(fbZorder);
@@ -467,46 +446,68 @@
             ovutils::DEFAULT_PLANE_ALPHA,
             (ovutils::eBlending)
             getBlending(layer->blending));
-    ov.setSource(parg, destL);
-    ov.setSource(parg, destR);
-
-    //Crop and Position are same for FB
-    ovutils::Dim cropPosL(
-            fbUpdatingRect.left,
-            fbUpdatingRect.top,
-            (fbUpdatingRect.right - fbUpdatingRect.left) / 2,
-            fbUpdatingRect.bottom - fbUpdatingRect.top);
-
-    ovutils::Dim cropPosR(
-            cropPosL.x + cropPosL.w,
-            cropPosL.y,
-            cropPosL.w,
-            cropPosL.h);
-
-    ov.setCrop(cropPosL, destL);
-    ov.setCrop(cropPosR, destR);
-    ov.setPosition(cropPosL, destL);
-    ov.setPosition(cropPosR, destR);
 
     int transform = layer->transform;
     ovutils::eTransform orient =
             static_cast<ovutils::eTransform>(transform);
-    ov.setTransform(orient, destL);
-    ov.setTransform(orient, destR);
 
-    ret = true;
-    if (!ov.commit(destL)) {
-        ALOGE("%s: commit fails for left", __FUNCTION__);
-        ret = false;
+    hwc_rect_t cropL = fbUpdatingRect;
+    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);
+    if(destL == ovutils::OV_INVALID) {
+        ALOGE("%s: No pipes available to configure fb for dpy %d's left"
+                " mixer", __FUNCTION__, mDpy);
+        return false;
     }
-    if (!ov.commit(destR)) {
-        ALOGE("%s: commit fails for right", __FUNCTION__);
-        ret = false;
+
+    ovutils::eDest destR = ovutils::OV_INVALID;
+
+    //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);
+        if(destR == ovutils::OV_INVALID) {
+            ALOGE("%s: No pipes available to configure fb for dpy %d's right"
+                    " mixer", __FUNCTION__, mDpy);
+            return false;
+        }
+
+        if(ctx->mOverlay->comparePipePriority(destL, destR) == -1) {
+            qhwc::swap(destL, destR);
+        }
+
+        //Split crop equally when using 2 pipes
+        cropL.right = (fbUpdatingRect.right + fbUpdatingRect.left) / 2;
+        cropR.left = cropL.right;
     }
-    if(ret == false) {
-        ctx->mLayerRotMap[mDpy]->clear();
+
+    mDestLeft = destL;
+    mDestRight = destR;
+
+    if(destL != OV_INVALID) {
+        if(configMdp(ctx->mOverlay, parg, orient,
+                    cropL, cropL, NULL /*metadata*/, destL) < 0) {
+            ALOGE("%s: commit failed for left mixer config", __FUNCTION__);
+            ctx->mLayerRotMap[mDpy]->clear();
+            return false;
+        }
     }
-    return ret;
+
+    //configure right pipe
+    if(destR != OV_INVALID) {
+        if(configMdp(ctx->mOverlay, parg, orient,
+                    cropR, cropR, NULL /*metadata*/, destR) < 0) {
+            ALOGE("%s: commit failed for right mixer config", __FUNCTION__);
+            ctx->mLayerRotMap[mDpy]->clear();
+            return false;
+        }
+    }
+
+    return true;
 }
 
 //---------------------------------------------------------------------
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index ab175cb..54530e2 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -1848,7 +1848,7 @@
 
 //================MDPCompSrcSplit==============================================
 bool MDPCompSrcSplit::acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
-        MdpPipeInfoSplit& pipe_info, ePipeType /*type*/) {
+        MdpPipeInfoSplit& pipe_info, ePipeType type) {
     private_handle_t *hnd = (private_handle_t *)layer->handle;
     hwc_rect_t dst = layer->displayFrame;
     hwc_rect_t crop = integerizeSourceCrop(layer->sourceCropf);
@@ -1858,13 +1858,9 @@
     //If 2 pipes are staged on a single stage of a mixer, then the left pipe
     //should have a higher priority than the right one. Pipe priorities are
     //starting with VG0, VG1 ... , RGB0 ..., DMA1
-    //TODO Currently we acquire VG pipes for left side and RGB/DMA for right to
-    //make sure pipe priorities are satisfied. A better way is to have priority
-    //as part of overlay object and acquire any 2 pipes. Assign the higher
-    //priority one to left side and lower to right side.
 
     //1 pipe by default for a layer
-    pipe_info.lIndex = getMdpPipe(ctx, MDPCOMP_OV_VG, Overlay::MIXER_DEFAULT);
+    pipe_info.lIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
     if(pipe_info.lIndex == ovutils::OV_INVALID) {
         if(isYuvBuffer(hnd)) {
             return false;
@@ -1879,38 +1875,31 @@
     //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) {
-        ePipeType rightType = isYuvBuffer(hnd) ?
-                MDPCOMP_OV_VG : MDPCOMP_OV_ANY;
-        pipe_info.rIndex = getMdpPipe(ctx, rightType, Overlay::MIXER_DEFAULT);
+        pipe_info.rIndex = getMdpPipe(ctx, type, Overlay::MIXER_DEFAULT);
         if(pipe_info.rIndex == ovutils::OV_INVALID) {
-            return false;
+            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 values
+        // 1  Left pipe is higher priority, do nothing.
+        // 0  Pipes of same priority.
+        //-1  Right pipe is of higher priority, needs swap.
+        if(ctx->mOverlay->comparePipePriority(pipe_info.lIndex,
+                pipe_info.rIndex) == -1) {
+            qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
         }
     }
 
     return true;
 }
 
-bool MDPCompSrcSplit::allocLayerPipes(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list) {
-    for(int index = 0 ; index < mCurrentFrame.layerCount; index++) {
-        if(mCurrentFrame.isFBComposed[index]) continue;
-        hwc_layer_1_t* layer = &list->hwLayers[index];
-        int mdpIndex = mCurrentFrame.layerToMDP[index];
-        PipeLayerPair& info = mCurrentFrame.mdpToLayer[mdpIndex];
-        info.pipeInfo = new MdpPipeInfoSplit;
-        info.rot = NULL;
-        MdpPipeInfoSplit& pipe_info = *(MdpPipeInfoSplit*)info.pipeInfo;
-
-        ePipeType type = MDPCOMP_OV_ANY;
-        if(!acquireMDPPipes(ctx, layer, pipe_info, type)) {
-            ALOGD_IF(isDebug(), "%s: Unable to get pipe for type = %d",
-                    __FUNCTION__, (int) type);
-            return false;
-        }
-    }
-    return true;
-}
-
 int MDPCompSrcSplit::configure(hwc_context_t *ctx, hwc_layer_1_t *layer,
         PipeLayerPair& PipeLayerPair) {
     private_handle_t *hnd = (private_handle_t *)layer->handle;
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index b6615ad..470ce12 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -308,9 +308,6 @@
     virtual bool acquireMDPPipes(hwc_context_t *ctx, hwc_layer_1_t* layer,
             MdpPipeInfoSplit& pipe_info, ePipeType type);
 
-    virtual bool allocLayerPipes(hwc_context_t *ctx,
-            hwc_display_contents_1_t* list);
-
     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 265aa9f..7e7f275 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -175,6 +175,19 @@
     return false;
 }
 
+int Overlay::comparePipePriority(utils::eDest pipe1Index,
+        utils::eDest pipe2Index) {
+    validate((int)pipe1Index);
+    validate((int)pipe2Index);
+    uint8_t pipe1Prio = mPipeBook[(int)pipe1Index].mPipe->getPriority();
+    uint8_t pipe2Prio = mPipeBook[(int)pipe2Index].mPipe->getPriority();
+    if(pipe1Prio > pipe2Prio)
+        return 1;
+    if(pipe1Prio < pipe2Prio)
+        return -1;
+    return 0;
+}
+
 bool Overlay::commit(utils::eDest dest) {
     bool ret = false;
     int index = (int)dest;
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index d8615cd..44193be 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -114,6 +114,12 @@
      * displays
      */
     bool isPipeTypeAttached(utils::eMdpPipeType type);
+    /* Compare pipe priorities and return
+     * 1 if 1st pipe has a higher priority
+     * 0 if both have the same priority
+     *-1 if 2nd pipe has a higher priority
+     */
+    int comparePipePriority(utils::eDest pipe1Index, utils::eDest pipe2Index);
     /* Returns pipe dump. Expects a NULL terminated buffer of big enough size
      * to populate.
      */
diff --git a/liboverlay/overlayCtrlData.h b/liboverlay/overlayCtrlData.h
index 26202ec..51209a7 100644
--- a/liboverlay/overlayCtrlData.h
+++ b/liboverlay/overlayCtrlData.h
@@ -79,6 +79,8 @@
     void setDownscale(int dscale_factor);
     /* Update the src format based on rotator's dest */
     void updateSrcFormat(const uint32_t& rotDstFormat);
+    /* return pipe priority */
+    uint8_t getPriority() const;
     /* dump the state of the object */
     void dump() const;
     /* Return the dump in the specified buffer */
@@ -208,6 +210,10 @@
     mMdp->setDownscale(dscale_factor);
 }
 
+inline uint8_t Ctrl::getPriority() const {
+    return mMdp->getPriority();
+}
+
 inline void Ctrl::getDump(char *buf, size_t len) {
     mMdp->getDump(buf, len);
 }
diff --git a/liboverlay/overlayMdp.h b/liboverlay/overlayMdp.h
index 843556b..d312c2e 100644
--- a/liboverlay/overlayMdp.h
+++ b/liboverlay/overlayMdp.h
@@ -80,6 +80,8 @@
     utils::Dim getDstRectDim() const;
     /* returns a copy to src rect dim */
     utils::Dim getSrcRectDim() const;
+    /* return pipe priority */
+    uint8_t getPriority() const;
     /* setVisualParam */
     bool setVisualParams(const MetaData_t& data);
 
@@ -304,6 +306,10 @@
         mOVInfo.flags |= MDP_SOURCE_ROTATED_90;
 }
 
+inline uint8_t MdpCtrl::getPriority() const {
+    return mOVInfo.priority;
+}
+
 ///////    MdpCtrl3D //////
 
 inline MdpCtrl3D::MdpCtrl3D() { reset(); }
diff --git a/liboverlay/pipes/overlayGenPipe.cpp b/liboverlay/pipes/overlayGenPipe.cpp
index 9e57223..303cd34 100644
--- a/liboverlay/pipes/overlayGenPipe.cpp
+++ b/liboverlay/pipes/overlayGenPipe.cpp
@@ -106,6 +106,10 @@
     return mCtrl->getCrop();
 }
 
+uint8_t GenericPipe::getPriority() const {
+    return mCtrl->getPriority();
+}
+
 void GenericPipe::dump() const
 {
     ALOGE("== Dump Generic pipe start ==");
diff --git a/liboverlay/pipes/overlayGenPipe.h b/liboverlay/pipes/overlayGenPipe.h
index 813a2b3..ee6f9ad 100644
--- a/liboverlay/pipes/overlayGenPipe.h
+++ b/liboverlay/pipes/overlayGenPipe.h
@@ -69,6 +69,8 @@
     bool isOpen() const;
     /* return Ctrl fd. Used for S3D */
     int getCtrlFd() const;
+    /* return pipe priority */
+    uint8_t getPriority() const;
     /* dump the state of the object */
     void dump() const;
     /* Return the dump in the specified buffer */
diff --git a/libvirtual/virtual.cpp b/libvirtual/virtual.cpp
index 5453e3a..ca64fad 100644
--- a/libvirtual/virtual.cpp
+++ b/libvirtual/virtual.cpp
@@ -177,13 +177,13 @@
         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);
 
+        initResolution(extW, extH);
+
         if(!qdutils::MDPVersion::getInstance().is8x26()
                 && (mHwcContext->mMDPDownscaleEnabled || isDRC)) {