sde: Add interface for Partial Update feature

Composition Manager propagates HWResourceInfo, HWPanelInfo information
to Strategy Interface. Strategy Interface implementation uses this
information to determine partial update is qualified for a given display.

Change-Id: I48bd209c4c4386f7a6afdce38b754833f9c100e6
diff --git a/displayengine/libs/core/comp_manager.cpp b/displayengine/libs/core/comp_manager.cpp
index 27d1052..4e101a3 100644
--- a/displayengine/libs/core/comp_manager.cpp
+++ b/displayengine/libs/core/comp_manager.cpp
@@ -80,6 +80,8 @@
     destroy_strategy_intf_ = StrategyDefault::DestroyStrategyInterface;
   }
 
+  hw_res_info_ = hw_res_info;
+
   return error;
 }
 
@@ -96,7 +98,7 @@
 }
 
 DisplayError CompManager::RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
-                                          Handle *display_ctx) {
+                                          const HWPanelInfo &hw_panel_info, Handle *display_ctx) {
   SCOPE_LOCK(locker_);
 
   DisplayError error = kErrorNone;
@@ -106,7 +108,7 @@
     return kErrorMemory;
   }
 
-  if (create_strategy_intf_(STRATEGY_VERSION_TAG, type,
+  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;
@@ -114,7 +116,8 @@
     return kErrorUndefined;
   }
 
-  error = res_mgr_.RegisterDisplay(type, attributes, &display_comp_ctx->display_resource_ctx);
+  error = res_mgr_.RegisterDisplay(type, attributes, hw_panel_info,
+                                   &display_comp_ctx->display_resource_ctx);
   if (error != kErrorNone) {
     destroy_strategy_intf_(display_comp_ctx->strategy_intf);
     delete display_comp_ctx;
diff --git a/displayengine/libs/core/comp_manager.h b/displayengine/libs/core/comp_manager.h
index 0a21ee0..06871f1 100644
--- a/displayengine/libs/core/comp_manager.h
+++ b/displayengine/libs/core/comp_manager.h
@@ -40,7 +40,7 @@
                     BufferSyncHandler *buffer_sync_handler_);
   DisplayError Deinit();
   DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
-                               Handle *res_mgr_hnd);
+                               const HWPanelInfo &hw_panel_info, Handle *res_mgr_hnd);
   DisplayError UnregisterDisplay(Handle res_mgr_hnd);
   void PrePrepare(Handle display_ctx, HWLayers *hw_layers);
   DisplayError Prepare(Handle display_ctx, HWLayers *hw_layers);
@@ -81,6 +81,7 @@
   bool safe_mode_;                      // Flag to notify all displays to be in resource crunch
                                         // mode, where strategy manager chooses the best strategy
                                         // that uses optimal number of pipes for each display
+  HWResourceInfo hw_res_info_;
 };
 
 }  // namespace sde
diff --git a/displayengine/libs/core/display_base.cpp b/displayengine/libs/core/display_base.cpp
index e58b4f8..a70a7c9 100644
--- a/displayengine/libs/core/display_base.cpp
+++ b/displayengine/libs/core/display_base.cpp
@@ -74,7 +74,7 @@
   }
 
   error = comp_manager_->RegisterDisplay(display_type_, display_attributes_[active_mode_index_],
-                                        &display_comp_ctx_);
+                                         hw_panel_info_, &display_comp_ctx_);
   if (error != kErrorNone) {
     goto CleanupOnError;
   }
@@ -327,7 +327,8 @@
     comp_manager_->UnregisterDisplay(display_comp_ctx_);
   }
 
-  error = comp_manager_->RegisterDisplay(display_type_, display_attributes, &display_comp_ctx_);
+  error = comp_manager_->RegisterDisplay(display_type_, display_attributes, hw_panel_info_,
+                                         &display_comp_ctx_);
   if (error != kErrorNone) {
     return error;
   }
