sdm: Add support for solid fill mixer stage

- Define drm interface for setting solid fill stage info on crtc.
- Define sdm private structure for solid fill layers in hw layer config.
- Add DAL translation of setting up solidfill stages for atomic commit.
- Multiply alpha component of color with plane alpha.

Change-Id: I60ac64beee31986f83fcfe025a7ece02aa0198b1
CRs-fixed: 2026472
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 8fddb43..35285ee 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -230,6 +230,12 @@
    */
   CRTC_SET_SECURITY_LEVEL,
   /*
+   * Op: sets solid fill stages
+   * Arg: uint32_t - CRTC ID
+   *      Vector of DRMSolidfillStage
+   */
+  CRTC_SET_SOLIDFILL_STAGES,
+  /*
    * Op: Returns retire fence for this commit. Should be called after Commit() on
    * DRMAtomicReqInterface.
    * Arg: uint32_t - Connector ID
@@ -321,6 +327,7 @@
 struct DRMCrtcInfo {
   bool has_src_split;
   uint32_t max_blend_stages;
+  uint32_t max_solidfill_stages;
   QSEEDVersion qseed_version;
   SmartDMARevision smart_dma_rev;
   float ib_fudge_factor;
@@ -471,6 +478,14 @@
   SECURE_ONLY,
 };
 
+struct DRMSolidfillStage {
+ DRMRect bounding_rect {};
+ bool is_exclusion_rect = false;
+ uint32_t color = 0xff000000; // in 8bit argb
+ uint32_t z_order = 0;
+ uint32_t plane_alpha = 0xff;
+};
+
 /* DRM Atomic Request Property Set.
  *
  * Helper class to create and populate atomic properties of DRM components
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 8cf1922..752d0c4 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -157,6 +157,7 @@
   uint32_t num_rgb_pipe = 0;
   uint32_t num_cursor_pipe = 0;
   uint32_t num_blending_stages = 0;
+  uint32_t num_solidfill_stages = 0;
   uint32_t num_control = 0;
   uint32_t num_mixer_to_disp = 0;
   uint32_t smp_total = 0;
@@ -460,11 +461,21 @@
   void Reset() { *this = HWPipeInfo(); }
 };
 
+struct HWSolidfillStage {
+  uint32_t z_order = kMaxSDELayers;
+  uint32_t color = 0;
+  LayerRect roi = {};
+  bool is_exclusion_rect = false;
+};
+
 struct HWLayerConfig {
   HWPipeInfo left_pipe;           // pipe for left side of output
   HWPipeInfo right_pipe;          // pipe for right side of output
   HWRotatorSession hw_rotator_session;
+  HWSolidfillStage hw_solidfill_stage;
+
   float compression = 1.0f;
+  bool use_solidfill_stage = false;
 
   void Reset() { *this = HWLayerConfig(); }
 };
diff --git a/sdm/libs/core/drm/hw_device_drm.cpp b/sdm/libs/core/drm/hw_device_drm.cpp
index 29ac44e..30168ef 100644
--- a/sdm/libs/core/drm/hw_device_drm.cpp
+++ b/sdm/libs/core/drm/hw_device_drm.cpp
@@ -668,6 +668,8 @@
   HWQosData &qos_data = hw_layers->qos_data;
   DRMSecurityLevel crtc_security_level = DRMSecurityLevel::SECURE_NON_SECURE;
 
+  solid_fills_.clear();
+
   // TODO(user): Once destination scalar is enabled we can always send ROIs if driver allows
   if (hw_panel_info_.partial_update) {
     const int kNumMaxROIs = 4;
@@ -703,6 +705,11 @@
     HWPipeInfo *right_pipe = &hw_layers->config[i].right_pipe;
     HWRotatorSession *hw_rotator_session = &hw_layers->config[i].hw_rotator_session;
 
+    if (hw_layers->config[i].use_solidfill_stage) {
+      AddSolidfillStage(hw_layers->config[i].hw_solidfill_stage, layer.plane_alpha);
+      continue;
+    }
+
     for (uint32_t count = 0; count < 2; count++) {
       HWPipeInfo *pipe_info = (count == 0) ? left_pipe : right_pipe;
       HWRotateInfo *hw_rotate_info = &hw_rotator_session->hw_rotate_info[count];
@@ -769,6 +776,7 @@
     }
   }
 
+  SetSolidfillStages();
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_CLK, token_.crtc_id, qos_data.clock_hz);
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_AB, token_.crtc_id, qos_data.core_ab_bps);
   drm_atomic_intf_->Perform(DRMOps::CRTC_SET_CORE_IB, token_.crtc_id, qos_data.core_ib_bps);
@@ -785,6 +793,28 @@
            qos_data.rot_clock_hz);
 }
 
+void HWDeviceDRM::AddSolidfillStage(const HWSolidfillStage &sf, uint32_t plane_alpha) {
+  sde_drm::DRMSolidfillStage solidfill;
+  solidfill.bounding_rect.left = UINT32(sf.roi.left);
+  solidfill.bounding_rect.top = UINT32(sf.roi.top);
+  solidfill.bounding_rect.right = UINT32(sf.roi.right);
+  solidfill.bounding_rect.bottom = UINT32(sf.roi.bottom);
+  solidfill.is_exclusion_rect  = sf.is_exclusion_rect;
+  solidfill.plane_alpha = plane_alpha;
+  solidfill.z_order = sf.z_order;
+  solidfill.color = sf.color;
+  solid_fills_.push_back(solidfill);
+  DLOGI_IF(kTagDriverConfig, "Add a solidfill stage at z_order:%d argb_color:%x plane_alpha:%x",
+           solidfill.z_order, solidfill.color, solidfill.plane_alpha);
+}
+
+void HWDeviceDRM::SetSolidfillStages() {
+  if (hw_resource_.num_solidfill_stages) {
+    drm_atomic_intf_->Perform(DRMOps::CRTC_SET_SOLIDFILL_STAGES, token_.crtc_id,
+                              reinterpret_cast<uint64_t> (&solid_fills_));
+  }
+}
+
 DisplayError HWDeviceDRM::Validate(HWLayers *hw_layers) {
   DTRACE_SCOPED();
 
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index e754cfa..eb836ed 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -118,6 +118,8 @@
   void ResetDisplayParams();
   bool EnableHotPlugDetection(int enable);
   void UpdateMixerAttributes();
+  void SetSolidfillStages();
+  void AddSolidfillStage(const HWSolidfillStage &sf, uint32_t plane_alpha);
   void SetBlending(const LayerBlending &source, sde_drm::DRMBlendType *target);
   void SetSrcConfig(const LayerBuffer &input_buffer, uint32_t *config);
   void SetRect(const LayerRect &source, sde_drm::DRMRect *target);
@@ -176,6 +178,7 @@
   HWMixerAttributes mixer_attributes_ = {};
   std::string interface_str_ = "DSI";
   HWScaleDRM *hw_scale_ = {};
+  std::vector<sde_drm::DRMSolidfillStage> solid_fills_ {};
 };
 
 }  // namespace sdm
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index 7b632e8..69af1bd 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -254,6 +254,7 @@
   hw_resource->is_src_split = info.has_src_split;
   hw_resource->has_qseed3 = (info.qseed_version == sde_drm::QSEEDVersion::V3);
   hw_resource->num_blending_stages = info.max_blend_stages;
+  hw_resource->num_solidfill_stages = info.max_solidfill_stages;
   hw_resource->smart_dma_rev = (info.smart_dma_rev == sde_drm::SmartDMARevision::V2) ?
     SmartDMARevision::V2 : SmartDMARevision::V1;
   hw_resource->ib_fudge_factor = info.ib_fudge_factor;