hwc/overlay: Add support for pipe priorities, 1 pipe config for FB

If using source split to stage 2 pipes on the same mixer stage,
the left pipe needs to be a higher priority than the right.

Add API in overlay to compare pipe priorities and use this in
source split config to stage pipes accordingly.

Add support for 1 pipe config for FB if updating rect is within 2048
pixels.

Change-Id: I8b33d5ebd0f8765ee842bab128d8abd67a110145
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index b51b2ea..2dd256e 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -426,35 +426,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 +445,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 */