@@ -355,7 +356,7 @@
     comp_manager_->UnregisterDisplay(display_comp_ctx_);
   }
 
-  error = comp_manager_->RegisterDisplay(display_type_, display_attributes_[index],
+  error = comp_manager_->RegisterDisplay(display_type_, display_attributes_[index], hw_panel_info_,
                                          &display_comp_ctx_);
 
   return error;
diff --git a/displayengine/libs/core/res_config.cpp b/displayengine/libs/core/res_config.cpp
index 4624a35..ecd8ef1 100644
--- a/displayengine/libs/core/res_config.cpp
+++ b/displayengine/libs/core/res_config.cpp
@@ -168,7 +168,7 @@
   scissor.bottom = FLOAT(display_attributes.y_pixels);
   bool crop_right_valid = false;
 
-  if (IsValidRect(scissor)) {
+  if (IsValid(scissor)) {
     crop_right_valid = CalculateCropRects(scissor, transform, &crop_right, &dst_right);
   }
 
@@ -240,8 +240,8 @@
     float rot_scale = 1.0f;
     if (!IsValidDimension(layer.src_rect, layer.dst_rect)) {
       DLOGV_IF(kTagResources, "Input is invalid");
-      LogRect(kTagResources, "input layer src_rect", layer.src_rect);
-      LogRect(kTagResources, "input layer dst_rect", layer.dst_rect);
+      Log(kTagResources, "input layer src_rect", layer.src_rect);
+      Log(kTagResources, "input layer dst_rect", layer.dst_rect);
       return kErrorNotSupported;
     }
 
@@ -265,7 +265,7 @@
     uint32_t align_x, align_y;
     GetAlignFactor(layer.input_buffer->format, &align_x, &align_y);
     if (align_x > 1 || align_y > 1) {
-      NormalizeRect(align_x, align_y, &src_rect);
+      Normalize(align_x, align_y, &src_rect);
     }
 
     if (ValidateScaling(layer, src_rect, dst_rect, &rot_scale)) {
@@ -304,21 +304,21 @@
 
     DLOGV_IF(kTagResources, "==== layer = %d, left pipe valid = %d ====",
              i, layer_config->left_pipe.valid);
-    LogRect(kTagResources, "input layer src_rect", layer.src_rect);
-    LogRect(kTagResources, "input layer dst_rect", layer.dst_rect);
+    Log(kTagResources, "input layer src_rect", layer.src_rect);
+    Log(kTagResources, "input layer dst_rect", layer.dst_rect);
     for (uint32_t k = 0; k < layer_config->num_rotate; k++) {
       DLOGV_IF(kTagResources, "rotate num = %d, scale_x = %.2f", k, rot_scale);
-      LogRect(kTagResources, "rotate src", layer_config->rotates[k].src_roi);
-      LogRect(kTagResources, "rotate dst", layer_config->rotates[k].dst_roi);
+      Log(kTagResources, "rotate src", layer_config->rotates[k].src_roi);
+      Log(kTagResources, "rotate dst", layer_config->rotates[k].dst_roi);
     }
 
-    LogRect(kTagResources, "cropped src_rect", src_rect);
-    LogRect(kTagResources, "cropped dst_rect", dst_rect);
-    LogRect(kTagResources, "left pipe src", layer_config->left_pipe.src_roi);
-    LogRect(kTagResources, "left pipe dst", layer_config->left_pipe.dst_roi);
+    Log(kTagResources, "cropped src_rect", src_rect);
+    Log(kTagResources, "cropped dst_rect", dst_rect);
+    Log(kTagResources, "left pipe src", layer_config->left_pipe.src_roi);
+    Log(kTagResources, "left pipe dst", layer_config->left_pipe.dst_roi);
     if (hw_layers->config[i].right_pipe.valid) {
-      LogRect(kTagResources, "right pipe src", layer_config->right_pipe.src_roi);
-      LogRect(kTagResources, "right pipe dst", layer_config->right_pipe.dst_roi);
+      Log(kTagResources, "right pipe src", layer_config->right_pipe.src_roi);
+      Log(kTagResources, "right pipe dst", layer_config->right_pipe.dst_roi);
     }
     // set z_order, left_pipe should always be valid
     left_pipe.z_order = z_order;
@@ -507,9 +507,9 @@
   crop_top += crop_height * top_cut_ratio;
   crop_right -= crop_width * right_cut_ratio;
   crop_bottom -= crop_height * bottom_cut_ratio;
-  NormalizeRect(1, 1, crop);
-  NormalizeRect(1, 1, dst);
-  if (IsValidRect(*crop) && IsValidRect(*dst))
+  Normalize(1, 1, crop);
+  Normalize(1, 1, dst);
+  if (IsValid(*crop) && IsValid(*dst))
     return true;
   else
     return false;
@@ -612,12 +612,12 @@
   // 2. Normalize source and destination rect of a layer to multiple of 1.
   // TODO(user) Check buffer format and check if rotate is involved.
 
-  NormalizeRect(align_x, align_y, &left_pipe->src_roi);
-  NormalizeRect(1, 1, &left_pipe->dst_roi);
+  Normalize(align_x, align_y, &left_pipe->src_roi);
+  Normalize(1, 1, &left_pipe->dst_roi);
 
   if (right_pipe->valid) {
-    NormalizeRect(align_x, align_y, &right_pipe->src_roi);
-    NormalizeRect(1, 1, &right_pipe->dst_roi);
+    Normalize(align_x, align_y, &right_pipe->src_roi);
+    Normalize(1, 1, &right_pipe->dst_roi);
   }
 
   if (right_pipe->valid) {
diff --git a/displayengine/libs/core/res_manager.cpp b/displayengine/libs/core/res_manager.cpp
index c6f9f64..1499bb9 100644
--- a/displayengine/libs/core/res_manager.cpp
+++ b/displayengine/libs/core/res_manager.cpp
@@ -133,7 +133,7 @@
 }
 
 DisplayError ResManager::RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
-                                         Handle *display_ctx) {
+                                         const HWPanelInfo &hw_panel_info, Handle *display_ctx) {
   DisplayError error = kErrorNone;
 
   HWBlockType hw_block_id = kHWBlockMax;
@@ -170,6 +170,7 @@
     return kErrorMemory;
   }
 
+  display_resource_ctx->hw_panel_info_ = hw_panel_info;
   display_resource_ctx->buffer_manager = new BufferManager(buffer_allocator_, buffer_sync_handler_);
   if (display_resource_ctx->buffer_manager == NULL) {
     delete display_resource_ctx;
@@ -1119,7 +1120,7 @@
   // Initialize the output format with input format by default.
   *output_format = input_format;
 
-  switch(input_format) {
+  switch (input_format) {
   case kFormatARGB8888:
   case kFormatRGBA8888:
     if (is_opaque) {
@@ -1181,8 +1182,9 @@
     }
   }
 
-  DLOGV_IF(kTagResources, "Input format %x, Output format = %x, rot90 %d ubwc %d downscale %d",
-           input_format, *output_format, rot90, hw_res_info_.has_ubwc, downscale);
+  DLOGV_IF(kTagResources, "Input format = %x, Output format = %x, rot90 = %d, ubwc = %d,"
+           "downscale = %d", input_format, *output_format, rot90, hw_res_info_.has_ubwc,
+           downscale);
 
   return;
 }
diff --git a/displayengine/libs/core/res_manager.h b/displayengine/libs/core/res_manager.h
index c293453..99ac874 100644
--- a/displayengine/libs/core/res_manager.h
+++ b/displayengine/libs/core/res_manager.h
@@ -42,7 +42,7 @@
                     BufferSyncHandler *buffer_sync_handler);
   DisplayError Deinit();
   DisplayError RegisterDisplay(DisplayType type, const HWDisplayAttributes &attributes,
-                               Handle *display_ctx);
+                               const HWPanelInfo &hw_panel_info, Handle *display_ctx);
   DisplayError UnregisterDisplay(Handle display_ctx);
   DisplayError Start(Handle display_ctx);
   DisplayError Stop(Handle display_ctx);
@@ -120,6 +120,7 @@
     BufferManager *buffer_manager;
     DisplayType display_type;
     HWBlockType hw_block_id;
+    HWPanelInfo hw_panel_info_;
     uint64_t frame_count;
     int32_t session_id;  // applicable for virtual display sessions only
     uint32_t rotate_count;
diff --git a/displayengine/libs/core/strategy_default.cpp b/displayengine/libs/core/strategy_default.cpp
index e3270b7..48fc79d 100644
--- a/displayengine/libs/core/strategy_default.cpp
+++ b/displayengine/libs/core/strategy_default.cpp
@@ -35,6 +35,8 @@
 }
 
 DisplayError StrategyDefault::CreateStrategyInterface(uint16_t version, DisplayType type,
+                                                      const HWResourceInfo *hw_resource_info,
+                                                      const HWPanelInfo *hw_panel_info,
                                                       StrategyInterface **interface) {
   StrategyDefault *strategy_default  = new StrategyDefault();
 
diff --git a/displayengine/libs/core/strategy_default.h b/displayengine/libs/core/strategy_default.h
index 2ba19f8..7b6f594 100644
--- a/displayengine/libs/core/strategy_default.h
+++ b/displayengine/libs/core/strategy_default.h
@@ -35,6 +35,8 @@
   StrategyDefault();
 
   static DisplayError CreateStrategyInterface(uint16_t version, DisplayType type,
+                                              const HWResourceInfo *hw_resource_info,
+                                              const HWPanelInfo *hw_panel_info,
                                               StrategyInterface **interface);
   static DisplayError DestroyStrategyInterface(StrategyInterface *interface);
 
diff --git a/displayengine/libs/utils/debug_android.cpp b/displayengine/libs/utils/debug_android.cpp
index 96339df..77c82b0 100644
--- a/displayengine/libs/utils/debug_android.cpp
+++ b/displayengine/libs/utils/debug_android.cpp
@@ -89,5 +89,15 @@
   return false;
 }
 
