hwc: Check for mdp max downscale.

Check for MDP's max downscale limit before using MDP for composition.
MDP 4 can downscale in each direction upto a factor of 8.

Bug: 8744080
Change-Id: Ib9f640a6b1db3ba6244eb665a060f624425b4841
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index f9f76c7..98905b1 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -16,6 +16,7 @@
  * limitations under the License.
  */
 
+#include <math.h>
 #include "hwc_mdpcomp.h"
 #include <sys/ioctl.h>
 #include "external.h"
@@ -264,7 +265,7 @@
 }
 
 bool MDPComp::isValidDimension(hwc_context_t *ctx, hwc_layer_1_t *layer) {
-
+    const int dpy = HWC_DISPLAY_PRIMARY;
     private_handle_t *hnd = (private_handle_t *)layer->handle;
 
     if(!hnd) {
@@ -275,24 +276,21 @@
     int hw_w = ctx->dpyAttr[mDpy].xres;
     int hw_h = ctx->dpyAttr[mDpy].yres;
 
-    hwc_rect_t sourceCrop = layer->sourceCrop;
-    hwc_rect_t displayFrame = layer->displayFrame;
-
-    hwc_rect_t crop =  sourceCrop;
-    int crop_w = crop.right - crop.left;
-    int crop_h = crop.bottom - crop.top;
-
-    hwc_rect_t dst = displayFrame;
-    int dst_w = dst.right - dst.left;
-    int dst_h = dst.bottom - dst.top;
+    hwc_rect_t crop = layer->sourceCrop;
+    hwc_rect_t dst = layer->displayFrame;
 
     if(dst.left < 0 || dst.top < 0 || dst.right > hw_w || dst.bottom > hw_h) {
-        hwc_rect_t scissor = {0, 0, hw_w, hw_h };
-        qhwc::calculate_crop_rects(crop, dst, scissor, layer->transform);
-        crop_w = crop.right - crop.left;
-        crop_h = crop.bottom - crop.top;
+       hwc_rect_t scissor = {0, 0, hw_w, hw_h };
+       qhwc::calculate_crop_rects(crop, dst, scissor, layer->transform);
     }
 
+    int crop_w = crop.right - crop.left;
+    int crop_h = crop.bottom - crop.top;
+    int dst_w = dst.right - dst.left;
+    int dst_h = dst.bottom - dst.top;
+    float w_dscale = ceilf((float)crop_w / (float)dst_w);
+    float h_dscale = ceilf((float)crop_h / (float)dst_h);
+
     /* Workaround for MDP HW limitation in DSI command mode panels where
      * FPS will not go beyond 30 if buffers on RGB pipes are of width or height
      * less than 5 pixels
@@ -302,6 +300,25 @@
     if((crop_w < 5)||(crop_h < 5))
         return false;
 
+    const uint32_t downscale =
+            qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
+    if(ctx->mMDP.version >= qdutils::MDSS_V5) {
+        /* Workaround for downscales larger than 4x.
+         * Will be removed once decimator block is enabled for MDSS
+         */
+        if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
+            if(crop_w > MAX_DISPLAY_DIM || w_dscale > downscale ||
+                    h_dscale > downscale)
+                return false;
+        } else {
+            if(w_dscale > 64 || h_dscale > 64)
+                return false;
+        }
+    } else { //A-family
+        if(w_dscale > downscale || h_dscale > downscale)
+            return false;
+    }
+
     return true;
 }
 
@@ -390,13 +407,14 @@
         hwc_layer_1_t* layer = &list->hwLayers[i];
         private_handle_t *hnd = (private_handle_t *)layer->handle;
 
-        if(layer->transform & HWC_TRANSFORM_ROT_90 && !isYuvBuffer(hnd)) {
+        if((layer->transform & HWC_TRANSFORM_ROT_90) && !isYuvBuffer(hnd)) {
             ALOGD_IF(isDebug(), "%s: orientation involved",__FUNCTION__);
             return false;
         }
 
-        if(!isYuvBuffer(hnd) && !isValidDimension(ctx,layer)) {
-            ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",__FUNCTION__);
+        if(!isValidDimension(ctx,layer)) {
+            ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
+                __FUNCTION__);
             return false;
         }
     }
@@ -468,13 +486,16 @@
     int numAppLayers = ctx->listStats[mDpy].numAppLayers;
     mCurrentFrame.reset(numAppLayers);
     updateYUV(ctx, list);
-    int mdpCount = mCurrentFrame.layerCount - mCurrentFrame.fbCount;
+    int mdpCount = mCurrentFrame.mdpCount;
     int fbNeeded = int(mCurrentFrame.fbCount != 0);
 
     if(!isYuvPresent(ctx, mDpy)) {
         return false;
     }
 
+    if(!mdpCount)
+        return false;
+
     if(mdpCount > (sMaxPipesPerMixer - fbNeeded)) {
         ALOGD_IF(isDebug(), "%s: Exceeds MAX_PIPES_PER_MIXER",__FUNCTION__);
         return false;
@@ -504,24 +525,12 @@
         return false;
     }
 
-    if(!qdutils::MDPVersion::getInstance().supportsDecimation()) {
-        const uint32_t downscale =
-                qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
-        hwc_rect_t crop = layer->sourceCrop;
-        hwc_rect_t dst = layer->displayFrame;
-        int cWidth = crop.right - crop.left;
-        int cHeight = crop.bottom - crop.top;
-        int dWidth = dst.right - dst.left;
-        int dHeight = dst.bottom - dst.top;
-
-        if(layer->transform & HAL_TRANSFORM_ROT_90) {
-            swap(cWidth, cHeight);
-        }
-
-        if(cWidth > MAX_DISPLAY_DIM || (cWidth/dWidth) > downscale ||
-                    (cHeight/dHeight) > downscale)
-            return false;
+    if(!isValidDimension(ctx, layer)) {
+        ALOGD_IF(isDebug(), "%s: Buffer is of invalid width",
+            __FUNCTION__);
+        return false;
     }
+
     return true;
 }