hwc: Enable mdp downscale feature for 4k resolution

Enable MDP Downscale feature for primary resolution greater than
2048 only for the targets that supports source split.

Change-Id: I21871b099f74543aa8c2416bac41e3a16d4ce72d
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index d12d9f0..0a1335a 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -589,9 +589,11 @@
             // if primary resolution is more than the hdmi resolution
             // configure dpy attr to primary resolution and set
             // downscale mode
-            // Restrict this upto 1080p resolution max
-            if(((priW * priH) > (width * height)) &&
-               ((priW * priH) <= SUPPORTED_DOWNSCALE_AREA)) {
+            // Restrict this upto 1080p resolution max, if target does not
+            // support source split feature.
+            if((priW * priH) > (width * height) &&
+                (((priW * priH) <= SUPPORTED_DOWNSCALE_AREA) ||
+                qdutils::MDPVersion::getInstance().isSrcSplit())) {
                 // tmpW and tmpH will hold the primary dimensions before we
                 // update the aspect ratio if necessary.
                 int tmpW = priW;
@@ -609,14 +611,39 @@
                 // keeping aspect ratio intact.
                 hwc_rect r = {0, 0, 0, 0};
                 qdutils::getAspectRatioPosition(tmpW, tmpH, width, height, r);
-                mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres =
-                                                              r.right - r.left;
-                mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres =
-                                                              r.bottom - r.top;
+                int newExtW = r.right - r.left;
+                int newExtH = r.bottom - r.top;
+                int alignedExtW;
+                int alignedExtH;
+                // On 8994 and below targets MDP supports only 4X downscaling,
+                // Restricting selected external resolution to be exactly 4X
+                // greater resolution than actual external resolution
+                int maxMDPDownScale =
+                        qdutils::MDPVersion::getInstance().getMaxMDPDownscale();
+                if((width * height * maxMDPDownScale) < (newExtW * newExtH)) {
+                    float upScaleFactor = (float)maxMDPDownScale / 2.0f;
+                    newExtW = (int)((float)width * upScaleFactor);
+                    newExtH = (int)((float)height * upScaleFactor);
+                }
+                // Align it down so that the new aligned resolution does not
+                // exceed the maxMDPDownscale factor
+                alignedExtW = overlay::utils::aligndown(newExtW, 4);
+                alignedExtH = overlay::utils::aligndown(newExtH, 4);
+                mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres = alignedExtW;
+                mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres = alignedExtH;
                 // Set External Display MDP Downscale mode indicator
                 mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].mDownScaleMode =true;
             }
         }
+        ALOGD_IF(DEBUG_MDPDOWNSCALE, "Selected external resolution [%d X %d] "
+                 "maxMDPDownScale %d MDPDownScaleMode %d srcSplitEnabled %d "
+                 "MDPDownscale feature %d",
+                 mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].xres,
+                 mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].yres,
+                 qdutils::MDPVersion::getInstance().getMaxMDPDownscale(),
+                 mHwcContext->dpyAttr[HWC_DISPLAY_EXTERNAL].mDownScaleMode,
+                 qdutils::MDPVersion::getInstance().isSrcSplit(),
+                 mHwcContext->mMDPDownscaleEnabled);
         //Initialize the display viewFrame info
         mHwcContext->mViewFrame[HWC_DISPLAY_EXTERNAL].left = 0;
         mHwcContext->mViewFrame[HWC_DISPLAY_EXTERNAL].top = 0;
diff --git a/libhwcomposer/hwc_mdpcomp.cpp b/libhwcomposer/hwc_mdpcomp.cpp
index 0d968c8..6b114a9 100644
--- a/libhwcomposer/hwc_mdpcomp.cpp
+++ b/libhwcomposer/hwc_mdpcomp.cpp
@@ -2478,6 +2478,9 @@
         else if (hnd->format == HAL_PIXEL_FORMAT_RGBX_8888)
             whf.format = getMdpFormat(HAL_PIXEL_FORMAT_BGRX_8888);
     }
+    /* Calculate the external display position based on MDP downscale,
+       ActionSafe, and extorientation features. */
+    calcExtDisplayPosition(ctx, hnd, mDpy, crop, dst, transform, orient);
 
     int downscale = getRotDownscale(ctx, layer);
     eMdpFlags mdpFlags = OV_MDP_BACKEND_COMPOSITION;
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index e57e573..6c04965 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -636,6 +636,10 @@
                 displayFrame.top = int(hRatio*(float)displayFrame.top);
                 displayFrame.right = int(wRatio*(float)displayFrame.right);
                 displayFrame.bottom = int(hRatio*(float)displayFrame.bottom);
+                ALOGD_IF(DEBUG_MDPDOWNSCALE, "Calculated external display frame"
+                         " for MDPDownscale feature [%d %d %d %d]",
+                         displayFrame.left, displayFrame.top,
+                         displayFrame.right, displayFrame.bottom);
             }
         }else {
             if(extOrient || ctx->dpyAttr[dpy].mDownScaleMode) {
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 98e53a6..845897c 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -21,7 +21,9 @@
 #ifndef HWC_UTILS_H
 #define HWC_UTILS_H
 
+#define DEBUG_MDPDOWNSCALE 0
 #define HWC_REMOVE_DEPRECATED_VERSIONS 1
+
 #include <fcntl.h>
 #include <math.h>
 #include <hardware/hwcomposer.h>