Upgrade drm_hwcomposer to 12d302c4abcef99ab28c94c3fef709754fac48e2

This project was upgraded with external_updater.
Usage: tools/external_updater/updater.sh update external/drm_hwcomposer
For more info, check https://cs.android.com/android/platform/superproject/main/+/main:tools/external_updater/README.md

Test: TreeHugger
Change-Id: I58953e268a57e1af8bc75d0e2ee6609a8c77d410
diff --git a/METADATA b/METADATA
index 24845b6..c577677 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@
   last_upgrade_date {
     year: 2025
     month: 3
-    day: 14
+    day: 21
   }
   identifier {
     type: "Git"
     value: "https://gitlab.freedesktop.org/drm-hwcomposer/drm-hwcomposer"
-    version: "f638348b22e96e208badb71de52a860d201ee2fb"
+    version: "12d302c4abcef99ab28c94c3fef709754fac48e2"
   }
 }
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index c97c640..2a47a2a 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -48,6 +48,11 @@
     0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F,
 };
 
+bool float_equals(float a, float b) {
+  const float epsilon = 0.001F;
+  return std::abs(a - b) < epsilon;
+}
+
 uint64_t To3132FixPt(float in) {
   constexpr uint64_t kSignMask = (1ULL << 63);
   constexpr uint64_t kValueMask = ~(1ULL << 63);
@@ -57,6 +62,16 @@
   return static_cast<uint64_t>(in * kValueScale) & kValueMask;
 }
 
+bool TransformHasOffsetValue(const float *matrix) {
+  for (int i = 12; i < 14; i++) {
+    if (!float_equals(matrix[i], 0.F)) {
+      ALOGW("DRM API does not support CTM with offsets.");
+      return true;
+    }
+  }
+  return false;
+}
+
 auto ToColorTransform(const std::array<float, 16> &color_transform_matrix) {
   /* HAL provides a 4x4 float type matrix:
    * | 0  1  2  3|
@@ -134,35 +149,31 @@
   if (type_ == HWC2::DisplayType::Virtual) {
     writeback_layer_ = std::make_unique<HwcLayer>(this);
   }
+
+  identity_color_matrix_ = ToColorTransform(kIdentityMatrix);
 }
 
 void HwcDisplay::SetColorTransformMatrix(
     const std::array<float, 16> &color_transform_matrix) {
-  auto almost_equal = [](auto a, auto b) {
-    const float epsilon = 0.001F;
-    return std::abs(a - b) < epsilon;
-  };
   const bool is_identity = std::equal(color_transform_matrix.begin(),
                                       color_transform_matrix.end(),
-                                      kIdentityMatrix.begin(), almost_equal);
+                                      kIdentityMatrix.begin(), float_equals);
   color_transform_hint_ = is_identity ? HAL_COLOR_TRANSFORM_IDENTITY
                                       : HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX;
+  ctm_has_offset_ = false;
+
   if (color_transform_hint_ == is_identity) {
     SetColorMatrixToIdentity();
   } else {
+    if (TransformHasOffsetValue(color_transform_matrix.data()))
+      ctm_has_offset_ = true;
+
     color_matrix_ = ToColorTransform(color_transform_matrix);
   }
 }
 
 void HwcDisplay::SetColorMatrixToIdentity() {
-  color_matrix_ = std::make_shared<drm_color_ctm>();
-  for (int i = 0; i < kCtmCols; i++) {
-    for (int j = 0; j < kCtmRows; j++) {
-      constexpr uint64_t kOne = (1ULL << 32); /* 1.0 in s31.32 format */
-      color_matrix_->matrix[(i * kCtmRows) + j] = (i == j) ? kOne : 0;
-    }
-  }
-
+  color_matrix_ = identity_color_matrix_;
   color_transform_hint_ = HAL_COLOR_TRANSFORM_IDENTITY;
 }
 
@@ -822,6 +833,7 @@
   }
 
   // order the layers by z-order
