hwc: Dynamic Resolution support on Primary

    * Useful to estimate GPU/MDP performance for different resolutions.
    * MDP:
      Every layer is downscaled/upscaled to primary panel resolution.
    * GPU:
      All layers will be composed in required resolution to FB.
      FB is downscaled/upscaled to primary panel resolution.
    * Steps to follow:
          step 1: adb root
          step 2: adb shell setprop debug.hwc.fbsize XRESxYRES
          step 3: adb shell stop
          step 4: adb shell start

Change-Id: I82a032df87c91549c49a9cdbd981ff02f105ff2e
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index dcad00b..8048f32 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2014, The Linux Foundation. All rights reserved.
  *
  * Not a Contribution, Apache license notifications and license are retained
  * for attribution purposes only.
@@ -132,6 +132,38 @@
         ctx->mHWCVirtual->destroy(ctx, numDisplays, displays);
 }
 
+bool isEqual(float f1, float f2) {
+        return ((int)(f1*100) == (int)(f2*100)) ? true : false;
+}
+
+static void scaleDisplayFrame(hwc_context_t *ctx, int dpy,
+                            hwc_display_contents_1_t *list) {
+    float origXres = ctx->dpyAttr[dpy].xres_orig;
+    float origYres = ctx->dpyAttr[dpy].yres_orig;
+    float fakeXres = ctx->dpyAttr[dpy].xres;
+    float fakeYres = ctx->dpyAttr[dpy].yres;
+    float xresRatio = origXres / fakeXres;
+    float yresRatio = origYres / fakeYres;
+    for (size_t i = 0; i < list->numHwLayers; i++) {
+        hwc_layer_1_t *layer = &list->hwLayers[i];
+        hwc_rect_t& displayFrame = layer->displayFrame;
+        hwc_rect_t sourceCrop = integerizeSourceCrop(layer->sourceCropf);
+        float layerWidth = displayFrame.right - displayFrame.left;
+        float layerHeight = displayFrame.bottom - displayFrame.top;
+        float sourceWidth = sourceCrop.right - sourceCrop.left;
+        float sourceHeight = sourceCrop.bottom - sourceCrop.top;
+
+        if (isEqual(layerWidth / sourceWidth, xresRatio) &&
+                isEqual(layerHeight / sourceHeight, yresRatio))
+            break;
+
+        displayFrame.left = xresRatio * displayFrame.left;
+        displayFrame.top = yresRatio * displayFrame.top;
+        displayFrame.right = displayFrame.left + layerWidth * xresRatio;
+        displayFrame.bottom = displayFrame.top + layerHeight * yresRatio;
+    }
+}
+
 static int hwc_prepare_primary(hwc_composer_device_1 *dev,
         hwc_display_contents_1_t *list) {
     ATRACE_CALL();
@@ -139,6 +171,10 @@
     const int dpy = HWC_DISPLAY_PRIMARY;
     if (LIKELY(list && list->numHwLayers > 1) &&
             ctx->dpyAttr[dpy].isActive) {
+
+        if (ctx->dpyAttr[dpy].customFBSize)
+            scaleDisplayFrame(ctx, dpy, list);
+
         reset_layer_prop(ctx, dpy, list->numHwLayers - 1);
         setListStats(ctx, list, dpy);
 #ifdef VPU_TARGET