Merge "display: Add support for interleaved YUY2 and YUYV format."
diff --git a/libcopybit/copybit.cpp b/libcopybit/copybit.cpp
index 521d55d..ec12b83 100644
--- a/libcopybit/copybit.cpp
+++ b/libcopybit/copybit.cpp
@@ -231,7 +231,12 @@
 /** copy the bits */
 static int msm_copybit(struct copybit_context_t *dev, void const *list)
 {
-    int err = ioctl(dev->mFD, MSMFB_ASYNC_BLIT,
+    int err;
+    if (dev->relFence != -1) {
+        close(dev->relFence);
+        dev->relFence = -1;
+    }
+    err = ioctl(dev->mFD, MSMFB_ASYNC_BLIT,
                     (struct mdp_async_blit_req_list const*)list);
     ALOGE_IF(err<0, "copyBits failed (%s)", strerror(errno));
     if (err == 0) {
@@ -408,7 +413,6 @@
             list->count = 0;
             list->sync.acq_fen_fd_cnt = 0;
             ctx->acqFence[list->sync.acq_fen_fd_cnt++] = acquireFenceFd;
-            ctx->relFence = -1;
         }
     }
     return 0;
@@ -515,9 +519,7 @@
 
             if (++list->count == maxCount) {
                 status = msm_copybit(ctx, list);
-                if (ctx->relFence != -1) {
-                    list->sync.acq_fen_fd_cnt = 0;
-                }
+                list->sync.acq_fen_fd_cnt = 0;
                 list->count = 0;
             }
         }
@@ -525,9 +527,7 @@
             //Before freeing the buffer we need buffer passed through blit call
             if (list->count != 0) {
                 status = msm_copybit(ctx, list);
-                if (ctx->relFence != -1) {
-                    list->sync.acq_fen_fd_cnt = 0;
-                }
+                list->sync.acq_fen_fd_cnt = 0;
                 list->count = 0;
             }
             free_buffer(yv12_handle);
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index dbb4413..8f2cf55 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -437,7 +437,7 @@
         dtdy > scaleLimitMax ||
         dsdx < 1/scaleLimitMin ||
         dtdy < 1/scaleLimitMin) {
-        ALOGE("%s: greater than max supported size dsdx=%f dtdy=%f \
+        ALOGW("%s: greater than max supported size dsdx=%f dtdy=%f \
               scaleLimitMax=%f scaleLimitMin=%f", __FUNCTION__,dsdx,dtdy,
                                           scaleLimitMax,1/scaleLimitMin);
         return -1;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index d388ebb..44db2bc 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--;
+                }
             }
         }
     }
@@ -748,9 +751,12 @@
             private_handle_t *hnd = (private_handle_t *)layer->handle;
             if (hnd) {
                 hwc_rect_t crop = layer->sourceCrop;
+                hwc_rect_t dst = layer->displayFrame;
+                trimLayer(ctx, mDpy, layer->transform, crop, dst);
                 float bpp = ((float)hnd->size) / (hnd->width * hnd->height);
-                size += bpp * ((crop.right - crop.left) *
-                    (crop.bottom - crop.top));
+                size += bpp * (crop.right - crop.left) *
+                    (crop.bottom - crop.top) *
+                    ctx->dpyAttr[mDpy].yres / (dst.bottom - dst.top);
             }
         }
     }
@@ -839,7 +845,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 +933,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 +1131,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);
 };
diff --git a/liboverlay/overlay.h b/liboverlay/overlay.h
index 4b91038..9d7f5c8 100644
--- a/liboverlay/overlay.h
+++ b/liboverlay/overlay.h
@@ -86,6 +86,8 @@
     int availablePipes(int dpy, int mixer);
     /* Returns available ("unallocated") pipes for a display */
     int availablePipes(int dpy);
+    /* Returns available ("unallocated") pipe of given type for a display */
+    int availablePipes(int dpy, utils::eMdpPipeType type);
     /* Returns if any of the requested pipe type is attached to any of the
      * displays
      */
@@ -215,6 +217,19 @@
     return avail;
 }
 
+inline int Overlay::availablePipes(int dpy, utils::eMdpPipeType type) {
+    int avail = 0;
+    for(int i = 0; i < PipeBook::NUM_PIPES; i++) {
+        if((mPipeBook[i].mDisplay == DPY_UNUSED ||
+            mPipeBook[i].mDisplay == dpy) &&
+            PipeBook::isNotAllocated(i) &&
+            type == PipeBook::getPipeType((utils::eDest)i)) {
+            avail++;
+        }
+    }
+    return avail;
+}
+
 inline void Overlay::setDMAMode(const int& mode) {
     if(mode == DMA_LINE_MODE || mode == DMA_BLOCK_MODE)
         sDMAMode = mode;