+  size_t client_layer_count = 0;
   bool use_client_layer = false;
   uint32_t client_z_order = UINT32_MAX;
   std::map<uint32_t, HwcLayer *> z_map;
@@ -843,12 +855,20 @@
       case HWC2::Composition::Client:
         // Place it at the z_order of the lowest client layer
         use_client_layer = true;
+        client_layer_count++;
         client_z_order = std::min(client_z_order, layer.GetZOrder());
         break;
       default:
         continue;
     }
   }
+
+  // CTM will be applied by the client, don't apply DRM CTM
+  if (client_layer_count == layers_.size())
+   a_args.color_matrix = identity_color_matrix_;
+  else
+    a_args.color_matrix = color_matrix_;
+
   if (use_client_layer) {
     z_map.emplace(client_z_order, &client_layer_);
 
@@ -1000,6 +1020,7 @@
     return HWC2::Error::BadParameter;
 
   color_transform_hint_ = static_cast<android_color_transform_t>(hint);
+  ctm_has_offset_ = false;
 
   if (IsInHeadlessMode())
     return HWC2::Error::None;
@@ -1014,10 +1035,9 @@
     case HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX:
       // Without HW support, we cannot correctly process matrices with an offset.
       {
-        for (int i = 12; i < 14; i++) {
-          if (matrix[i] != 0.F)
-            return HWC2::Error::Unsupported;
-        }
+        if (TransformHasOffsetValue(matrix))
+          ctm_has_offset_ = true;
+
         std::array<float, 16> aidl_matrix = kIdentityMatrix;
         memcpy(aidl_matrix.data(), matrix, aidl_matrix.size() * sizeof(float));
         color_matrix_ = ToColorTransform(aidl_matrix);
@@ -1034,7 +1054,7 @@
   if (color_transform_hint_ == HAL_COLOR_TRANSFORM_IDENTITY)
     return false;
 
-  if (GetPipe().crtc->Get()->GetCtmProperty())
+  if (GetPipe().crtc->Get()->GetCtmProperty() && !ctm_has_offset_)
     return false;
 
   if (GetHwc()->GetResMan().GetCtmHandling() == CtmHandling::kDrmOrIgnore)
@@ -1307,11 +1327,6 @@
   if (GetHwc()->GetResMan().GetCtmHandling() == CtmHandling::kDrmOrIgnore)
     skip_ctm = true;
 
-  // Skip client CTM if DRM can handle it
-  if (!skip_ctm && !IsInHeadlessMode() &&
-      GetPipe().crtc->Get()->GetCtmProperty())
-    skip_ctm = true;
-
   if (!skip_ctm) {
     *outNumCapabilities = 0;
     return HWC2::Error::None;
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h
index c645400..d493597 100644
--- a/hwc2_device/HwcDisplay.h
+++ b/hwc2_device/HwcDisplay.h
@@ -287,7 +287,9 @@
   uint16_t virtual_disp_height_{};
   int32_t color_mode_{};
   std::shared_ptr<drm_color_ctm> color_matrix_;
+  std::shared_ptr<drm_color_ctm> identity_color_matrix_;
   android_color_transform_t color_transform_hint_{};
+  bool ctm_has_offset_ = false;
   int32_t content_type_{};
   Colorspace colorspace_{};
   int32_t min_bpc_{};
diff --git a/hwc3/ComposerClient.cpp b/hwc3/ComposerClient.cpp
index ecb2dca..bc5932b 100644
--- a/hwc3/ComposerClient.cpp
+++ b/hwc3/ComposerClient.cpp
@@ -198,12 +198,6 @@
     return hwc3::Error::kBadParameter;
   }
 
-  // Without HW support, we cannot correctly process matrices with an offset.
-  constexpr int kOffsetIndex = kCtmColumns * 3;
-  for (int i = kOffsetIndex; i < kOffsetIndex + 3; i++) {
-    if (color_transform_matrix.value()[i] != 0.F)
-      return hwc3::Error::kUnsupported;
-  }
   return hwc3::Error::kNone;
 }