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:
parent
7472126b18
commit
447858ca48
9 changed files with 73 additions and 16 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue