HWC: Update DisplayFrame of all layers properly in Dynamic FB

Use change in HWC_GEOMETRY_CHANGED flag appropriately to avoid
redundant and unintentional overwrites of DisplayFrame values,
which may result fall back to GPU.

Change-Id: Ifb0f8dc5d356c965b6e80644f32392c460fb1ae7
diff --git a/libhwcomposer/hwc.cpp b/libhwcomposer/hwc.cpp
index f4baa25..f176d79 100644
--- a/libhwcomposer/hwc.cpp
+++ b/libhwcomposer/hwc.cpp
@@ -226,31 +226,20 @@
         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) {
-    uint32_t origXres = ctx->dpyAttr[dpy].xres_orig;
-    uint32_t origYres = ctx->dpyAttr[dpy].yres_orig;
-    uint32_t fakeXres = ctx->dpyAttr[dpy].xres;
-    uint32_t fakeYres = ctx->dpyAttr[dpy].yres;
-    float xresRatio = (float)origXres / (float)fakeXres;
-    float yresRatio = (float)origYres / (float)fakeYres;
+    uint32_t origXres = ctx->dpyAttr[dpy].xres;
+    uint32_t origYres = ctx->dpyAttr[dpy].yres;
+    uint32_t newXres = ctx->dpyAttr[dpy].xres_new;
+    uint32_t newYres = ctx->dpyAttr[dpy].yres_new;
+    float xresRatio = (float)origXres / (float)newXres;
+    float yresRatio = (float)origYres / (float)newYres;
     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);
         uint32_t layerWidth = displayFrame.right - displayFrame.left;
         uint32_t layerHeight = displayFrame.bottom - displayFrame.top;
-        uint32_t sourceWidth = sourceCrop.right - sourceCrop.left;
-        uint32_t sourceHeight = sourceCrop.bottom - sourceCrop.top;
-
-        if (isEqual(((float)layerWidth / (float)sourceWidth), xresRatio) &&
-                isEqual(((float)layerHeight / (float)sourceHeight), yresRatio))
-            break;
-
         displayFrame.left = (int)(xresRatio * (float)displayFrame.left);
         displayFrame.top = (int)(yresRatio * (float)displayFrame.top);
         displayFrame.right = (int)((float)displayFrame.left +
@@ -311,7 +300,8 @@
     if (LIKELY(list && list->numHwLayers > 1) &&
             ctx->dpyAttr[dpy].isActive) {
 
-        if (ctx->dpyAttr[dpy].customFBSize)
+        if (ctx->dpyAttr[dpy].customFBSize &&
+                list->flags & HWC_GEOMETRY_CHANGED)
             scaleDisplayFrame(ctx, dpy, list);
 
         reset_layer_prop(ctx, dpy, (int)list->numHwLayers - 1);
@@ -824,14 +814,21 @@
             values[i] = ctx->dpyAttr[disp].vsync_period;
             break;
         case HWC_DISPLAY_WIDTH:
-            values[i] = ctx->dpyAttr[disp].xres;
+            if (ctx->dpyAttr[disp].customFBSize)
+                values[i] = ctx->dpyAttr[disp].xres_new;
+            else
+                values[i] = ctx->dpyAttr[disp].xres;
+
             ALOGD("%s disp = %d, width = %d",__FUNCTION__, disp,
-                    ctx->dpyAttr[disp].xres);
+                    values[i]);
             break;
         case HWC_DISPLAY_HEIGHT:
-            values[i] = ctx->dpyAttr[disp].yres;
+            if (ctx->dpyAttr[disp].customFBSize)
+                values[i] = ctx->dpyAttr[disp].yres_new;
+            else
+                values[i] = ctx->dpyAttr[disp].yres;
             ALOGD("%s disp = %d, height = %d",__FUNCTION__, disp,
-                    ctx->dpyAttr[disp].yres);
+                    values[i]);
             break;
         case HWC_DISPLAY_DPI_X:
             values[i] = (int32_t) (ctx->dpyAttr[disp].xdpi*1000.0);
