ANDROID: Set min bpc on modeset

When HDR10 is the desired output type for the display mode, request a minimum
bpc of 8 from the connector. This ensures the quality of the HDR content and
allows the caller to retry with SDR if there is insufficient bandwidth.

Bug: 374183675
Test: Presubmit
Change-Id: I897e0b42e0065a61ecfe28c280094b6c375d8a72
Signed-off-by: Sasha McIntosh <sashamcintosh@google.com>
diff --git a/drm/DrmAtomicStateManager.cpp b/drm/DrmAtomicStateManager.cpp
index 9ce9a93..405c311 100644
--- a/drm/DrmAtomicStateManager.cpp
+++ b/drm/DrmAtomicStateManager.cpp
@@ -165,6 +165,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 4af04d1..510bf70 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_;