Merge "liboverlay: Fix pipe priority mismatch on new allocations"
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index b63fb3a..8660740 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -541,7 +541,7 @@
             return false;
         }
 
-        if(ctx->mOverlay->comparePipePriority(destL, destR) == -1) {
+        if(ctx->mOverlay->needsPrioritySwap(destL, destR)) {
             qhwc::swap(destL, destR);
         }
 
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 4312dec..34cc39f 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -2673,12 +2673,8 @@
             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) {
+        if(ctx->mOverlay->needsPrioritySwap(pipe_info.lIndex,
+                    pipe_info.rIndex)) {
             qhwc::swap(pipe_info.lIndex, pipe_info.rIndex);
         }
     }
diff --git a/liboverlay/overlay.cpp b/liboverlay/overlay.cpp
index c250919..ca599ed 100644
--- a/liboverlay/overlay.cpp
+++ b/liboverlay/overlay.cpp
@@ -282,38 +282,58 @@
     return false;
 }
 
-int Overlay::comparePipePriority(utils::eDest pipe1Index,
+bool Overlay::needsPrioritySwap(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;
-    else if(pipe1Prio < pipe2Prio)
-        return 1;
-    else {
+
+    int pipe1Id = mPipeBook[(int)pipe1Index].mPipe->getPipeId();
+    int pipe2Id = mPipeBook[(int)pipe2Index].mPipe->getPipeId();
+
+    utils::eMdpPipeType leftType = PipeBook::getPipeType(pipe1Index);
+    utils::eMdpPipeType rightType = PipeBook::getPipeType(pipe2Index);
+
+    if(pipe1Id >=0 && pipe2Id >=0) {
+        // LEFT priority should be higher then RIGHT
+        return (pipe1Prio > pipe2Prio);
+    } else if(pipe1Id < 0 && pipe2Id < 0) {
         // If we are here, Source Split is enabled and both pipes are
         // new requests. In this case left type should be of higher prio
         // than right type
-        utils::eMdpPipeType leftType = PipeBook::getPipeType(pipe1Index);
-        utils::eMdpPipeType rightType = PipeBook::getPipeType(pipe2Index);
-
         if(leftType == rightType) {
             //Safe. Onus on driver to assign correct pipes within same type
-            return 1;
+            return false;
         } else if(leftType == OV_MDP_PIPE_DMA or rightType == OV_MDP_PIPE_VG) {
             //If we are here, right is definitely a higher prio type.
             //This check takes advantage of having only 3 types and avoids 3
             //different failure combination checks.
-            return -1;
+            return true;
         } else {
             //Types are correct priority-wise
-            return 1;
+            return false;
+        }
+    } else if(pipe1Id < 0) {
+        //LEFT needs new allocation.
+        if(leftType == rightType) {
+            // If RIGHT has highest priority(lowest id), swap it.
+            return (pipe2Id == PipeBook::pipeMinID[leftType]);
+        } else {
+            // Swap if needs lowest priority type pipe.
+            return (leftType == OV_MDP_PIPE_DMA);
+        }
+    } else { /* if (pipe2Id < 0) */
+        // RIGHT needs new allocation.
+        if(leftType == rightType) {
+            // If LEFT has lowest priority(highest id), swap it.
+            return (pipe1Id == PipeBook::pipeMaxID[leftType]);
+        } else {
+            // Swap if needs highest  priority type pipe.
+            return (rightType == OV_MDP_PIPE_VG);
         }
     }
-
-    return 0;
 }
 
 bool Overlay::commit(utils::eDest dest) {
@@ -413,6 +433,13 @@
         }
     }
 
+    PipeBook::pipeMinID[OV_MDP_PIPE_RGB] = 8;
+    PipeBook::pipeMaxID[OV_MDP_PIPE_RGB] = (numPipesXType[OV_MDP_PIPE_RGB] == 3)? 32 : 512;
+    PipeBook::pipeMinID[OV_MDP_PIPE_VG] = 1;
+    PipeBook::pipeMaxID[OV_MDP_PIPE_VG] = (numPipesXType[OV_MDP_PIPE_VG] == 3)? 4 : 256;
+    PipeBook::pipeMinID[OV_MDP_PIPE_DMA] = 64;
+    PipeBook::pipeMaxID[OV_MDP_PIPE_DMA] = 128;
+
     FILE *displayDeviceFP = NULL;
     char fbType[MAX_FRAME_BUFFER_NAME_SIZE];
     char msmFbTypePath[MAX_FRAME_BUFFER_NAME_SIZE];
@@ -578,6 +605,8 @@
 int Overlay::PipeBook::sAllocatedBitmap = 0;
 utils::eMdpPipeType Overlay::PipeBook::pipeTypeLUT[utils::OV_MAX] =
     {utils::OV_MDP_PIPE_ANY};
+int Overlay::PipeBook::pipeMinID[utils::OV_MDP_PIPE_ANY] = {0};
+int Overlay::PipeBook::pipeMaxID[utils::OV_MDP_PIPE_ANY] = {0};
 void *Overlay::sLibScaleHandle = NULL;
 int (*Overlay::sFnProgramScale)(struct mdp_overlay_list *) = NULL;
 /* Dynamically link ABL library */
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 984b439..45b5e57 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -123,11 +123,10 @@
      */
     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
+     * true - A swap is needed to fix the priority.
+     * false - Good, priority wise.
      */
-    int comparePipePriority(utils::eDest pipe1Index, utils::eDest pipe2Index);
+    bool needsPrioritySwap(utils::eDest pipe1Index, utils::eDest pipe2Index);
     /* Returns pipe dump. Expects a NULL terminated buffer of big enough size
      * to populate.
      */
@@ -229,6 +228,9 @@
 
         static int NUM_PIPES;
         static utils::eMdpPipeType pipeTypeLUT[utils::OV_MAX];
+        static int pipeMinID[utils::OV_MDP_PIPE_ANY];
+        static int pipeMaxID[utils::OV_MDP_PIPE_ANY];
+
         /* Session for reserved pipes */
         enum Session {
             NONE,