diff --git a/libhwcomposer/hwc_fbupdate.cpp b/libhwcomposer/hwc_fbupdate.cpp
index c733523..fb0a613 100644
--- a/libhwcomposer/hwc_fbupdate.cpp
+++ b/libhwcomposer/hwc_fbupdate.cpp
@@ -49,8 +49,15 @@
 
 IFBUpdate::IFBUpdate(hwc_context_t *ctx, const int& dpy) : mDpy(dpy) {
     size_t size = 0;
-    getBufferAttributes(ctx->dpyAttr[mDpy].xres,
-            ctx->dpyAttr[mDpy].yres,
+    uint32_t xres = ctx->dpyAttr[mDpy].xres;
+    uint32_t yres = ctx->dpyAttr[mDpy].yres;
+    if (ctx->dpyAttr[dpy].customFBSize) {
+        //GPU will render and compose at new resolution
+        //So need to have FB at new resolution
+        xres = ctx->dpyAttr[mDpy].xres_new;
+        yres = ctx->dpyAttr[mDpy].yres_new;
+    }
+    getBufferAttributes((int)xres, (int)yres,
             HAL_PIXEL_FORMAT_RGBA_8888,
             0,
             mAlignedFBWidth,
diff --git a/libhwcomposer/hwc_qclient.cpp b/libhwcomposer/hwc_qclient.cpp
index 976b23d..0bb71f0 100644
--- a/libhwcomposer/hwc_qclient.cpp
+++ b/libhwcomposer/hwc_qclient.cpp
@@ -108,8 +108,13 @@
         Parcel* outParcel) {
     int dpy = inParcel->readInt32();
     outParcel->writeInt32(ctx->dpyAttr[dpy].vsync_period);
-    outParcel->writeInt32(ctx->dpyAttr[dpy].xres);
-    outParcel->writeInt32(ctx->dpyAttr[dpy].yres);
+    if (ctx->dpyAttr[dpy].customFBSize) {
+        outParcel->writeInt32(ctx->dpyAttr[dpy].xres_new);
+        outParcel->writeInt32(ctx->dpyAttr[dpy].yres_new);
+    } else {
+        outParcel->writeInt32(ctx->dpyAttr[dpy].xres);
+        outParcel->writeInt32(ctx->dpyAttr[dpy].yres);
+    }
     outParcel->writeFloat(ctx->dpyAttr[dpy].xdpi);
     outParcel->writeFloat(ctx->dpyAttr[dpy].ydpi);
     //XXX: Need to check what to return for HDMI
diff --git a/libhwcomposer/hwc_utils.cpp b/libhwcomposer/hwc_utils.cpp
index 7499ba5..60a853a 100644
--- a/libhwcomposer/hwc_utils.cpp
+++ b/libhwcomposer/hwc_utils.cpp
@@ -85,20 +85,19 @@
 
 void changeResolution(hwc_context_t *ctx, int xres_orig, int yres_orig) {
     //Store original display resolution.
-    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_orig = xres_orig;
-    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_orig = yres_orig;
+    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_orig;
+    ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_orig;
     ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = false;
-
     char property[PROPERTY_VALUE_MAX] = {'\0'};
     char *yptr = NULL;
     if (property_get("debug.hwc.fbsize", property, NULL) > 0) {
         yptr = strcasestr(property,"x");
-        int xres = atoi(property);
-        int yres = atoi(yptr + 1);
-        if (isValidResolution(ctx,xres,yres) &&
-                 xres != xres_orig && yres != yres_orig) {
-            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres = xres;
-            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres = yres;
+        int xres_new = atoi(property);
+        int yres_new = atoi(yptr + 1);
+        if (isValidResolution(ctx,xres_new,yres_new) &&
+                 xres_new != xres_orig && yres_new != yres_orig) {
+            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].xres_new = xres_new;
+            ctx->dpyAttr[HWC_DISPLAY_PRIMARY].yres_new = yres_new;
             ctx->dpyAttr[HWC_DISPLAY_PRIMARY].customFBSize = true;
         }
     }
diff --git a/libhwcomposer/hwc_utils.h b/libhwcomposer/hwc_utils.h
index 6f527aa..0883a51 100644
--- a/libhwcomposer/hwc_utils.h
+++ b/libhwcomposer/hwc_utils.h
@@ -104,8 +104,8 @@
     //If property fbsize set via adb shell debug.hwc.fbsize = XRESxYRES
     //following fields are used.
     bool customFBSize;
-    uint32_t xres_orig;
-    uint32_t yres_orig;
+    uint32_t xres_new;
+    uint32_t yres_new;
 
 };