1
0
Fork 0

drm_hwcomposer: 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.

Change-Id: I897e0b42e0065a61ecfe28c280094b6c375d8a72
Signed-off-by: Sasha McIntosh <sashamcintosh@google.com>
This commit is contained in:
Sasha McIntosh 2024-11-07 14:40:45 -05:00
parent 7472126b18
commit 447858ca48
9 changed files with 73 additions and 16 deletions

View file

@ -170,6 +170,43 @@ auto HwcDisplay::GetLastRequestedConfig() const -> const HwcDisplayConfig * {
return GetConfig(staged_mode_config_id_.value_or(configs_.active_config_id));
}
HWC2::Error HwcDisplay::SetOutputType(uint32_t hdr_output_type) {
switch (hdr_output_type) {
case 3: { // HDR10
auto ret = SetHdrOutputMetadata(ui::Hdr::HDR10);
if (ret != HWC2::Error::None)
return ret;
min_bpc_ = 8;
colorspace_ = Colorspace::kBt2020Rgb;
break;
}
case 1: { // SYSTEM
std::vector<ui::Hdr> hdr_types;
GetEdid()->GetSupportedHdrTypes(hdr_types);
if (!hdr_types.empty()) {
auto ret = SetHdrOutputMetadata(hdr_types.front());
if (ret != HWC2::Error::None)
return ret;
min_bpc_ = 8;
colorspace_ = Colorspace::kBt2020Rgb;
break;
} else {
[[fallthrough]];
}
}
case 0: // INVALID
[[fallthrough]];
case 2: // SDR
[[fallthrough]];
default:
hdr_metadata_.reset();
min_bpc_ = 6;
colorspace_ = Colorspace::kDefault;
}
return HWC2::Error::None;
}
HwcDisplay::ConfigError HwcDisplay::SetConfig(hwc2_config_t config) {
const HwcDisplayConfig *new_config = GetConfig(config);
if (new_config == nullptr) {
@ -217,6 +254,8 @@ HwcDisplay::ConfigError HwcDisplay::SetConfig(hwc2_config_t config) {
}
ALOGV("Create modeset commit.");
SetOutputType(new_config->output_type);
// Create atomic commit args for a blocking modeset. There's no need to do a
// separate test commit, since the commit does a test anyways.
AtomicCommitArgs commit_args = CreateModesetCommit(new_config,
@ -679,6 +718,7 @@ AtomicCommitArgs HwcDisplay::CreateModesetCommit(
args.content_type = content_type_;
args.colorspace = colorspace_;
args.hdr_metadata = hdr_metadata_;
args.min_bpc = min_bpc_;
std::vector<LayerData> composition_layers;
if (modeset_layer) {
@ -751,6 +791,7 @@ HWC2::Error HwcDisplay::CreateComposition(AtomicCommitArgs &a_args) {
a_args.content_type = content_type_;
a_args.colorspace = colorspace_;
a_args.hdr_metadata = hdr_metadata_;
a_args.min_bpc = min_bpc_;
uint32_t prev_vperiod_ns = GetCurrentVsyncPeriodNs();
std::optional<uint32_t> new_vsync_period_ns;
@ -896,38 +937,24 @@ HWC2::Error HwcDisplay::SetColorMode(int32_t mode) {
switch (mode) {
case HAL_COLOR_MODE_NATIVE:
hdr_metadata_ = std::make_shared<hdr_output_metadata>();
colorspace_ = Colorspace::kDefault;
break;
case HAL_COLOR_MODE_STANDARD_BT601_625:
case HAL_COLOR_MODE_STANDARD_BT601_625_UNADJUSTED:
case HAL_COLOR_MODE_STANDARD_BT601_525:
case HAL_COLOR_MODE_STANDARD_BT601_525_UNADJUSTED:
hdr_metadata_ = std::make_shared<hdr_output_metadata>();
// The DP spec does not say whether this is the 525 or the 625 line version.
colorspace_ = Colorspace::kBt601Ycc;
break;
case HAL_COLOR_MODE_STANDARD_BT709:
case HAL_COLOR_MODE_SRGB:
hdr_metadata_ = std::make_shared<hdr_output_metadata>();
colorspace_ = Colorspace::kBt709Ycc;
break;
case HAL_COLOR_MODE_DCI_P3:
case HAL_COLOR_MODE_DISPLAY_P3:
hdr_metadata_ = std::make_shared<hdr_output_metadata>();
colorspace_ = Colorspace::kDciP3RgbD65;
break;
case HAL_COLOR_MODE_DISPLAY_BT2020: {
std::vector<ui::Hdr> hdr_types;
GetEdid()->GetSupportedHdrTypes(hdr_types);
if (!hdr_types.empty()) {
auto ret = SetHdrOutputMetadata(hdr_types.front());
if (ret != HWC2::Error::None)
return ret;
}
colorspace_ = Colorspace::kBt2020Rgb;
break;
}
case HAL_COLOR_MODE_DISPLAY_BT2020:
case HAL_COLOR_MODE_ADOBE_RGB:
case HAL_COLOR_MODE_BT2020:
case HAL_COLOR_MODE_BT2100_PQ:

View file

@ -271,6 +271,7 @@ class HwcDisplay {
bool ctm_has_offset_ = false;
ContentType content_type_ = ContentType::kNoData;
Colorspace colorspace_{};
int32_t min_bpc_{};
std::shared_ptr<hdr_output_metadata> hdr_metadata_;
std::shared_ptr<DrmKmsPlan> current_plan_;
@ -285,6 +286,8 @@ class HwcDisplay {
bool Init();
HWC2::Error SetHdrOutputMetadata(ui::Hdr hdrType);
HWC2::Error SetOutputType(uint32_t hdr_output_type);
auto GetEdid() -> EdidWrapperUnique & {
return GetPipe().connector->Get()->GetParsedEdid();
}

View file

@ -147,6 +147,7 @@ bool HwcDisplayConfigs::Update(DrmConnector &connector) {
.group_id = group_found,
.mode = mode,
.disabled = disabled,
.output_type = 1, // OutputType::SYSTEM
};
/* Chwck if the mode is preferred */

View file

@ -29,6 +29,7 @@ struct HwcDisplayConfig {
uint32_t group_id{};
DrmMode mode{};
bool disabled{};
uint32_t output_type{};
bool IsInterlaced() const {
return (mode.GetRawMode().flags & DRM_MODE_FLAG_INTERLACE) != 0;