hwc: Handle multiple videos with priority to secure

In video handling this patch makes sure:
1) Sufficient VG pipes are available, not just any pipes
2) If VG pipes are insufficient in multi-video scenarios
    preference is given to secure videos

Change-Id: I170592463a1c28348108a1b12d60908cf3063d7d
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index d388ebb..6e44234 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -482,7 +482,7 @@
     //Setup mCurrentFrame
     mCurrentFrame.reset(numAppLayers);
     updateLayerCache(ctx, list);
-    updateYUV(ctx, list);
+    updateYUV(ctx, list, false /*secure only*/);
     batchLayers(); //sets up fbZ also
 
     int mdpCount = mCurrentFrame.mdpCount;
@@ -505,10 +505,10 @@
 }
 
 bool MDPComp::isOnlyVideoDoable(hwc_context_t *ctx,
-        hwc_display_contents_1_t* list){
+        hwc_display_contents_1_t* list, bool secureOnly) {
     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
     mCurrentFrame.reset(numAppLayers);
-    updateYUV(ctx, list);
+    updateYUV(ctx, list, secureOnly);
     int mdpCount = mCurrentFrame.mdpCount;
     int fbNeeded = int(mCurrentFrame.fbCount != 0);
 
@@ -644,8 +644,8 @@
     ALOGD_IF(isDebug(),"%s: cached count: %d",__FUNCTION__, numCacheableLayers);
 }
 
-void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list) {
-
+void MDPComp::updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
+        bool secureOnly) {
     int nYuvCount = ctx->listStats[mDpy].yuvCount;
     if(!nYuvCount && mDpy) {
         //Reset "No animation on external display" related  parameters.
@@ -667,8 +667,11 @@
             }
         } else {
             if(mCurrentFrame.isFBComposed[nYuvIndex]) {
-                mCurrentFrame.isFBComposed[nYuvIndex] = false;
-                mCurrentFrame.fbCount--;
+                private_handle_t *hnd = (private_handle_t *)layer->handle;
+                if(!secureOnly || isSecureBuffer(hnd)) {
+                    mCurrentFrame.isFBComposed[nYuvIndex] = false;
+                    mCurrentFrame.fbCount--;
+                }
             }
         }
     }
@@ -839,7 +842,8 @@
                 mCurrentFrame.needsRedraw = true;
             }
         }
-    } else if(isOnlyVideoDoable(ctx, list)) {
+    } else if(isOnlyVideoDoable(ctx, list, false /*secure only*/) ||
+            isOnlyVideoDoable(ctx, list, true /*secure only*/)) {
         //All layers marked for MDP comp cannot be bypassed.
         //Try to compose atleast YUV layers through MDP comp and let
         //all the RGB layers compose in FB
@@ -926,6 +930,36 @@
         return false;
     }
 
+    if(not areVGPipesAvailable(ctx, list)) {
+        return false;
+    }
+
+    return true;
+}
+
+bool MDPCompNonSplit::areVGPipesAvailable(hwc_context_t *ctx,
+        hwc_display_contents_1_t* list) {
+    overlay::Overlay& ov = *ctx->mOverlay;
+    int pipesNeeded = 0;
+    for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
+        if(!mCurrentFrame.isFBComposed[i]) {
+            hwc_layer_1_t* layer = &list->hwLayers[i];
+            hwc_rect_t dst = layer->displayFrame;
+            private_handle_t *hnd = (private_handle_t *)layer->handle;
+            if(isYuvBuffer(hnd)) {
+                pipesNeeded++;
+            }
+        }
+    }
+
+    int availableVGPipes = ov.availablePipes(mDpy, ovutils::OV_MDP_PIPE_VG);
+    if(pipesNeeded > availableVGPipes) {
+        ALOGD_IF(isDebug(), "%s: Insufficient VG pipes for video layers"
+                "dpy %d needed %d, avail %d",
+                __FUNCTION__, mDpy, pipesNeeded, availableVGPipes);
+        return false;
+    }
+
     return true;
 }
 
