ANDROID: 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.
Bug: 374183675
Test: Presubmit
Change-Id: I897e0b42e0065a61ecfe28c280094b6c375d8a72
Signed-off-by: Sasha McIntosh <sashamcintosh@google.com>
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index 16d8bac..be861e4 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -283,6 +283,43 @@
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) {
@@ -317,6 +354,8 @@
}
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,
@@ -825,6 +864,7 @@
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) {
@@ -855,6 +895,7 @@
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 = 0;
GetDisplayVsyncPeriod(&prev_vperiod_ns);
@@ -1017,6 +1058,8 @@
staged_mode_change_time_ = change_time;
staged_mode_config_id_ = config;
+ if (const HwcDisplayConfig *new_config = GetConfig(config))
+ SetOutputType(new_config->output_type);
return HWC2::Error::None;
}
@@ -1084,38 +1127,24 @@
switch (mode) {
case HAL_COLOR_MODE_NATIVE:
- hdr_metadata_.reset();
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_.reset();
// 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_.reset();
colorspace_ = Colorspace::kBt709Ycc;
break;
case HAL_COLOR_MODE_DCI_P3:
case HAL_COLOR_MODE_DISPLAY_P3:
- hdr_metadata_.reset();
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: