sdm: Add support for excl rect

- Check if excl rect is supported

- Program excl rect for all layers
  below opaque surfaces

Change-Id: Ibb27863ab722b51338990e17c2bacf1bfe920209
CRs-Fixed: 2178936
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 97660ea..5b1b7ac 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2018, 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
@@ -60,6 +60,12 @@
    */
   PLANE_SET_DST_RECT,
   /*
+   * Op: Sets plane exclusion rect
+   * Arg: uint32_t - Plane ID
+   *      drm_clip_rect - Exclusion Rectangle
+   */
+  PLANE_SET_EXCL_RECT,
+  /*
    * Op: Sets plane zorder
    * Arg: uint32_t - Plane ID
    *      uint32_t - zorder
@@ -434,6 +440,7 @@
   uint32_t max_vertical_deci;
   uint64_t max_pipe_bandwidth;
   uint32_t cache_size;  // cache size in bytes for inline rotation support.
+  bool has_excl_rect = false;
   QSEEDStepVersion qseed3_version;
   bool multirect_prop_present = false;
 };
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 52bc73e..19405a2 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -220,6 +220,7 @@
   bool has_qseed3 = false;
   bool has_concurrent_writeback = false;
   bool has_ppp = false;
+  bool has_excl_rect = false;
   uint32_t writeback_index = kHWBlockMax;
   HWDynBwLimitInfo dyn_bw_info;
   std::vector<HWPipeCaps> hw_pipes;
@@ -486,6 +487,7 @@
   HWSubBlockType sub_block_type = kHWSubBlockMax;
   LayerRect src_roi;
   LayerRect dst_roi;
+  LayerRect excl_rect;  // exclusion rectangle per pipe rectangle
   uint8_t horizontal_decimation = 0;
   uint8_t vertical_decimation = 0;
   HWScaleData scale_data;
@@ -528,12 +530,18 @@
   HDROperation operation = kNoOp;
 };
 
+struct LayerExt {
+  std::vector<LayerRect> excl_rects = {};  // list of exclusion rects
+};
+
 struct HWLayersInfo {
   LayerStack *stack = NULL;        // Input layer stack. Set by the caller.
   uint32_t app_layer_count = 0;    // Total number of app layers. Must not be 0.
   uint32_t gpu_target_index = 0;   // GPU target layer index. 0 if not present.
 
   std::vector<Layer> hw_layers = {};  // Layers which need to be programmed on the HW
+  std::vector<LayerExt> layer_exts = {};  // Extention layer having list of
+                                          // exclusion rectangles for each layer
 
   std::vector<uint32_t> index;   // Indexes of the layers from the layer stack which need to
                                  // be programmed on hardware.
diff --git a/sdm/include/utils/formats.h b/sdm/include/utils/formats.h
index 2d43850..f5a7a25 100644
--- a/sdm/include/utils/formats.h
+++ b/sdm/include/utils/formats.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016 - 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016 - 2018, 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
@@ -56,6 +56,7 @@
 BufferLayout GetBufferLayout(LayerBufferFormat format);
 DisplayError GetBufferFormatTileSize(LayerBufferFormat format, FormatTileSize *tile_size);
 float GetBufferFormatBpp(LayerBufferFormat format);
+bool HasAlphaChannel(LayerBufferFormat format);
 
 }  // namespace sdm
 
diff --git a/sdm/include/utils/rect.h b/sdm/include/utils/rect.h
index b25f76e..c3fd492 100644
--- a/sdm/include/utils/rect.h
+++ b/sdm/include/utils/rect.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-2018, 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
@@ -51,6 +51,8 @@
   LayerRect Union(const LayerRect &rect1, const LayerRect &rect2);
   LayerRect Intersection(const LayerRect &rect1, const LayerRect &rect2);
   LayerRect Subtract(const LayerRect &rect1, const LayerRect &rect2);
+  void Subtract(const LayerRect &rect1, const LayerRect &rect2, LayerRect *res);
+  bool Contains(const LayerRect &rect1, const LayerRect &rect2);
   LayerRect Reposition(const LayerRect &rect1, const int &x_offset, const int &y_offset);
   void SplitLeftRight(const LayerRect &in_rect, uint32_t split_count, uint32_t align_x,
                       bool flip_horizontal, LayerRect *out_rects);
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index c734f4c..4d29d9d 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2018, 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
@@ -863,7 +863,9 @@
         DRMRect dst = {};
         SetRect(pipe_info->dst_roi, &dst);
         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_DST_RECT, pipe_id, dst);
-
+        DRMRect excl = {};
+        SetRect(pipe_info->excl_rect, &excl);
+        drm_atomic_intf_->Perform(DRMOps::PLANE_SET_EXCL_RECT, pipe_id, excl);
         uint32_t rot_bit_mask = 0;
         SetRotation(layer.transform, hw_rotator_session->mode, &rot_bit_mask);
         drm_atomic_intf_->Perform(DRMOps::PLANE_SET_ROTATION, pipe_id, rot_bit_mask);
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index b08c0e6..80f9ba1 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2018, 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
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index 5c69ed7..b0302a5 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2018, 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
@@ -403,6 +403,7 @@
           name.c_str(), pipe_obj.first, pipe_obj.second.master_plane_id);
     hw_resource->hw_pipes.push_back(std::move(pipe_caps));
   }
+  hw_resource->has_excl_rect = planes[0].second.has_excl_rect;
 }
 
 void HWInfoDRM::PopulatePipeCaps(const sde_drm::DRMPlaneTypeInfo &info,
diff --git a/sdm/libs/utils/formats.cpp b/sdm/libs/utils/formats.cpp
index 42dfea9..74f4f80 100644
--- a/sdm/libs/utils/formats.cpp
+++ b/sdm/libs/utils/formats.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2016-2018, 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
@@ -212,5 +212,25 @@
   return kErrorNone;
 }
 
+bool HasAlphaChannel(LayerBufferFormat format) {
+  switch (format) {
+  case kFormatARGB8888:
+  case kFormatRGBA8888:
+  case kFormatBGRA8888:
+  case kFormatRGBA5551:
+  case kFormatRGBA4444:
+  case kFormatRGBA8888Ubwc:
+  case kFormatRGBA1010102:
+  case kFormatARGB2101010:
+  case kFormatBGRA1010102:
+  case kFormatABGR2101010:
+  case kFormatRGBA1010102Ubwc:
+    return true;
+  default:
+    return false;
+  }
+}
+
+
 }  // namespace sdm
 
diff --git a/sdm/libs/utils/rect.cpp b/sdm/libs/utils/rect.cpp
index a830542..e121b58 100644
--- a/sdm/libs/utils/rect.cpp
+++ b/sdm/libs/utils/rect.cpp
@@ -1,5 +1,5 @@
 /*
-* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
+* Copyright (c) 2015-2018, 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
@@ -98,6 +98,47 @@
   return res;
 }
 
+// Is rect2 completely inside rect1?
+bool Contains(const LayerRect &rect1, const LayerRect &rect2) {
+  if (!IsValid(rect1) || !IsValid(rect2)) {
+    return false;
+  }
+  return (rect1.top <= rect2.top && rect1.bottom >= rect2.bottom &&
+          rect1.left <= rect2.left && rect1.right >= rect2.right);
+}
+
+// subtracts 2 rects iff result of subtraction is 2 rects.
+void Subtract(const LayerRect &rect1, const LayerRect &rect2, LayerRect *res) {
+  if (!res) {
+    return;
+  }
+  if (!IsValid(rect1) || !IsValid(rect2)) {
+    return;
+  }
+
+  if (rect1.left != rect2.left || rect1.right != rect2.right) {
+    return;
+  }
+  res[0].left = rect1.left;
+  res[0].right = rect1.right;
+  if (rect1.top < rect2.top) {
+    res[0].top = rect1.top;
+    res[0].bottom = rect2.top;
+  } else {
+    res[0].top = rect2.top;
+    res[0].bottom = rect1.top;
+  }
+  res[1].left = rect1.left;
+  res[1].right = rect1.right;
+  if (rect1.bottom < rect2.bottom) {
+    res[1].top = rect1.bottom;
+    res[1].bottom = rect2.bottom;
+  } else {
+    res[1].top = rect2.bottom;
+    res[1].bottom = rect1.bottom;
+  }
+}
+
 // 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;