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