Merge "hwc: Calculate true rendering area to be blitted using MDP"
diff --git a/libhwcomposer/hwc_copybit.cpp b/libhwcomposer/hwc_copybit.cpp
index ae7431f..f547f19 100644
--- a/libhwcomposer/hwc_copybit.cpp
+++ b/libhwcomposer/hwc_copybit.cpp
@@ -82,6 +82,29 @@
     return true;
 }
 
+bool CopyBit::isSmartBlitPossible(const hwc_display_contents_1_t *list){
+    if(list->numHwLayers > 2) {
+        hwc_rect_t displayFrame0 = {0, 0, 0, 0};
+        hwc_rect_t displayFrame1 = {0, 0, 0, 0};
+        for (unsigned int i=0; i<list->numHwLayers -1; i++) {
+            hwc_rect_t displayFrame = getIntersection(mDirtyRect,
+                                                list->hwLayers[i].displayFrame);
+            if (isValidRect(displayFrame) && !isValidRect(displayFrame0)) {
+                displayFrame0 = displayFrame;
+            } else if(isValidRect(displayFrame)) {
+                displayFrame1 = displayFrame;
+                break;
+            }
+        }
+        if((displayFrame0 == displayFrame1) &&
+            not (list->flags & (MDP_ROT_90 | MDP_FLIP_UD | MDP_FLIP_LR))) {
+            ALOGD_IF (DEBUG_COPYBIT, "%s:Smart Bilt Possible",__FUNCTION__);
+            return true;
+        }
+    }
+    return false;
+}
+
 bool CopyBit::canUseCopybitForRGB(hwc_context_t *ctx,
                                         hwc_display_contents_1_t *list,
                                         int dpy) {
@@ -99,7 +122,11 @@
         unsigned int renderArea = getRGBRenderingArea(ctx, list);
             ALOGD_IF (DEBUG_COPYBIT, "%s:renderArea %u, fbArea %u",
                                   __FUNCTION__, renderArea, fbArea);
-        if (renderArea < (mDynThreshold * fbArea)) {
+        double dynThreshold = mDynThreshold;
+        if(not isSmartBlitPossible(list))
+            dynThreshold -= 1;
+
+        if (renderArea < (dynThreshold * fbArea)) {
             return true;
         }
     } else if ((compositionType & qdutils::COMPOSITION_TYPE_MDP)) {
@@ -326,6 +353,20 @@
         return false;
     }
 
+    mDirtyLayerIndex =  checkDirtyRect(ctx, list, dpy);
+    ALOGD_IF (DEBUG_COPYBIT, "%s:Dirty Layer Index: %d",
+                                       __FUNCTION__, mDirtyLayerIndex);
+    hwc_rect_t clearRegion = {0,0,0,0};
+    int last = (uint32_t)list->numHwLayers - 1;
+    mDirtyRect = list->hwLayers[last].displayFrame;
+    if (mDirtyLayerIndex != -1) {
+        if (mDirtyLayerIndex == NO_UPDATING_LAYER) {
+            mDirtyRect = clearRegion;
+        } else {
+            mDirtyRect = list->hwLayers[mDirtyLayerIndex].displayFrame;
+        }
+    }
+
     bool useCopybitForYUV = canUseCopybitForYUV(ctx);
     bool useCopybitForRGB = canUseCopybitForRGB(ctx, list, dpy);
     LayerProp *layerProp = ctx->layerProp[dpy];
@@ -559,27 +600,12 @@
         }
     }
 
-    mDirtyLayerIndex =  checkDirtyRect(ctx, list, dpy);
-    ALOGD_IF (DEBUG_COPYBIT, "%s:Dirty Layer Index: %d",
-                                       __FUNCTION__, mDirtyLayerIndex);
-
-    hwc_rect_t clearRegion = {0,0,0,0};
-    mDirtyRect = list->hwLayers[last].displayFrame;
-
     if (mDirtyLayerIndex != NO_UPDATING_LAYER &&
            not CBUtils::uiClearRegion(list, ctx->mMDP.version, layerProp,
                                    mDirtyLayerIndex, mEngine, renderBuffer)){
         mDirtyLayerIndex = -1;
     }
 
-    if (mDirtyLayerIndex != -1) {
-        if (mDirtyLayerIndex == NO_UPDATING_LAYER) {
-            mDirtyRect = clearRegion;
-        } else {
-            mDirtyRect = list->hwLayers[mDirtyLayerIndex].displayFrame;
-        }
-    }
-
     // numAppLayers-1, as we iterate from 0th layer index with HWC_COPYBIT flag
     for (int i = 0; i <= (ctx->listStats[dpy].numAppLayers-1); i++) {
         if(!(layerProp[i].mFlags & HWC_COPYBIT)) {
@@ -1138,9 +1164,10 @@
                                  unsigned int& width, unsigned int& height)
 {
     hwc_rect_t displayFrame  = layer->displayFrame;
+    hwc_rect_t result = getIntersection(mDirtyRect, displayFrame);
 
-    width = displayFrame.right - displayFrame.left;
-    height = displayFrame.bottom - displayFrame.top;
+    width = result.right - result.left;
+    height = result.bottom - result.top;
 }
 
 bool CopyBit::validateParams(hwc_context_t *ctx,
diff --git a/libhwcomposer/hwc_copybit.h b/libhwcomposer/hwc_copybit.h
index 993c790..0d05dd9 100644
--- a/libhwcomposer/hwc_copybit.h
+++ b/libhwcomposer/hwc_copybit.h
@@ -141,6 +141,7 @@
                   int dpy);
     bool isLayerChanging(hwc_context_t *ctx,
                             hwc_display_contents_1_t *list, int k);
+    bool isSmartBlitPossible(const hwc_display_contents_1_t *list);
 };
 
 }; //namespace qhwc