Merge 25Q1 (ab/BP1A.250305.020) to AOSP main am: 54fc5ed35d am: ccea2dd929

Original change: undetermined

Change-Id: I0837b128fa0569ba568ad8457ab3eb0bb83b5770
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/drm/DrmAtomicStateManager.cpp b/drm/DrmAtomicStateManager.cpp
index 299d30c..4e4be80 100644
--- a/drm/DrmAtomicStateManager.cpp
+++ b/drm/DrmAtomicStateManager.cpp
@@ -170,6 +170,23 @@
       return -EINVAL;
   }
 
+  if (args.min_bpc && connector->GetMinBpcProperty()) {
+    int err;
+    uint64_t range_min, range_max = 0;
+    std::tie(err, range_min) = connector->GetMinBpcProperty().RangeMin();
+    if (err)
+      return err;
+    std::tie(err, range_max) = connector->GetMinBpcProperty().RangeMax();
+    if (err)
+      return err;
+
+    // Adjust requested min bpc to be within the property range
+    int32_t min_bpc_val = std::max(args.min_bpc.value(), static_cast<int32_t>(range_min));
+    min_bpc_val = std::min(min_bpc_val, static_cast<int32_t>(range_max));
+    if (!connector->GetMinBpcProperty().AtomicSet(*pset, min_bpc_val))
+      return -EINVAL;
+  }
+
   auto unused_planes = new_frame_state.used_planes;
 
   if (args.composition) {
diff --git a/drm/DrmAtomicStateManager.h b/drm/DrmAtomicStateManager.h
index f97a488..e4fff56 100644
--- a/drm/DrmAtomicStateManager.h
+++ b/drm/DrmAtomicStateManager.h
@@ -41,6 +41,7 @@
   std::optional<Colorspace> colorspace;
   std::optional<int32_t> content_type;
   std::shared_ptr<hdr_output_metadata> hdr_metadata;
+  std::optional<int32_t> min_bpc;
 
   std::shared_ptr<DrmFbIdHandle> writeback_fb;
   SharedFd writeback_release_fence;
diff --git a/drm/DrmConnector.cpp b/drm/DrmConnector.cpp
index 37e1be4..82a109b 100644
--- a/drm/DrmConnector.cpp
+++ b/drm/DrmConnector.cpp
@@ -146,6 +146,8 @@
   GetOptionalConnectorProperty("HDR_OUTPUT_METADATA",
                                &hdr_output_metadata_property_);
 
+  GetOptionalConnectorProperty("min bpc", &min_bpc_property_);
+
   if (GetOptionalConnectorProperty("panel orientation", &panel_orientation_)) {
     panel_orientation_
         .AddEnumToMapReverse("Normal",
diff --git a/drm/DrmConnector.h b/drm/DrmConnector.h
index c22d059..4d4f070 100644
--- a/drm/DrmConnector.h
+++ b/drm/DrmConnector.h
@@ -115,6 +115,10 @@
     return content_type_property_;
   }
 
+  auto &GetMinBpcProperty() const {
+    return min_bpc_property_;
+  }
+
   auto &GetHdrOutputMetadataProperty() const {
     return hdr_output_metadata_property_;
   }
@@ -173,6 +177,7 @@
   DrmProperty edid_property_;
   DrmProperty colorspace_property_;
   DrmProperty content_type_property_;
+  DrmProperty min_bpc_property_;
   DrmProperty hdr_output_metadata_property_;
 
   DrmProperty link_status_property_;
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index 42ebd63..13287ef 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -187,6 +187,43 @@
   return GetConfig(staged_mode_config_id_.value_or(configs_.active_config_id));
 }
 
+HWC2::Error HwcDisplay::SetOutputType(uint32_t hdr_output_type) {
+  switch (hdr_output_type) {
+    case 3: { // HDR10
+      auto ret = SetHdrOutputMetadata(ui::Hdr::HDR10);
+      if (ret != HWC2::Error::None)
+        return ret;
+      min_bpc_ = 8;
+      colorspace_ = Colorspace::kBt2020Rgb;
+      break;
+    }
+    case 1: { // SYSTEM
+      std::vector<ui::Hdr> hdr_types;
+      GetEdid()->GetSupportedHdrTypes(hdr_types);
+      if (!hdr_types.empty()) {
+        auto ret = SetHdrOutputMetadata(hdr_types.front());
+        if (ret != HWC2::Error::None)
+          return ret;
+        min_bpc_ = 8;
+        colorspace_ = Colorspace::kBt2020Rgb;
+        break;
+      } else {
+        [[fallthrough]];
+      }
+    }
+    case 0:  // INVALID
+      [[fallthrough]];
+    case 2:  // SDR
+      [[fallthrough]];
+    default:
+      hdr_metadata_.reset();
+      min_bpc_ = 6;
+      colorspace_ = Colorspace::kDefault;
+  }
+
+  return HWC2::Error::None;
+}
+
 HwcDisplay::ConfigError HwcDisplay::SetConfig(hwc2_config_t config) {
   const HwcDisplayConfig *new_config = GetConfig(config);
   if (new_config == nullptr) {
@@ -230,6 +267,8 @@
   }
 
   ALOGV("Create modeset commit.");
+  SetOutputType(new_config->output_type);
+
   // Create atomic commit args for a blocking modeset. There's no need to do a
   // separate test commit, since the commit does a test anyways.
   AtomicCommitArgs commit_args = CreateModesetCommit(new_config,
@@ -239,7 +278,7 @@
 
   if (ret) {
     ALOGE("Blocking config failed: %d", ret);
-    return HwcDisplay::ConfigError::kBadConfig;
+    return HwcDisplay::ConfigError::kConfigFailed;
   }
 
   ALOGV("Blocking config succeeded.");
@@ -664,6 +703,7 @@
   args.content_type = content_type_;
   args.colorspace = colorspace_;
   args.hdr_metadata = hdr_metadata_;
+  args.min_bpc = min_bpc_;
 
   std::vector<LayerData> composition_layers;
   if (modeset_layer) {
@@ -695,6 +735,7 @@
   a_args.content_type = content_type_;
   a_args.colorspace = colorspace_;
   a_args.hdr_metadata = hdr_metadata_;
+  a_args.min_bpc = min_bpc_;
 
   uint32_t prev_vperiod_ns = 0;
   GetDisplayVsyncPeriod(&prev_vperiod_ns);
@@ -825,6 +866,8 @@
 
   staged_mode_change_time_ = change_time;
   staged_mode_config_id_ = config;
+  if (const HwcDisplayConfig *new_config = GetConfig(config))
+    SetOutputType(new_config->output_type);
 
   return HWC2::Error::None;
 }
@@ -842,38 +885,24 @@
 
   switch (mode) {
     case HAL_COLOR_MODE_NATIVE:
-      hdr_metadata_.reset();
       colorspace_ = Colorspace::kDefault;
       break;
     case HAL_COLOR_MODE_STANDARD_BT601_625:
     case HAL_COLOR_MODE_STANDARD_BT601_625_UNADJUSTED:
     case HAL_COLOR_MODE_STANDARD_BT601_525:
     case HAL_COLOR_MODE_STANDARD_BT601_525_UNADJUSTED:
-      hdr_metadata_.reset();
       // The DP spec does not say whether this is the 525 or the 625 line version.
       colorspace_ = Colorspace::kBt601Ycc;
       break;
     case HAL_COLOR_MODE_STANDARD_BT709:
     case HAL_COLOR_MODE_SRGB:
-      hdr_metadata_.reset();
       colorspace_ = Colorspace::kBt709Ycc;
       break;
     case HAL_COLOR_MODE_DCI_P3:
     case HAL_COLOR_MODE_DISPLAY_P3:
-      hdr_metadata_.reset();
       colorspace_ = Colorspace::kDciP3RgbD65;
       break;
-    case HAL_COLOR_MODE_DISPLAY_BT2020: {
-      std::vector<ui::Hdr> hdr_types;
-      GetEdid()->GetSupportedHdrTypes(hdr_types);
-      if (!hdr_types.empty()) {
-        auto ret = SetHdrOutputMetadata(hdr_types.front());
-        if (ret != HWC2::Error::None)
-          return ret;
-      }
-      colorspace_ = Colorspace::kBt2020Rgb;
-      break;
-    }
+    case HAL_COLOR_MODE_DISPLAY_BT2020:
     case HAL_COLOR_MODE_ADOBE_RGB:
     case HAL_COLOR_MODE_BT2020:
     case HAL_COLOR_MODE_BT2100_PQ:
diff --git a/hwc2_device/HwcDisplay.h b/hwc2_device/HwcDisplay.h
index 7391785..94f3f14 100644
--- a/hwc2_device/HwcDisplay.h
+++ b/hwc2_device/HwcDisplay.h
@@ -52,7 +52,8 @@
     kNone,
     kBadConfig,
     kSeamlessNotAllowed,
-    kSeamlessNotPossible
+    kSeamlessNotPossible,
+    kConfigFailed,
   };
 
   HwcDisplay(hwc2_display_t handle, HWC2::DisplayType type, DrmHwc *hwc);
@@ -279,6 +280,7 @@
   android_color_transform_t color_transform_hint_{};
   int32_t content_type_{};
   Colorspace colorspace_{};
+  int32_t min_bpc_{};
   std::shared_ptr<hdr_output_metadata> hdr_metadata_;
 
   std::shared_ptr<DrmKmsPlan> current_plan_;
@@ -294,6 +296,8 @@
 
   HWC2::Error SetActiveConfigInternal(uint32_t config, int64_t change_time);
   HWC2::Error SetHdrOutputMetadata(ui::Hdr hdrType);
+  HWC2::Error SetOutputType(uint32_t hdr_output_type);
+
   auto GetEdid() -> EdidWrapperUnique & {
     return GetPipe().connector->Get()->GetParsedEdid();
   }
diff --git a/hwc2_device/HwcDisplayConfigs.cpp b/hwc2_device/HwcDisplayConfigs.cpp
index fa1d2a9..ca70c14 100644
--- a/hwc2_device/HwcDisplayConfigs.cpp
+++ b/hwc2_device/HwcDisplayConfigs.cpp
@@ -147,6 +147,7 @@
         .group_id = group_found,
         .mode = mode,
         .disabled = disabled,
+        .output_type = 1,  // OutputType::SYSTEM
     };
 
     /* Chwck if the mode is preferred */
diff --git a/hwc2_device/HwcDisplayConfigs.h b/hwc2_device/HwcDisplayConfigs.h
index 33dcb81..8fc89bf 100644
--- a/hwc2_device/HwcDisplayConfigs.h
+++ b/hwc2_device/HwcDisplayConfigs.h
@@ -31,6 +31,7 @@
   uint32_t group_id{};
   DrmMode mode{};
   bool disabled{};
+  uint32_t output_type{};
 
   bool IsInterlaced() const {
     return (mode.GetRawMode().flags & DRM_MODE_FLAG_INTERLACE) != 0;
diff --git a/hwc3/ComposerClient.cpp b/hwc3/ComposerClient.cpp
index c378397..d6efe07 100644
--- a/hwc3/ComposerClient.cpp
+++ b/hwc3/ComposerClient.cpp
@@ -31,6 +31,7 @@
 #include <aidl/android/hardware/graphics/composer3/DisplayRequest.h>
 #include <aidl/android/hardware/graphics/composer3/IComposerClient.h>
 #include <aidl/android/hardware/graphics/composer3/Luts.h>
+#include <aidl/android/hardware/graphics/composer3/OutputType.h>
 #include <aidl/android/hardware/graphics/composer3/PowerMode.h>
 #include <aidl/android/hardware/graphics/composer3/PresentOrValidate.h>
 #include <aidl/android/hardware/graphics/composer3/RenderIntent.h>
@@ -278,7 +279,8 @@
        .width = config.mode.GetRawMode().hdisplay,
        .height = config.mode.GetRawMode().vdisplay,
        .configGroup = static_cast<int32_t>(config.group_id),
-       .vsyncPeriod = config.mode.GetVSyncPeriodNs()};
+       .vsyncPeriod = config.mode.GetVSyncPeriodNs(),
+       .hdrOutputType = static_cast<OutputType>(config.output_type)};
 
   if (configs.mm_width != 0) {
     // ideally this should be vdisplay/mm_heigth, however mm_height
@@ -1264,6 +1266,8 @@
       return ToBinderStatus(hwc3::Error::kSeamlessNotAllowed);
     case HwcDisplay::ConfigError::kSeamlessNotPossible:
       return ToBinderStatus(hwc3::Error::kSeamlessNotPossible);
+    case HwcDisplay::ConfigError::kConfigFailed:
+      return ToBinderStatus(hwc3::Error::kConfigFailed);
     case HwcDisplay::ConfigError::kNone:
       return ndk::ScopedAStatus::ok();
   }
diff --git a/hwc3/Utils.h b/hwc3/Utils.h
index 642c777..aa956f6 100644
--- a/hwc3/Utils.h
+++ b/hwc3/Utils.h
@@ -40,6 +40,7 @@
   kUnsupported = IComposerClient::EX_UNSUPPORTED,
   kSeamlessNotAllowed = IComposerClient::EX_SEAMLESS_NOT_ALLOWED,
   kSeamlessNotPossible = IComposerClient::EX_SEAMLESS_NOT_POSSIBLE,
+  kConfigFailed = IComposerClient::EX_CONFIG_FAILED,
 };
 }  // namespace hwc3