drm_hwcomposer: Set HDR metadata on the connector

Implement a function to set HDR metadata on the connector. Support HDR10
and HLG, which are common HDR types.

Change-Id: Id3dbe8eea2ee6b8ba700af23845a43e2070dd14e
Signed-off-by: Sasha McIntosh <sashamcintosh@google.com>
diff --git a/utils/EdidWrapper.h b/utils/EdidWrapper.h
index 3552001..867d1a0 100644
--- a/utils/EdidWrapper.h
+++ b/utils/EdidWrapper.h
@@ -24,6 +24,8 @@
 }
 #endif
 
+#include <ui/GraphicTypes.h>
+
 #include "drm/DrmUnique.h"
 #include "utils/log.h"
 
@@ -35,6 +37,16 @@
   EdidWrapper() = default;
   EdidWrapper(const EdidWrapper &) = delete;
   virtual ~EdidWrapper() = default;
+
+  virtual void GetSupportedHdrTypes(std::vector<ui::Hdr> &types) {
+    types.clear();
+  };
+  virtual void GetHdrCapabilities(std::vector<ui::Hdr> &types,
+                                  const float * /*max_luminance*/,
+                                  const float * /*max_average_luminance*/,
+                                  const float * /*min_luminance*/) {
+    GetSupportedHdrTypes(types);
+  };
 };
 
 #if HAS_LIBDISPLAY_INFO
@@ -42,26 +54,23 @@
 class LibdisplayEdidWrapper final : public EdidWrapper {
  public:
   LibdisplayEdidWrapper() = delete;
-  LibdisplayEdidWrapper(di_info *info) : info_(info) {
-  }
   ~LibdisplayEdidWrapper() override {
     di_info_destroy(info_);
   }
   static auto Create(DrmModePropertyBlobUnique blob)
-      -> std::unique_ptr<LibdisplayEdidWrapper> {
-    if (!blob)
-      return nullptr;
+      -> std::unique_ptr<LibdisplayEdidWrapper>;
 
-    auto *info = di_info_parse_edid(blob->data, blob->length);
-    if (!info) {
-      ALOGW("Failed to parse edid blob.");
-      return nullptr;
-    }
+  void GetSupportedHdrTypes(std::vector<ui::Hdr> &types) override;
 
-    return std::make_unique<LibdisplayEdidWrapper>(std::move(info));
-  }
+  void GetHdrCapabilities(std::vector<ui::Hdr> &types,
+                          const float *max_luminance,
+                          const float *max_average_luminance,
+                          const float *min_luminance) override;
 
  private:
+  LibdisplayEdidWrapper(di_info *info) : info_(std::move(info)) {
+  }
+
   di_info *info_{};
 };
 #endif
diff --git a/utils/LibdisplayEdidWrapper.cpp b/utils/LibdisplayEdidWrapper.cpp
new file mode 100644
index 0000000..5a17b93
--- /dev/null
+++ b/utils/LibdisplayEdidWrapper.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "drmhwc"
+
+#if HAS_LIBDISPLAY_INFO
+#include "utils/EdidWrapper.h"
+#include "utils/log.h"
+
+namespace android {
+
+auto LibdisplayEdidWrapper::Create(DrmModePropertyBlobUnique blob)
+    -> std::unique_ptr<LibdisplayEdidWrapper> {
+  if (!blob)
+    return nullptr;
+
+  auto *info = di_info_parse_edid(blob->data, blob->length);
+  if (!info) {
+    ALOGW("Failed to parse edid blob.");
+    return nullptr;
+  }
+
+  return std::unique_ptr<LibdisplayEdidWrapper>(
+      new LibdisplayEdidWrapper(std::move(info)));
+}
+
+void LibdisplayEdidWrapper::GetSupportedHdrTypes(std::vector<ui::Hdr> &types) {
+  types.clear();
+
+  const auto *hdr_static_meta = di_info_get_hdr_static_metadata(info_);
+  const auto *colorimetries = di_info_get_supported_signal_colorimetry(info_);
+  if (colorimetries->bt2020_cycc || colorimetries->bt2020_ycc ||
+      colorimetries->bt2020_rgb) {
+    if (hdr_static_meta->pq)
+      types.emplace_back(ui::Hdr::HDR10);
+    if (hdr_static_meta->hlg)
+      types.emplace_back(ui::Hdr::HLG);
+  }
+}
+
+void LibdisplayEdidWrapper::GetHdrCapabilities(
+    std::vector<ui::Hdr> &types, const float *max_luminance,
+    const float *max_average_luminance, const float *min_luminance) {
+  GetSupportedHdrTypes(types);
+
+  const auto *hdr_static_meta = di_info_get_hdr_static_metadata(info_);
+  max_luminance = &hdr_static_meta->desired_content_max_luminance;
+  max_average_luminance = &hdr_static_meta
+                               ->desired_content_max_frame_avg_luminance;
+  min_luminance = &hdr_static_meta->desired_content_min_luminance;
+}
+
+}  // namespace android
+#endif