@@ -1094,6 +1128,42 @@
         return false;
     }
 
+    if(not areVGPipesAvailable(ctx, list)) {
+        return false;
+    }
+
+    return true;
+}
+
+bool MDPCompSplit::areVGPipesAvailable(hwc_context_t *ctx,
+        hwc_display_contents_1_t* list) {
+    overlay::Overlay& ov = *ctx->mOverlay;
+    int pipesNeeded = 0;
+    const int lSplit = getLeftSplit(ctx, mDpy);
+    for(int i = 0; i < mCurrentFrame.layerCount; ++i) {
+        if(!mCurrentFrame.isFBComposed[i]) {
+            hwc_layer_1_t* layer = &list->hwLayers[i];
+            hwc_rect_t dst = layer->displayFrame;
+            private_handle_t *hnd = (private_handle_t *)layer->handle;
+            if(isYuvBuffer(hnd)) {
+                if(dst.left < lSplit) {
+                    pipesNeeded++;
+                }
+                if(dst.right > lSplit) {
+                    pipesNeeded++;
+                }
+            }
+        }
+    }
+
+    int availableVGPipes = ov.availablePipes(mDpy, ovutils::OV_MDP_PIPE_VG);
+    if(pipesNeeded > availableVGPipes) {
+        ALOGD_IF(isDebug(), "%s: Insufficient VG pipes for video layers"
+                "dpy %d needed %d, avail %d",
+                __FUNCTION__, mDpy, pipesNeeded, availableVGPipes);
+        return false;
+    }
+
     return true;
 }
 
diff --git a/libhwcomposer/hwc_mdpcomp.h b/libhwcomposer/hwc_mdpcomp.h
index da4b330..7fb0968 100644
--- a/libhwcomposer/hwc_mdpcomp.h
+++ b/libhwcomposer/hwc_mdpcomp.h
@@ -139,7 +139,8 @@
     /* check if we can use layer cache to do at least partial MDP comp */
     bool partialMDPComp(hwc_context_t *ctx, hwc_display_contents_1_t* list);
     /* checks for conditions where only video can be bypassed */
-    bool isOnlyVideoDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list);
+    bool isOnlyVideoDoable(hwc_context_t *ctx, hwc_display_contents_1_t* list,
+            bool secureOnly);
     /* checks for conditions where YUV layers cannot be bypassed */
     bool isYUVDoable(hwc_context_t* ctx, hwc_layer_1_t* layer);
     /* calcs bytes read by MDP for a given frame */
@@ -159,7 +160,8 @@
     /* optimize layers for mdp comp*/
     void batchLayers();
     /* updates cache map with YUV info */
-    void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list);
+    void updateYUV(hwc_context_t* ctx, hwc_display_contents_1_t* list,
+            bool secureOnly);
     bool programMDP(hwc_context_t *ctx, hwc_display_contents_1_t* list);
     bool programYUV(hwc_context_t *ctx, hwc_display_contents_1_t* list);
     void reset(const int& numAppLayers, hwc_display_contents_1_t* list);
@@ -203,6 +205,10 @@
     /* Checks for pipes needed versus pipes available */
     virtual bool arePipesAvailable(hwc_context_t *ctx,
             hwc_display_contents_1_t* list);
+
+    /* Checks for video pipes needed versus pipes available */
+    virtual bool areVGPipesAvailable(hwc_context_t *ctx,
+            hwc_display_contents_1_t* list);
 };
 
 class MDPCompSplit : public MDPComp {
@@ -232,6 +238,10 @@
     virtual bool arePipesAvailable(hwc_context_t *ctx,
             hwc_display_contents_1_t* list);
 
+    /* Checks for video pipes needed versus pipes available */
+    virtual bool areVGPipesAvailable(hwc_context_t *ctx,
+            hwc_display_contents_1_t* list);
+
     int pipesNeeded(hwc_context_t *ctx, hwc_display_contents_1_t* list,
             int mixer);
 };