+// This property serves to disable/enable partial update
+bool Debug::IsPartialUpdate() {
+  char property[PROPERTY_VALUE_MAX];
+  if (property_get("sde.hwc.partial_update", property, NULL) > 0) {
+    return (atoi(property) ? 1 : true, false);
+  }
+
+  return false;
+}
+
 }  // namespace sde
 
diff --git a/displayengine/libs/utils/rect.cpp b/displayengine/libs/utils/rect.cpp
index 8dfd7dd..9b05951 100644
--- a/displayengine/libs/utils/rect.cpp
+++ b/displayengine/libs/utils/rect.cpp
@@ -35,15 +35,33 @@
 
 namespace sde {
 
-bool IsValidRect(const LayerRect &rect) {
+bool IsValid(const LayerRect &rect) {
   return ((rect.bottom > rect.top) && (rect.right > rect.left));
 }
 
+bool IsCongruent(const LayerRect &rect1, const LayerRect &rect2) {
+  return ((rect1.left == rect2.left) &&
+          (rect1.top == rect2.top) &&
+          (rect1.right == rect2.right) &&
+          (rect1.bottom == rect2.bottom));
+}
 
-LayerRect GetIntersection(const LayerRect &rect1, const LayerRect &rect2) {
+void Log(DebugTag debug_tag, const char *prefix, const LayerRect &roi) {
+  DLOGV_IF(debug_tag, "%s: left = %.0f, top = %.0f, right = %.0f, bottom = %.0f",
+           prefix, roi.left, roi.top, roi.right, roi.bottom);
+}
+
+void Normalize(const uint32_t &align_x, const uint32_t &align_y, LayerRect *rect) {
+    rect->left = ROUND_UP_ALIGN_UP(rect->left, align_x);
+    rect->right = ROUND_UP_ALIGN_DOWN(rect->right, align_x);
+    rect->top = ROUND_UP_ALIGN_UP(rect->top, align_y);
+    rect->bottom = ROUND_UP_ALIGN_DOWN(rect->bottom, align_y);
+}
+
+LayerRect Intersection(const LayerRect &rect1, const LayerRect &rect2) {
   LayerRect res;
 
-  if (!IsValidRect(rect1) || !IsValidRect(rect2)) {
+  if (!IsValid(rect1) || !IsValid(rect2)) {
     return LayerRect();
   }
 
@@ -52,23 +70,72 @@
   res.right = MIN(rect1.right, rect2.right);
   res.bottom = MIN(rect1.bottom, rect2.bottom);
 
-  if (!IsValidRect(res)) {
+  if (!IsValid(res)) {
     return LayerRect();
   }
 
   return res;
 }
 
-void LogRect(DebugTag debug_tag, const char *prefix, const LayerRect &roi) {
-  DLOGV_IF(debug_tag, "%s: left = %.0f, top = %.0f, right = %.0f, bottom = %.0f",
-           prefix, roi.left, roi.top, roi.right, roi.bottom);
+LayerRect Reposition(const LayerRect &rect, const int &x_offset, const int &y_offset) {
+  LayerRect res;
+
+  if (!IsValid(rect)) {
+    return LayerRect();
+  }
+
+  res.left = rect.left + FLOAT(x_offset);
+  res.top = rect.top + FLOAT(y_offset);
+  res.right = rect.right + FLOAT(x_offset);
+  res.bottom = rect.bottom + FLOAT(y_offset);
+
+  return res;
 }
 
-void NormalizeRect(const uint32_t &align_x, const uint32_t &align_y, LayerRect *rect) {
-  rect->left = ROUND_UP_ALIGN_UP(rect->left, align_x);
-  rect->right = ROUND_UP_ALIGN_DOWN(rect->right, align_x);
-  rect->top = ROUND_UP_ALIGN_UP(rect->top, align_y);
-  rect->bottom = ROUND_UP_ALIGN_DOWN(rect->bottom, align_y);
+// Not a geometrical rect deduction. Deducts rect2 from rect1 only if it results a single rect
+LayerRect Subtract(const LayerRect &rect1, const LayerRect &rect2) {
+  LayerRect res;
+
+  res = rect1;
+
+  if ((rect1.left == rect2.left) && (rect1.right == rect2.right)) {
+    if ((rect1.top == rect2.top) && (rect2.bottom <= rect1.bottom)) {
+      res.top = rect2.bottom;
+    } else if ((rect1.bottom == rect2.bottom) && (rect2.top >= rect1.top)) {
+      res.bottom = rect2.top;
+    }
+  } else if ((rect1.top == rect2.top) && (rect1.bottom == rect2.bottom)) {
+    if ((rect1.left == rect2.left) && (rect2.right <= rect1.right)) {
+      res.left = rect2.right;
+    } else if ((rect1.right == rect2.right) && (rect2.left >= rect1.left)) {
+      res.right = rect2.left;
+    }
+  }
+
+  return res;
+}
+
+LayerRect Union(const LayerRect &rect1, const LayerRect &rect2) {
+  LayerRect res;
+
+  if (!IsValid(rect1) && !IsValid(rect2)) {
+    return LayerRect();
+  }
+
+  if(!IsValid(rect1)){
+    return rect2;
+  }
+
+  if(!IsValid(rect2)){
+    return rect1;
+  }
+
+  res.left = MIN(rect1.left, rect2.left);
+  res.top = MIN(rect1.top, rect2.top);
+  res.right = MAX(rect1.right, rect2.right);
+  res.bottom = MAX(rect1.bottom, rect2.bottom);
+
+  return res;
 }
 
 }  // namespace sde