sde: partial update implementation

  1. Partial update for non-split and split panels.
  2. Currently, partial update is enabled on qualified
     primary displays only.
Change-Id: I4d37e83e0991693cce950dc1428ed8c30d4f6caa
diff --git a/displayengine/include/private/strategy_interface.h b/displayengine/include/private/strategy_interface.h
index df01c7f..a0a52f8 100644
--- a/displayengine/include/private/strategy_interface.h
+++ b/displayengine/include/private/strategy_interface.h
@@ -96,7 +96,7 @@
   @return \link DisplayError \endlink
 */
 typedef DisplayError (*CreateStrategyInterface)(uint16_t version, DisplayType type,
-                      const HWResourceInfo *hw_resource_info, const HWPanelInfo *hw_panel_info,
+                      const HWResourceInfo &hw_resource_info, const HWPanelInfo &hw_panel_info,
                       StrategyInterface **interface);
 
 /*! @brief Function to destroy composer strategy interface.
diff --git a/displayengine/include/utils/debug.h b/displayengine/include/utils/debug.h
index 2cef5d7..1dbf0c3 100644
--- a/displayengine/include/utils/debug.h
+++ b/displayengine/include/utils/debug.h
@@ -65,7 +65,7 @@
   static uint32_t GetIdleTimeoutMs();
   static bool IsRotatorDownScaleDisabled();
   static bool IsDecimationDisabled();
-  static bool IsPartialUpdate();
+  static bool IsPartialUpdateEnabled();
 
  private:
   Debug();
diff --git a/displayengine/libs/core/comp_manager.cpp b/displayengine/libs/core/comp_manager.cpp
index 75d520f..fa02e94 100644
--- a/displayengine/libs/core/comp_manager.cpp
+++ b/displayengine/libs/core/comp_manager.cpp
@@ -107,7 +107,7 @@
     return kErrorMemory;
   }
 
-  if (create_strategy_intf_(STRATEGY_VERSION_TAG, type, &hw_res_info_, &hw_panel_info,
+  if (create_strategy_intf_(STRATEGY_VERSION_TAG, type, hw_res_info_, hw_panel_info,
                             &display_comp_ctx->strategy_intf) != kErrorNone) {
     DLOGW("Unable to create strategy interface");
     delete display_comp_ctx;
diff --git a/displayengine/libs/core/fb/hw_device.cpp b/displayengine/libs/core/fb/hw_device.cpp
index d96820f..809e817 100644
--- a/displayengine/libs/core/fb/hw_device.cpp
+++ b/displayengine/libs/core/fb/hw_device.cpp
@@ -194,7 +194,6 @@
   DTRACE_SCOPED();
 
   DisplayError error = kErrorNone;
-  ResetDisplayParams();
 
   HWLayersInfo &hw_layer_info = hw_layers->info;
   LayerStack *stack = hw_layer_info.stack;
@@ -206,6 +205,12 @@
   mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
   uint32_t &mdp_layer_count = mdp_commit.input_layer_cnt;
 
+  DLOGI("left_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.left_roi.x, mdp_commit.left_roi.y,
+                                                    mdp_commit.left_roi.w, mdp_commit.left_roi.h);
+  DLOGI("right_roi: x = %d, y = %d, w = %d, h = %d", mdp_commit.right_roi.x,
+                                                     mdp_commit.right_roi.y, mdp_commit.right_roi.w,
+                                                     mdp_commit.right_roi.h);
+
   for (uint32_t i = 0; i < hw_layer_info.count; i++) {
     uint32_t layer_index = hw_layer_info.index[i];
     Layer &layer = stack->layers[layer_index];
diff --git a/displayengine/libs/core/fb/hw_hdmi.cpp b/displayengine/libs/core/fb/hw_hdmi.cpp
index fec8661..f8279b2 100644
--- a/displayengine/libs/core/fb/hw_hdmi.cpp
+++ b/displayengine/libs/core/fb/hw_hdmi.cpp
@@ -326,6 +326,7 @@
 }
 
 DisplayError HWHDMI::Validate(HWLayers *hw_layers) {
+  HWDevice::ResetDisplayParams();
   return HWDevice::Validate(hw_layers);
 }
 
diff --git a/displayengine/libs/core/fb/hw_primary.cpp b/displayengine/libs/core/fb/hw_primary.cpp
index 6ff94b4..1fa4b4e 100644
--- a/displayengine/libs/core/fb/hw_primary.cpp
+++ b/displayengine/libs/core/fb/hw_primary.cpp
@@ -299,6 +299,27 @@
 }
 
 DisplayError HWPrimary::Validate(HWLayers *hw_layers) {
+  HWDevice::ResetDisplayParams();
+
+  mdp_layer_commit_v1 &mdp_commit = mdp_disp_commit_.commit_v1;
+
+  LayerRect left_roi = hw_layers->info.left_partial_update;
+  LayerRect right_roi = hw_layers->info.right_partial_update;
+  mdp_commit.left_roi.x = INT(left_roi.left);
+  mdp_commit.left_roi.y = INT(left_roi.top);
+  mdp_commit.left_roi.w = INT(left_roi.right - left_roi.left);
+  mdp_commit.left_roi.h = INT(left_roi.bottom - left_roi.top);
+
+  // SDE treats ROI as one full coordinate system.
+  // In case source split is disabled, However, Driver assumes Mixer to operate in
+  // different co-ordinate system.
+  if (!hw_resource_.is_src_split) {
+    mdp_commit.right_roi.x = INT(right_roi.left) - hw_panel_info_.split_info.left_split;
+    mdp_commit.right_roi.y = INT(right_roi.top);
+    mdp_commit.right_roi.w = INT(right_roi.right - right_roi.left);
+    mdp_commit.right_roi.h = INT(right_roi.bottom - right_roi.top);
+  }
+
   return HWDevice::Validate(hw_layers);
 }
 
@@ -402,7 +423,7 @@
     thermal_level = strtoull(data + strlen("thermal_level="), NULL, 0);
   }
 
-  DLOGI("Received thermal notification with thermal level = %d",thermal_level);
+  DLOGI("Received thermal notification with thermal level = %d", thermal_level);
 
   event_handler_->ThermalEvent(thermal_level);
 }
diff --git a/displayengine/libs/core/fb/hw_virtual.cpp b/displayengine/libs/core/fb/hw_virtual.cpp
index 374cc45..f108cfa 100644
--- a/displayengine/libs/core/fb/hw_virtual.cpp
+++ b/displayengine/libs/core/fb/hw_virtual.cpp
@@ -119,6 +119,7 @@
 }
 
 DisplayError HWVirtual::Validate(HWLayers *hw_layers) {
+  HWDevice::ResetDisplayParams();
   return HWDevice::Validate(hw_layers);
 }
 
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index c5a8a06..a8f9017 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -142,31 +142,39 @@
 DisplayError ResManager::DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
                                             const LayerTransform &transform,
                                             const LayerRect &src_rect, const LayerRect &dst_rect,
-                                            HWLayerConfig *layer_config, uint32_t align_x) {
+                                            const HWLayers &hw_layers, HWLayerConfig *layer_config,
+                                            uint32_t align_x) {
   LayerRect scissor_dst_left, scissor_dst_right;
   HWDisplayAttributes &display_attributes = display_resource_ctx->display_attributes;
 
   // for display split case
   HWPipeInfo *left_pipe = &layer_config->left_pipe;
   HWPipeInfo *right_pipe = &layer_config->right_pipe;
-  LayerRect scissor, dst_left, crop_left, crop_right, dst_right;
-  scissor.right = FLOAT(display_attributes.split_left);
-  scissor.bottom = FLOAT(display_attributes.y_pixels);
+  LayerRect scissor_left, scissor_right, dst_left, crop_left, crop_right, dst_right;
+
+  scissor_left.right = FLOAT(display_attributes.split_left);
+  scissor_left.bottom = FLOAT(display_attributes.y_pixels);
+
+  scissor_right.left = FLOAT(display_attributes.split_left);
+  scissor_right.top = 0.0f;
+  scissor_right.right = FLOAT(display_attributes.x_pixels);
+  scissor_right.bottom = FLOAT(display_attributes.y_pixels);
+
+  if (IsValid(hw_layers.info.left_partial_update) ||
+      IsValid(hw_layers.info.right_partial_update)) {
+    scissor_left = hw_layers.info.left_partial_update;
+    scissor_right = hw_layers.info.right_partial_update;
+  }
 
   crop_left = src_rect;
   dst_left = dst_rect;
   crop_right = crop_left;
   dst_right = dst_left;
-  bool crop_left_valid = CalculateCropRects(scissor, transform, &crop_left, &dst_left);
-
-  scissor.left = FLOAT(display_attributes.split_left);
-  scissor.top = 0.0f;
-  scissor.right = FLOAT(display_attributes.x_pixels);
-  scissor.bottom = FLOAT(display_attributes.y_pixels);
+  bool crop_left_valid = CalculateCropRects(scissor_left, transform, &crop_left, &dst_left);
   bool crop_right_valid = false;
 
-  if (IsValid(scissor)) {
-    crop_right_valid = CalculateCropRects(scissor, transform, &crop_right, &dst_right);
+  if (IsValid(scissor_right)) {
+    crop_right_valid = CalculateCropRects(scissor_right, transform, &crop_right, &dst_right);
   }
 
   if (crop_left_valid && (crop_left.right - crop_left.left) > hw_res_info_.max_pipe_width) {
@@ -248,6 +256,10 @@
     scissor.right = FLOAT(display_attributes.x_pixels);
     scissor.bottom = FLOAT(display_attributes.y_pixels);
 
+    if (IsValid(hw_layers->info.left_partial_update)) {
+      scissor = hw_layers->info.left_partial_update;
+    }
+
     struct HWLayerConfig *layer_config = &hw_layers->config[i];
     HWPipeInfo &left_pipe = layer_config->left_pipe;
     HWPipeInfo &right_pipe = layer_config->right_pipe;
@@ -295,19 +307,21 @@
       transform = LayerTransform();
     }
 
+    // TODO(user): need to revisit this logic
     if (hw_res_info_.is_src_split) {
-      error = SrcSplitConfig(display_resource_ctx, transform, src_rect,
-                             dst_rect, layer_config, align_x);
+      error = SrcSplitConfig(display_resource_ctx, transform, src_rect, dst_rect, layer_config,
+                             align_x);
     } else {
-      error = DisplaySplitConfig(display_resource_ctx, transform, src_rect,
-                                 dst_rect, layer_config, align_x);
+      error = DisplaySplitConfig(display_resource_ctx, transform, src_rect, dst_rect, *hw_layers,
+                                 layer_config, align_x);
     }
 
     if (error != kErrorNone) {
       break;
     }
 
-    error = AlignPipeConfig(layer, transform, &left_pipe, &right_pipe, align_x, align_y);
+    error = AlignPipeConfig(layer, transform, *hw_layers, &left_pipe, &right_pipe, align_x,
+                            align_y);
     if (error != kErrorNone) {
       break;
     }
@@ -742,8 +756,9 @@
 }
 
 DisplayError ResManager::AlignPipeConfig(const Layer &layer, const LayerTransform &transform,
-                                         HWPipeInfo *left_pipe, HWPipeInfo *right_pipe,
-                                         uint32_t align_x, uint32_t align_y) {
+                                         const HWLayers &hw_layers, HWPipeInfo *left_pipe,
+                                         HWPipeInfo *right_pipe, uint32_t align_x,
+                                         uint32_t align_y) {
   DisplayError error = kErrorNone;
   if (!left_pipe->valid) {
     DLOGE_IF(kTagResources, "left_pipe should not be invalid");
@@ -753,7 +768,6 @@
   //    rectangle of video layer to be even.
   // 2. Normalize source and destination rect of a layer to multiple of 1.
   // TODO(user) Check buffer format and check if rotate is involved.
-
   Normalize(align_x, align_y, &left_pipe->src_roi);
   Normalize(1, 1, &left_pipe->dst_roi);
 
@@ -762,8 +776,10 @@
     Normalize(1, 1, &right_pipe->dst_roi);
   }
 
-  if (right_pipe->valid) {
-    // Make sure the  left and right ROI are conjunct
+  // Make sure the  left and right ROI are conjunct, then make pipes ROI conjunct.
+  if (right_pipe->valid &&
+      (!IsValid(hw_layers.info.right_partial_update) ||
+      (hw_layers.info.left_partial_update.right == hw_layers.info.right_partial_update.left))) {
     if (transform.flip_horizontal) {
       left_pipe->src_roi.left = right_pipe->src_roi.right;
     } else {
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index d9c6c8b..1f8f48e 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -164,9 +164,12 @@
   DisplayError Config(DisplayResourceContext *display_resource_ctx, HWLayers *hw_layers,
                       uint32_t *rotate_count);
   DisplayError DisplaySplitConfig(DisplayResourceContext *display_resource_ctx,
-                                  const LayerTransform &transform, const LayerRect &src_rect,
-                                  const LayerRect &dst_rect, HWLayerConfig *layer_config,
+                                  const LayerTransform &transform,
+                                  const LayerRect &src_rect, const LayerRect &dst_rect,
+                                  const HWLayers &hw_layers, HWLayerConfig *layer_config,
                                   uint32_t align_x);
+  DisplayError ValidateScaling(const Layer &layer, const LayerRect &crop,
+                               const LayerRect &dst, float *rot_scale);
   DisplayError SrcSplitConfig(DisplayResourceContext *display_resource_ctx,
                               const LayerTransform &transform, const LayerRect &src_rect,
                               const LayerRect &dst_rect, HWLayerConfig *layer_config,
@@ -210,8 +213,8 @@
                               const bool &rot90, const bool &downscale,
                               LayerBufferFormat *output_format);
   DisplayError AlignPipeConfig(const Layer &layer, const LayerTransform &transform,
-                               HWPipeInfo *left_pipe, HWPipeInfo *right_pipe,
-                               uint32_t align_x, uint32_t align_y);
+                               const HWLayers &hw_layers, HWPipeInfo *left_pipe,
+                               HWPipeInfo *right_pipe, uint32_t align_x, uint32_t align_y);
   void ResourceStateLog(void);
   DisplayError CalculateDecimation(float downscale, uint8_t *decimation);
 
diff --git a/displayengine/libs/core/strategy_default.cpp b/displayengine/libs/core/strategy_default.cpp
index 48fc79d..4aab34d 100644
--- a/displayengine/libs/core/strategy_default.cpp
+++ b/displayengine/libs/core/strategy_default.cpp
@@ -31,14 +31,17 @@
 
 namespace sde {
 
-StrategyDefault::StrategyDefault() : hw_layers_info_(NULL) {
+StrategyDefault::StrategyDefault(DisplayType type, const HWResourceInfo &hw_resource_info,
+                                 const HWPanelInfo &hw_panel_info) : type_(type),
+                                 hw_resource_info_(hw_resource_info),
+                                 hw_panel_info_(hw_panel_info), hw_layers_info_(NULL) {
 }
 
 DisplayError StrategyDefault::CreateStrategyInterface(uint16_t version, DisplayType type,
-                                                      const HWResourceInfo *hw_resource_info,
-                                                      const HWPanelInfo *hw_panel_info,
+                                                      const HWResourceInfo &hw_resource_info,
+                                                      const HWPanelInfo &hw_panel_info,
                                                       StrategyInterface **interface) {
-  StrategyDefault *strategy_default  = new StrategyDefault();
+  StrategyDefault *strategy_default  = new StrategyDefault(type, hw_resource_info, hw_panel_info);
 
   if (!strategy_default) {
     return kErrorMemory;
@@ -61,6 +64,18 @@
   return kErrorNone;
 }
 
+bool StrategyDefault::IsDisplaySplit(uint32_t fb_x_res) {
+  if (fb_x_res > hw_resource_info_.max_mixer_width) {
+    return true;
+  }
+
+  if ((type_ == kPrimary) && hw_panel_info_.split_info.right_split) {
+    return true;
+  }
+
+  return false;
+}
+
 DisplayError StrategyDefault::Start(HWLayersInfo *hw_layers_info, uint32_t *max_attempts) {
   if (!hw_layers_info) {
     return kErrorParameters;
@@ -69,6 +84,29 @@
   hw_layers_info_ = hw_layers_info;
   *max_attempts = 1;
 
+  const LayerStack *layer_stack = hw_layers_info_->stack;
+  for (uint32_t i = 0; i < layer_stack->layer_count; i++) {
+    LayerComposition &composition = layer_stack->layers[i].composition;
+    if (composition == kCompositionGPUTarget) {
+      fb_layer_index_ = i;
+      break;
+    }
+  }
+
+  const LayerRect &src_rect = hw_layers_info_->stack->layers[fb_layer_index_].src_rect;
+  // TODO(user): read panels x_pixels and y_pixels instead of fb_x_res and fb_y_res
+  const float fb_x_res = src_rect.right - src_rect.left;
+  const float fb_y_res = src_rect.bottom - src_rect.top;
+
+  if (IsDisplaySplit(INT(fb_x_res))) {
+    float left_split = FLOAT(hw_panel_info_.split_info.left_split);
+    hw_layers_info->left_partial_update = (LayerRect) {0.0, 0.0, left_split, fb_y_res};
+    hw_layers_info->right_partial_update = (LayerRect) {left_split, 0.0, fb_x_res, fb_y_res};
+  } else {
+    hw_layers_info->left_partial_update = (LayerRect) {0.0, 0.0, fb_x_res, fb_y_res};
+    hw_layers_info->right_partial_update = (LayerRect) {0.0, 0.0, 0.0, 0.0};
+  }
+
   return kErrorNone;
 }
 
diff --git a/displayengine/libs/core/strategy_default.h b/displayengine/libs/core/strategy_default.h
index 7b6f594..37d5f9d 100644
--- a/displayengine/libs/core/strategy_default.h
+++ b/displayengine/libs/core/strategy_default.h
@@ -32,11 +32,11 @@
 
 class StrategyDefault : public StrategyInterface {
  public:
-  StrategyDefault();
-
+  StrategyDefault(DisplayType type, const HWResourceInfo &hw_resource_info,
+                  const HWPanelInfo &hw_panel_info);
   static DisplayError CreateStrategyInterface(uint16_t version, DisplayType type,
-                                              const HWResourceInfo *hw_resource_info,
-                                              const HWPanelInfo *hw_panel_info,
+                                              const HWResourceInfo &hw_resource_info,
+                                              const HWPanelInfo &hw_panel_info,
                                               StrategyInterface **interface);
   static DisplayError DestroyStrategyInterface(StrategyInterface *interface);
 
@@ -45,7 +45,12 @@
   virtual DisplayError Stop();
 
  private:
+  bool IsDisplaySplit(uint32_t fb_x_res);
+  DisplayType type_;
+  HWResourceInfo hw_resource_info_;
+  HWPanelInfo hw_panel_info_;
   HWLayersInfo *hw_layers_info_;
+  int fb_layer_index_;
 };
 
 }  // namespace sde
diff --git a/displayengine/libs/utils/debug_android.cpp b/displayengine/libs/utils/debug_android.cpp
index 77c82b0..779c441 100644
--- a/displayengine/libs/utils/debug_android.cpp
+++ b/displayengine/libs/utils/debug_android.cpp
@@ -90,7 +90,7 @@
 }
 
 // This property serves to disable/enable partial update
-bool Debug::IsPartialUpdate() {
+bool Debug::IsPartialUpdateEnabled() {
   char property[PROPERTY_VALUE_MAX];
   if (property_get("sde.hwc.partial_update", property, NULL) > 0) {
     return (atoi(property) ? 1 : true, false);
diff --git a/displayengine/libs/utils/rect.cpp b/displayengine/libs/utils/rect.cpp
index 9b05951..630cebb 100644
--- a/displayengine/libs/utils/rect.cpp
+++ b/displayengine/libs/utils/rect.cpp
@@ -122,11 +122,11 @@
     return LayerRect();
   }
 
-  if(!IsValid(rect1)){
+  if (!IsValid(rect1)) {
     return rect2;
   }
 
-  if(!IsValid(rect2)){
+  if (!IsValid(rect2)) {
     return rect1;
   }