Merge "sde: Add support for layer caching"
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index 3e16072..58cf374 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -523,9 +523,15 @@
             qdutils::MDPVersion::getInstance().isSrcSplitAlways();
     const uint32_t lSplit = getLeftSplit(ctx, mDpy);
     const uint32_t cropWidth = sourceCrop.right - sourceCrop.left;
+    const uint32_t cropHeight = sourceCrop.bottom - sourceCrop.top;
+    const uint32_t dstWidth = displayFrame.right - displayFrame.left;
+    const uint32_t dstHeight = displayFrame.bottom - displayFrame.top;
+    const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
+    const uint32_t mixerClock = lSplit;
 
     if((cropWidth > qdutils::MDPVersion::getInstance().getMaxMixerWidth()) or
-            (primarySplitAlways and cropWidth > lSplit)) {
+            (primarySplitAlways and
+            (cropWidth > lSplit or layerClock > mixerClock))) {
         destR = ov.getPipe(pipeSpecs);
         if(destR == ovutils::OV_INVALID) {
             ALOGE("%s: No pipes available to configure fb for dpy %d's right"
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index a2a5f2d..aa7783c 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -532,7 +532,8 @@
             }
 
             /* deduct any opaque region from visibleRect */
-            if (layer->blending == HWC_BLENDING_NONE)
+            if (layer->blending == HWC_BLENDING_NONE &&
+                    layer->planeAlpha == 0xFF)
                 visibleRect = deductRect(visibleRect, res);
         }
     }
@@ -638,7 +639,8 @@
                 return false;
             }
 
-            if (layer->blending == HWC_BLENDING_NONE) {
+            if (layer->blending == HWC_BLENDING_NONE &&
+                    layer->planeAlpha == 0xFF) {
                 visibleRectL = deductRect(visibleRectL, l_res);
                 visibleRectR = deductRect(visibleRectR, r_res);
             }
@@ -2568,18 +2570,26 @@
     MDPVersion& mdpHw = MDPVersion::getInstance();
     bool primarySplitAlways = (mDpy == HWC_DISPLAY_PRIMARY) and
             mdpHw.isSrcSplitAlways();
-    int lSplit = getLeftSplit(ctx, mDpy);
-    int dstWidth = dst.right - dst.left;
-    int cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
+    const uint32_t lSplit = getLeftSplit(ctx, mDpy);
+    const uint32_t dstWidth = dst.right - dst.left;
+    const uint32_t dstHeight = dst.bottom - dst.top;
+    const uint32_t cropWidth = has90Transform(layer) ? crop.bottom - crop.top :
             crop.right - crop.left;
+    const uint32_t cropHeight = has90Transform(layer) ? crop.right - crop.left :
+            crop.bottom - crop.top;
+    //Approximation to actual clock, ignoring the common factors in pipe and
+    //mixer cases like line_time
+    const uint32_t layerClock = getLayerClock(dstWidth, dstHeight, cropHeight);
+    const uint32_t mixerClock = lSplit;
 
     //TODO Even if a 4k video is going to be rot-downscaled to dimensions under
     //pipe line length, we are still using 2 pipes. This is fine just because
     //this is source split where destination doesn't matter. Evaluate later to
     //see if going through all the calcs to save a pipe is worth it
-    if(dstWidth > (int) mdpHw.getMaxMixerWidth() or
-            cropWidth > (int) mdpHw.getMaxMixerWidth() or
-            (primarySplitAlways and (cropWidth > lSplit))) {
+    if(dstWidth > mdpHw.getMaxMixerWidth() or
+            cropWidth > mdpHw.getMaxMixerWidth() or
+            (primarySplitAlways and
+            (cropWidth > lSplit or layerClock > mixerClock))) {
         pipe_info.rIndex = ctx->mOverlay->getPipe(pipeSpecs);
         if(pipe_info.rIndex == ovutils::OV_INVALID) {
             return false;
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 51e23de..916fbc7 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -1383,7 +1383,8 @@
         //see if there is no blending required.
         //If it is opaque see if we can substract this region from below
         //layers.
-        if(list->hwLayers[i].blending == HWC_BLENDING_NONE) {
+        if(list->hwLayers[i].blending == HWC_BLENDING_NONE &&
+                list->hwLayers[i].planeAlpha == 0xFF) {
             int j= i-1;
             hwc_rect_t& topframe =
                 (hwc_rect_t&)list->hwLayers[i].displayFrame;
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 2da8512..741527c 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -674,6 +674,11 @@
     return ctx->dpyAttr[HWC_DISPLAY_VIRTUAL].connected;
 }
 
+inline uint32_t getLayerClock(const uint32_t& dstW, const uint32_t& dstH,
+        const uint32_t& srcH) {
+    return max(dstW, (srcH * dstW) / dstH);
+}
+
 };
 
 #endif //HWC_UTILS_H