sdm: drm: Set HDR metadata to sink

Set HDR metadata to sink for HDR playback support.

CRs-Fixed: 2143509
Change-Id: I6e7021c6cda7cd32efe3fc6d88f6322762477a17
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index f93825d..6ff192e 100644
--- a/libdrmutils/drm_interface.h
+++ b/libdrmutils/drm_interface.h
@@ -304,6 +304,12 @@
    *      uint32_t - CRTC ID
    */
   CONNECTOR_SET_CRTC,
+  /*
+   * Op: Sets connector hdr metadata
+   * Arg: uint32_t - Connector ID
+   *      drm_msm_ext_hdr_metadata - hdr_metadata
+   */
+  CONNECTOR_SET_HDR_METADATA,
 };
 
 enum struct DRMRotation {
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index 9081427..bd6864c 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -41,6 +41,12 @@
 #include <map>
 #include <utility>
 
+#ifndef HDR_EOTF_SMTPE_ST2084
+#define HDR_EOTF_SMTPE_ST2084 2
+#endif
+#ifndef HDR_EOTF_HLG
+#define HDR_EOTF_HLG 3
+#endif
 
 #define __CLASS__ "HWTVDRM"
 
@@ -60,6 +66,23 @@
 
 namespace sdm {
 
+static int32_t GetEOTF(const GammaTransfer &transfer) {
+  int32_t hdr_transfer = -1;
+
+  switch (transfer) {
+  case Transfer_SMPTE_ST2084:
+    hdr_transfer = HDR_EOTF_SMTPE_ST2084;
+    break;
+  case Transfer_HLG:
+    hdr_transfer = HDR_EOTF_HLG;
+    break;
+  default:
+    DLOGW("Unknown Transfer: %d", transfer);
+  }
+
+  return hdr_transfer;
+}
+
 HWTVDRM::HWTVDRM(BufferSyncHandler *buffer_sync_handler, BufferAllocator *buffer_allocator,
                      HWInfoInterface *hw_info_intf)
   : HWDeviceDRM(buffer_sync_handler, buffer_allocator, hw_info_intf) {
@@ -164,5 +187,67 @@
         hw_panel_info_.average_luminance);
 }
 
+DisplayError HWTVDRM::Commit(HWLayers *hw_layers) {
+  DisplayError error = UpdateHDRMetaData(hw_layers);
+  if (error != kErrorNone) {
+    return error;
+  }
+  return HWDeviceDRM::Commit(hw_layers);
+}
+
+DisplayError HWTVDRM::UpdateHDRMetaData(HWLayers *hw_layers) {
+  const HWHDRLayerInfo &hdr_layer_info = hw_layers->info.hdr_layer_info;
+  if (!hw_panel_info_.hdr_enabled || hdr_layer_info.operation == HWHDRLayerInfo::kNoOp) {
+    return kErrorNone;
+  }
+
+  DisplayError error = kErrorNone;
+
+  Layer hdr_layer = {};
+  if (hdr_layer_info.operation == HWHDRLayerInfo::kSet && hdr_layer_info.layer_index > -1) {
+    hdr_layer = *(hw_layers->info.stack->layers.at(UINT32(hdr_layer_info.layer_index)));
+  }
+
+  const LayerBuffer *layer_buffer = &hdr_layer.input_buffer;
+  const MasteringDisplay &mastering_display = layer_buffer->color_metadata.masteringDisplayInfo;
+  const ContentLightLevel &light_level = layer_buffer->color_metadata.contentLightLevel;
+  const Primaries &primaries = mastering_display.primaries;
+
+  if (hdr_layer_info.operation == HWHDRLayerInfo::kSet) {
+    int32_t eotf = GetEOTF(layer_buffer->color_metadata.transfer);
+    hdr_metadata_.hdr_supported = 1;
+    hdr_metadata_.eotf = (eotf < 0) ? 0 : UINT32(eotf);
+    hdr_metadata_.white_point_x = primaries.whitePoint[0];
+    hdr_metadata_.white_point_y = primaries.whitePoint[1];
+    hdr_metadata_.display_primaries_x[0] = primaries.rgbPrimaries[0][0];
+    hdr_metadata_.display_primaries_y[0] = primaries.rgbPrimaries[0][1];
+    hdr_metadata_.display_primaries_x[1] = primaries.rgbPrimaries[1][0];
+    hdr_metadata_.display_primaries_y[1] = primaries.rgbPrimaries[1][1];
+    hdr_metadata_.display_primaries_x[2] = primaries.rgbPrimaries[2][0];
+    hdr_metadata_.display_primaries_y[2] = primaries.rgbPrimaries[2][1];
+    hdr_metadata_.min_luminance = mastering_display.minDisplayLuminance;
+    hdr_metadata_.max_luminance = mastering_display.maxDisplayLuminance/10000;
+    hdr_metadata_.max_content_light_level = light_level.maxContentLightLevel;
+    hdr_metadata_.max_average_light_level = light_level.minPicAverageLightLevel;
+
+    drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_HDR_METADATA, token_.conn_id, &hdr_metadata_);
+    DumpHDRMetaData(hdr_layer_info.operation);
+  }
+
+  return error;
+}
+
+void HWTVDRM::DumpHDRMetaData(HWHDRLayerInfo::HDROperation operation) {
+  DLOGI("Operation = %d, HDR Metadata: MaxDisplayLuminance = %d MinDisplayLuminance = %d\n"
+        "MaxContentLightLevel = %d MaxAverageLightLevel = %d Red_x = %d Red_y = %d Green_x = %d\n"
+        "Green_y = %d Blue_x = %d Blue_y = %d WhitePoint_x = %d WhitePoint_y = %d EOTF = %d\n",
+        operation, hdr_metadata_.max_luminance, hdr_metadata_.min_luminance,
+        hdr_metadata_.max_content_light_level, hdr_metadata_.max_average_light_level,
+        hdr_metadata_.display_primaries_x[0], hdr_metadata_.display_primaries_y[0],
+        hdr_metadata_.display_primaries_x[1], hdr_metadata_.display_primaries_y[1],
+        hdr_metadata_.display_primaries_x[2], hdr_metadata_.display_primaries_y[2],
+        hdr_metadata_.white_point_x, hdr_metadata_.white_point_y, hdr_metadata_.eotf);
+}
+
 }  // namespace sdm
 
diff --git a/sdm/libs/core/drm/hw_tv_drm.h b/sdm/libs/core/drm/hw_tv_drm.h
index ec09862..5661bc2 100644
--- a/sdm/libs/core/drm/hw_tv_drm.h
+++ b/sdm/libs/core/drm/hw_tv_drm.h
@@ -46,11 +46,16 @@
   virtual DisplayError Doze();
   virtual DisplayError DozeSuspend();
   virtual DisplayError Standby();
+  virtual DisplayError Commit(HWLayers *hw_layers);
   virtual void PopulateHWPanelInfo();
 
  private:
+  DisplayError UpdateHDRMetaData(HWLayers *hw_layers);
+  void DumpHDRMetaData(HWHDRLayerInfo::HDROperation operation);
+
   static const int kBitRGB  = 20;
   static const int kBitYUV  = 21;
+  drm_msm_ext_hdr_metadata hdr_metadata_ = {};
 };
 
 }  // namespace sdm