sdm: Update layer parameters based on panel orientation

Update layer rotation parameters with panel orientation.
Recalculate destination rect for all layers.

CRs-fixed: 1112326
Change-Id: I95f6428c77b23cf2437c319f6ab519aa3ad245e9
diff --git a/sdm/libs/core/display_primary.cpp b/sdm/libs/core/display_primary.cpp
index 9f6c917..99aa3d5 100644
--- a/sdm/libs/core/display_primary.cpp
+++ b/sdm/libs/core/display_primary.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted
 * provided that the following conditions are met:
@@ -88,6 +88,29 @@
   uint32_t new_mixer_height = 0;
   uint32_t display_width = display_attributes_.x_pixels;
   uint32_t display_height = display_attributes_.y_pixels;
+  bool needs_hv_flip = hw_panel_info_.panel_orientation.flip_horizontal &&
+                          hw_panel_info_.panel_orientation.flip_vertical;
+  LayerRect src_domain = {};
+  DisplayConfigVariableInfo variable_info = {};
+
+  if (needs_hv_flip) {
+    DisplayBase::GetFrameBufferConfig(&variable_info);
+    src_domain.right = variable_info.x_pixels;
+    src_domain.bottom = variable_info.y_pixels;
+
+    for (Layer *layer : layer_stack->layers) {
+      // Modify destination based on panel flip
+      TransformHV(src_domain, layer->dst_rect, &layer->dst_rect);
+
+      if (layer->flags.solid_fill) {
+        continue;
+      }
+
+      layer->transform.flip_horizontal ^= (hw_panel_info_.panel_orientation.flip_horizontal);
+      layer->transform.flip_vertical ^= (hw_panel_info_.panel_orientation.flip_vertical);
+     // TODO(user): Check how to handle rotation, if panel has rotation.
+    }
+  }
 
   if (NeedsMixerReconfiguration(layer_stack, &new_mixer_width, &new_mixer_height)) {
     error = ReconfigureMixer(new_mixer_width, new_mixer_height);
diff --git a/sdm/libs/core/fb/hw_device.cpp b/sdm/libs/core/fb/hw_device.cpp
index 111e386..dab6dab 100644
--- a/sdm/libs/core/fb/hw_device.cpp
+++ b/sdm/libs/core/fb/hw_device.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2014 - 2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2014 - 2017, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -899,6 +899,11 @@
         panel_info->primaries.blue[0] = UINT32(atoi(tokens[1]));
       } else if (!strncmp(tokens[0], "blue_chromaticity_y", strlen("blue_chromaticity_y"))) {
         panel_info->primaries.blue[1] = UINT32(atoi(tokens[1]));
+      } else if (!strncmp(tokens[0], "panel_orientation", strlen("panel_orientation"))) {
+        int32_t panel_orient = atoi(tokens[1]);
+        panel_info->panel_orientation.flip_horizontal = ((panel_orient & MDP_FLIP_LR) > 0);
+        panel_info->panel_orientation.flip_vertical = ((panel_orient & MDP_FLIP_UD) > 0);
+        panel_info->panel_orientation.rotation = ((panel_orient & MDP_ROT_90) > 0);
       }
     }
   }
diff --git a/sdm/libs/utils/rect.cpp b/sdm/libs/utils/rect.cpp
index fc553a3..dd5a872 100644
--- a/sdm/libs/utils/rect.cpp
+++ b/sdm/libs/utils/rect.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
@@ -223,6 +223,20 @@
   out_rect->bottom = dst_domain.top + (height_ratio * modified_in_rect.bottom);
 }
 
+void TransformHV(const LayerRect &src_domain, const LayerRect &in_rect, LayerRect *out_rect) {
+  if (!IsValid(src_domain) || !IsValid(in_rect)) {
+    return;
+  }
+
+  float in_width = in_rect.right - in_rect.left;
+  float in_height = in_rect.bottom - in_rect.top;
+
+  out_rect->right = src_domain.right - in_rect.left;
+  out_rect->bottom = src_domain.bottom - in_rect.top;
+  out_rect->left = out_rect->right - in_width;
+  out_rect->top = out_rect->bottom - in_height;
+}
+
 RectOrientation GetOrientation(const LayerRect &in_rect) {
   if (!IsValid(in_rect)) {
     return kOrientationUnknown;