hwc2: Add per layer matrix transformation support

This change adds support for the HWC2.3 per layer
matrix transform API.

CRs-Fixed: 2411786
Change-Id: I900f3a8a426be43cf24f05b5dd6be9582c9b5a6c
diff --git a/sdm/include/core/layer_stack.h b/sdm/include/core/layer_stack.h
index 8d429a2..9aba8fa 100644
--- a/sdm/include/core/layer_stack.h
+++ b/sdm/include/core/layer_stack.h
@@ -152,6 +152,9 @@
 
       uint32_t single_buffer : 1;  //!< This flag shall be set by client to indicate that the layer
                                    //!< uses only a single buffer that will not be swapped out
+
+      uint32_t color_transform : 1;  //!< This flag will be set by SDM when the layer
+                                     //!< has a custom matrix
     };
 
     uint32_t flags = 0;       //!< For initialization purpose only.
@@ -361,6 +364,10 @@
                                                    //!< needed on this layer.
   LayerSolidFill solid_fill_info = {};             //!< solid fill info along with depth.
   std::shared_ptr<LayerBufferMap> buffer_map = nullptr;  //!< Map of handle_id and fb_id.
+  float color_transform_matrix[kColorTransformMatrixSize] = { 1.0, 0.0, 0.0, 0.0,
+                                                              0.0, 1.0, 0.0, 0.0,
+                                                              0.0, 0.0, 1.0, 0.0,
+                                                              0.0, 0.0, 0.0, 1.0 };
 };
 
 /*! @brief This structure defines the color space + transfer of a given layer.
diff --git a/sdm/include/utils/constants.h b/sdm/include/utils/constants.h
index 342f436..e34ce60 100644
--- a/sdm/include/utils/constants.h
+++ b/sdm/include/utils/constants.h
@@ -78,6 +78,11 @@
   const int kPageSize = 4096;
   const uint32_t kGridSize = 129;  // size used for non-linear transformation before Tone-mapping
   const uint32_t kLutDim = 17;  // Dim of the 3d LUT for tone-mapping.
+  const int kColorTransformMatrixSize = 16;
+  const float kIdentityMatrix[kColorTransformMatrixSize] = { 1.0, 0.0, 0.0, 0.0,
+                                                             0.0, 1.0, 0.0, 0.0,
+                                                             0.0, 0.0, 1.0, 0.0,
+                                                             0.0, 0.0, 0.0, 1.0 };
 
   typedef void * Handle;
 
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 5a12549..ee55829 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -669,7 +669,6 @@
   metadata_refresh_rate_ = 0;
   layer_stack_.flags.animating = animating_;
   layer_stack_.flags.fast_path = fast_path_enabled_ && fast_path_composition_;
-
   // Add one layer for fb target
   for (auto hwc_layer : layer_set_) {
     // Reset layer data which SDM may change
@@ -790,6 +789,10 @@
       layer->flags.updating = IsLayerUpdating(hwc_layer);
     }
 
+    if (hwc_layer->IsColorTransformSet()) {
+      layer->flags.color_transform = true;
+    }
+
     layer_stack_.layers.push_back(layer);
   }
 
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 04896bc..8cdf63d 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -534,6 +534,20 @@
     geometry_changes_ |= kZOrder;
     z_ = z;
   }
+
+  return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerColorTransform(const float *matrix) {
+  std::memcpy(layer_->color_transform_matrix, matrix, sizeof(layer_->color_transform_matrix));
+  needs_validate_ = true;
+
+  if (!std::memcmp(matrix, kIdentityMatrix, sizeof(kIdentityMatrix))) {
+    color_transform_matrix_set_ = false;
+  } else {
+    color_transform_matrix_set_ = true;
+  }
+
   return HWC2::Error::None;
 }
 
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
index f628b53..b21c2bb 100644
--- a/sdm/libs/hwc2/hwc_layers.h
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -90,6 +90,7 @@
   HWC2::Error SetLayerPerFrameMetadata(uint32_t num_elements, const PerFrameMetadataKey *keys,
                                        const float *metadata);
   HWC2::Error SetLayerZOrder(uint32_t z);
+  HWC2::Error SetLayerColorTransform(const float *matrix);
   void SetComposition(const LayerComposition &sdm_composition);
   HWC2::Composition GetClientRequestedCompositionType() { return client_requested_; }
   void UpdateClientCompositionType(HWC2::Composition type) { client_requested_ = type; }
@@ -111,6 +112,7 @@
   void SetPartialUpdate(bool enabled) { partial_update_enabled_ = enabled; }
   bool IsNonIntegralSourceCrop() { return non_integral_source_crop_; }
   bool HasMetaDataRefreshRate() { return has_metadata_refresh_rate_; }
+  bool IsColorTransformSet() { return color_transform_matrix_set_; }
 
  private:
   Layer *layer_ = nullptr;
@@ -131,6 +133,7 @@
   bool surface_updated_ = true;
   bool non_integral_source_crop_ = false;
   bool has_metadata_refresh_rate_ = false;
+  bool color_transform_matrix_set_ = false;
 
   // Composition requested by client(SF)
   HWC2::Composition client_requested_ = HWC2::Composition::Device;
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index aa19a89..90aecb1 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -883,6 +883,12 @@
   return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
 }
 
+static int32_t SetLayerColorTransform(hwc2_device_t *device, hwc2_display_t display,
+                                      hwc2_layer_t layer, const float *matrix) {
+  return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColorTransform,
+                                       matrix);
+}
+
 int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
                                     buffer_handle_t buffer, int32_t releaseFence) {
   if (!device) {
@@ -1133,6 +1139,8 @@
     case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
       return AsFP<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>
              (HWCSession::GetDisplayIdentificationData);
+    case HWC2::FunctionDescriptor::SetLayerColorTransform:
+      return AsFP<HWC2_PFN_SET_LAYER_COLOR_TRANSFORM>(SetLayerColorTransform);
     default:
       DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
             to_string(descriptor).c_str());