Merge "gralloc1: Add support for P010 usage flag"
diff --git a/libdrmutils/drm_interface.h b/libdrmutils/drm_interface.h
index 6bf7f97..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 {
@@ -370,6 +376,7 @@
/* Per CRTC Resource Info*/
struct DRMCrtcInfo {
bool has_src_split;
+ bool has_hdr;
uint32_t max_blend_stages;
uint32_t max_solidfill_stages;
QSEEDVersion qseed_version;
@@ -476,6 +483,7 @@
DRMRotation panel_orientation;
drm_panel_hdr_properties panel_hdr_prop;
uint32_t transfer_time_us;
+ drm_msm_ext_hdr_properties ext_hdr_prop;
};
/* Identifier token for a display */
diff --git a/sdm/include/core/display_interface.h b/sdm/include/core/display_interface.h
index 92efd9f..303c89b 100644
--- a/sdm/include/core/display_interface.h
+++ b/sdm/include/core/display_interface.h
@@ -153,6 +153,8 @@
bool secure = false; //!< If this display is capable of handling secure content.
bool is_cmdmode = false; //!< If panel is command mode panel.
bool hdr_supported = false; //!< if HDR is enabled
+ bool hdr_metadata_type_one = false; //!< Metadata type one obtained from HDR sink
+ uint32_t hdr_eotf = 0; //!< Electro optical transfer function
uint32_t max_luminance = 0; //!< From Panel's peak luminance
uint32_t average_luminance = 0; //!< From Panel's average luminance
uint32_t min_luminance = 0; //!< From Panel's blackness level
diff --git a/sdm/include/private/hw_info_types.h b/sdm/include/private/hw_info_types.h
index 9f6a5d6..b086907 100644
--- a/sdm/include/private/hw_info_types.h
+++ b/sdm/include/private/hw_info_types.h
@@ -292,6 +292,8 @@
uint32_t left_roi_count = 1; // Number if ROI supported on left panel
uint32_t right_roi_count = 1; // Number if ROI supported on right panel
bool hdr_enabled = false; // HDR feature supported
+ bool hdr_metadata_type_one = false; // Static HDR metadata type one
+ uint32_t hdr_eotf = 0; // Electro optical transfer function
uint32_t peak_luminance = 0; // Panel's peak luminance level
uint32_t average_luminance = 0; // Panel's average luminance level
uint32_t blackness_level = 0; // Panel's blackness level
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index 1e948a2..5c5a45a 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -400,6 +400,8 @@
fixed_info->max_luminance = fixed_info->hdr_supported ? hw_panel_info_.peak_luminance: 0;
fixed_info->average_luminance = fixed_info->hdr_supported ? hw_panel_info_.average_luminance : 0;
fixed_info->min_luminance = fixed_info->hdr_supported ? hw_panel_info_.blackness_level: 0;
+ fixed_info->hdr_eotf = hw_panel_info_.hdr_eotf;
+ fixed_info->hdr_metadata_type_one = hw_panel_info_.hdr_metadata_type_one;
return kErrorNone;
}
diff --git a/sdm/libs/core/drm/hw_device_drm.h b/sdm/libs/core/drm/hw_device_drm.h
index 16355c8..5b7576a 100644
--- a/sdm/libs/core/drm/hw_device_drm.h
+++ b/sdm/libs/core/drm/hw_device_drm.h
@@ -97,6 +97,7 @@
virtual DisplayError GetMixerAttributes(HWMixerAttributes *mixer_attributes);
virtual void InitializeConfigs();
virtual DisplayError DumpDebugData() { return kErrorNone; }
+ virtual void PopulateHWPanelInfo();
enum {
kHWEventVSync,
@@ -113,7 +114,6 @@
DisplayError SetStride(HWDeviceType device_type, LayerBufferFormat format, uint32_t width,
uint32_t *target);
DisplayError PopulateDisplayAttributes(uint32_t index);
- void PopulateHWPanelInfo();
void GetHWDisplayPortAndMode();
void GetHWPanelMaxBrightness();
bool EnableHotPlugDetection(int enable);
diff --git a/sdm/libs/core/drm/hw_info_drm.cpp b/sdm/libs/core/drm/hw_info_drm.cpp
index 1f31727..b4c1d37 100644
--- a/sdm/libs/core/drm/hw_info_drm.cpp
+++ b/sdm/libs/core/drm/hw_info_drm.cpp
@@ -191,7 +191,6 @@
hw_resource->has_dyn_bw_support = false;
hw_resource->has_qseed3 = false;
hw_resource->has_concurrent_writeback = false;
- hw_resource->has_hdr = true;
hw_resource->hw_version = SDEVERSION(4, 0, 1);
// TODO(user): On FB driver hw_revision comprises of major version, minor version and hw_revision.
@@ -278,6 +277,7 @@
void HWInfoDRM::GetSystemInfo(HWResourceInfo *hw_resource) {
DRMCrtcInfo info;
drm_mgr_intf_->GetCrtcInfo(0 /* system_info */, &info);
+ hw_resource->has_hdr = info.has_hdr;
hw_resource->is_src_split = info.has_src_split;
hw_resource->has_qseed3 = (info.qseed_version == sde_drm::QSEEDVersion::V3);
hw_resource->num_blending_stages = info.max_blend_stages;
diff --git a/sdm/libs/core/drm/hw_tv_drm.cpp b/sdm/libs/core/drm/hw_tv_drm.cpp
index 565652e..f1d0d80 100644
--- a/sdm/libs/core/drm/hw_tv_drm.cpp
+++ b/sdm/libs/core/drm/hw_tv_drm.cpp
@@ -28,6 +28,7 @@
*/
#include "hw_tv_drm.h"
+#include <sys/time.h>
#include <utils/debug.h>
#include <utils/sys.h>
#include <utils/formats.h>
@@ -41,9 +42,19 @@
#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"
+#define HDR_DISABLE 0
+#define HDR_ENABLE 1
+#define MIN_HDR_RESET_WAITTIME 2
+
using drm_utils::DRMMaster;
using drm_utils::DRMResMgr;
using drm_utils::DRMLibLoader;
@@ -60,6 +71,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) {
@@ -148,5 +176,119 @@
return kErrorNone;
}
+void HWTVDRM::PopulateHWPanelInfo() {
+ hw_panel_info_ = {};
+
+ HWDeviceDRM::PopulateHWPanelInfo();
+ hw_panel_info_.hdr_enabled = connector_info_.ext_hdr_prop.hdr_supported;
+ hw_panel_info_.hdr_metadata_type_one = connector_info_.ext_hdr_prop.hdr_metadata_type_one;
+ hw_panel_info_.hdr_eotf = connector_info_.ext_hdr_prop.hdr_eotf;
+ hw_panel_info_.peak_luminance = connector_info_.ext_hdr_prop.hdr_max_luminance;
+ hw_panel_info_.average_luminance = connector_info_.ext_hdr_prop.hdr_avg_luminance;
+ hw_panel_info_.blackness_level = connector_info_.ext_hdr_prop.hdr_min_luminance;
+ DLOGI("TV Panel: %s, type_one = %d, eotf = %d, luminance[max = %d, min = %d, avg = %d]",
+ hw_panel_info_.hdr_enabled ? "HDR" : "Non-HDR", hw_panel_info_.hdr_metadata_type_one,
+ hw_panel_info_.hdr_eotf, hw_panel_info_.peak_luminance, hw_panel_info_.blackness_level,
+ 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) {
+ static struct timeval hdr_reset_start, hdr_reset_end;
+ static bool reset_hdr_flag = false;
+ const HWHDRLayerInfo &hdr_layer_info = hw_layers->info.hdr_layer_info;
+ if (!hw_panel_info_.hdr_enabled) {
+ 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) {
+ // Reset reset_hdr_flag to handle where there are two consecutive HDR video playbacks with not
+ // enough non-HDR frames in between to reset the HDR metadata.
+ reset_hdr_flag = false;
+
+ int32_t eotf = GetEOTF(layer_buffer->color_metadata.transfer);
+ hdr_metadata_.hdr_supported = 1;
+ hdr_metadata_.hdr_state = HDR_ENABLE;
+ 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);
+ } else if (hdr_layer_info.operation == HWHDRLayerInfo::kReset) {
+ memset(&hdr_metadata_, 0, sizeof(hdr_metadata_));
+ hdr_metadata_.hdr_supported = 1;
+ hdr_metadata_.hdr_state = HDR_ENABLE;
+ reset_hdr_flag = true;
+ gettimeofday(&hdr_reset_start, NULL);
+
+ drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_HDR_METADATA, token_.conn_id, &hdr_metadata_);
+ DumpHDRMetaData(hdr_layer_info.operation);
+ } else if (hdr_layer_info.operation == HWHDRLayerInfo::kNoOp) {
+ // TODO(user): This case handles the state transition from HDR_ENABLED to HDR_DISABLED.
+ // As per HDMI spec requirement, we need to send zero metadata for atleast 2 sec after end of
+ // playback. This timer calculates the 2 sec window after playback stops to stop sending HDR
+ // metadata. This will be replaced with an idle timer implementation in the future.
+ if (reset_hdr_flag) {
+ gettimeofday(&hdr_reset_end, NULL);
+ float hdr_reset_time_start = ((hdr_reset_start.tv_sec*1000) + (hdr_reset_start.tv_usec/1000));
+ float hdr_reset_time_end = ((hdr_reset_end.tv_sec*1000) + (hdr_reset_end.tv_usec/1000));
+
+ if (((hdr_reset_time_end-hdr_reset_time_start)/1000) >= MIN_HDR_RESET_WAITTIME) {
+ memset(&hdr_metadata_, 0, sizeof(hdr_metadata_));
+ hdr_metadata_.hdr_supported = 1;
+ hdr_metadata_.hdr_state = HDR_DISABLE;
+ reset_hdr_flag = false;
+
+ drm_atomic_intf_->Perform(DRMOps::CONNECTOR_SET_HDR_METADATA, token_.conn_id,
+ &hdr_metadata_);
+ }
+ }
+ }
+
+ 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 54ce327..5661bc2 100644
--- a/sdm/libs/core/drm/hw_tv_drm.h
+++ b/sdm/libs/core/drm/hw_tv_drm.h
@@ -46,10 +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
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index c846771..e5576f7 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -462,6 +462,9 @@
bool secure_display_active = false;
layer_stack_.flags.animating = animating_;
+ uint32_t color_mode_count = 0;
+ display_intf_->GetColorModeCount(&color_mode_count);
+
// Add one layer for fb target
// TODO(user): Add blit target layers
for (auto hwc_layer : layer_set_) {
@@ -534,7 +537,7 @@
bool hdr_layer = layer->input_buffer.color_metadata.colorPrimaries == ColorPrimaries_BT2020 &&
(layer->input_buffer.color_metadata.transfer == Transfer_SMPTE_ST2084 ||
layer->input_buffer.color_metadata.transfer == Transfer_HLG);
- if (hdr_layer && !disable_hdr_handling_) {
+ if (hdr_layer && !disable_hdr_handling_ && color_mode_count) {
// dont honor HDR when its handling is disabled
layer->input_buffer.flags.hdr = true;
layer_stack_.flags.hdr_present = true;