Merge "sdm: Avoid looping over event data list when registering events"
diff --git a/config/msmnile.mk b/config/msmnile.mk
old mode 100755
new mode 100644
index 840e8cf..e97dc73
--- a/config/msmnile.mk
+++ b/config/msmnile.mk
@@ -29,10 +29,11 @@
TARGET_USES_DRM_PP := true
TARGET_FORCE_HWC_FOR_VIRTUAL_DISPLAYS := true
MAX_VIRTUAL_DISPLAY_DIMENSION := 4096
-NUM_FRAMEBUFFER_SURFACE_BUFFERS := 2
+NUM_FRAMEBUFFER_SURFACE_BUFFERS := 3
TARGET_USES_HWC2 := true
TARGET_USES_QCOM_DISPLAY_BSP := true
TARGET_USES_COLOR_METADATA := true
+TARGET_HAS_WIDE_COLOR_DISPLAY := true
PRODUCT_PROPERTY_OVERRIDES += \
persist.demo.hdmirotationlock=false \
@@ -46,8 +47,17 @@
vendor.gralloc.disable_ubwc=0 \
vendor.display.disable_scaler=0 \
vendor.display.disable_inline_rotator=1 \
+ vendor.display.disable_decimation=1 \
vendor.display.enable_null_display=0 \
vendor.display.disable_excl_rect=0 \
vendor.display.comp_mask=0 \
- vendor.display.disable_hw_recovery=1 \
+ vendor.display.disable_hw_recovery=0 \
vendor.display.enable_default_color_mode=1
+ vendor.display.disable_hw_recovery=1
+
+# This matrix should be in column major order, per SurfaceFlinger requirement
+# 1.16868 -0.16868 0.00000
+# -0.03155 1.03155 0.00000
+# -0.01473 -0.05899 1.07372
+PRODUCT_PROPERTY_OVERRIDES += \
+ vendor.display.dataspace_saturation_matrix=1.16868,-0.03155,-0.01473,-0.16868,1.03155,-0.05899,0.00000,0.00000,1.07372
diff --git a/include/display_properties.h b/include/display_properties.h
index ef440cd..c321b98 100644
--- a/include/display_properties.h
+++ b/include/display_properties.h
@@ -99,6 +99,7 @@
#define DISABLE_HDR_LUT_GEN DISPLAY_PROP("disable_hdr_lut_gen")
#define ENABLE_DEFAULT_COLOR_MODE DISPLAY_PROP("enable_default_color_mode")
#define DISABLE_HDR DISPLAY_PROP("hwc_disable_hdr")
+#define DATASPACE_SATURATION_MATRIX_PROP DISPLAY_PROP("dataspace_saturation_matrix")
#define HDR_CONFIG_PROP RO_DISPLAY_PROP("hdr.config")
#define QDCM_PCC_TRANS_PROP DISPLAY_PROP("qdcm.pcc_for_trans")
diff --git a/libqservice/IQService.h b/libqservice/IQService.h
index bbbaf3a..d392e12 100644
--- a/libqservice/IQService.h
+++ b/libqservice/IQService.h
@@ -78,6 +78,7 @@
SET_COLOR_MODE_BY_ID = 36, // Overrides the QDCM mode using the given mode ID
GET_COMPOSER_STATUS = 37, // Get composer init status-true if primary display init is done
SET_QSYNC_MODE = 38, // Set qsync mode. 0 - (none)disable qsync, 1 - continuous mode.
+ SET_COLOR_MODE_WITH_RENDER_INTENT = 39,
COMMAND_LIST_END = 400,
};
diff --git a/sdm/include/private/color_params.h b/sdm/include/private/color_params.h
index dbe7a97..32f0505 100644
--- a/sdm/include/private/color_params.h
+++ b/sdm/include/private/color_params.h
@@ -84,6 +84,7 @@
static const std::string kDynamicRangeAttribute = "DynamicRange";
static const std::string kColorGamutAttribute = "ColorGamut";
static const std::string kPictureQualityAttribute = "PictureQuality";
+static const std::string kGammaTransferAttribute = "GammaTransfer";
static const std::string kHdr = "hdr";
static const std::string kSdr = "sdr";
@@ -92,12 +93,18 @@
static const std::string kDcip3 = "dcip3";
static const std::string kSrgb = "srgb";
static const std::string kDisplayP3 = "display_p3";
+static const std::string kBt2020 = "bt2020";
+
+static const std::string kHlg = "hlg";
+static const std::string kSt2084 = "st2084";
+static const std::string kGamma2_2 = "gamma2_2";
static const std::string kVivid = "vivid";
static const std::string kSharp = "sharp";
static const std::string kStandard = "standard";
static const std::string kAmazon = "amazon";
static const std::string kNetflix = "netflix";
+static const std::string kEnhanced = "enhanced";
// Enum to identify type of dynamic range of color mode.
enum DynamicRangeType {
diff --git a/sdm/include/private/strategy_interface.h b/sdm/include/private/strategy_interface.h
index 8b5455a..3f1b9ab 100644
--- a/sdm/include/private/strategy_interface.h
+++ b/sdm/include/private/strategy_interface.h
@@ -56,6 +56,7 @@
virtual DisplayError SetIdleTimeoutMs(uint32_t active_ms) = 0;
/* Sets the list of color modes supported on a display */
virtual DisplayError SetColorModesInfo(const std::vector<PrimariesTransfer> &colormodes_cs) = 0;
+ virtual DisplayError SetBlendSpace(const PrimariesTransfer &blend_space) = 0;
virtual ~StrategyInterface() { }
};
diff --git a/sdm/libs/core/comp_manager.cpp b/sdm/libs/core/comp_manager.cpp
index 05c6ba4..838de0c 100644
--- a/sdm/libs/core/comp_manager.cpp
+++ b/sdm/libs/core/comp_manager.cpp
@@ -587,4 +587,13 @@
return displays_str.c_str();
}
+DisplayError CompManager::SetBlendSpace(Handle display_ctx, const PrimariesTransfer &blend_space) {
+ DisplayCompositionContext *display_comp_ctx =
+ reinterpret_cast<DisplayCompositionContext *>(display_ctx);
+
+ display_comp_ctx->strategy->SetBlendSpace(blend_space);
+
+ return kErrorNone;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/comp_manager.h b/sdm/libs/core/comp_manager.h
index 2a24dc1..5814a67 100644
--- a/sdm/libs/core/comp_manager.h
+++ b/sdm/libs/core/comp_manager.h
@@ -80,6 +80,7 @@
DisplayError ControlDpps(bool enable);
DisplayError SetColorModesInfo(Handle display_ctx,
const std::vector<PrimariesTransfer> &colormodes_cs);
+ DisplayError SetBlendSpace(Handle display_ctx, const PrimariesTransfer &blend_space);
private:
static const int kMaxThermalLevel = 3;
diff --git a/sdm/libs/core/display_base.cpp b/sdm/libs/core/display_base.cpp
index cc6c215..5a7a838 100644
--- a/sdm/libs/core/display_base.cpp
+++ b/sdm/libs/core/display_base.cpp
@@ -91,6 +91,11 @@
DisplayError error = kErrorNone;
hw_panel_info_ = HWPanelInfo();
hw_intf_->GetHWPanelInfo(&hw_panel_info_);
+ if (hw_info_intf_) {
+ hw_info_intf_->GetHWResourceInfo(&hw_resource_info_);
+ }
+ auto max_mixer_stages = hw_resource_info_.num_blending_stages;
+ int property_value = Debug::GetMaxPipesPerMixer(display_type_);
uint32_t active_index = 0;
hw_intf_->GetActiveConfig(&active_index);
@@ -148,15 +153,10 @@
}
}
- if (hw_info_intf_) {
- hw_info_intf_->GetHWResourceInfo(&hw_resource_info_);
- auto max_mixer_stages = hw_resource_info_.num_blending_stages;
- int property_value = Debug::GetMaxPipesPerMixer(display_type_);
- if (property_value >= 0) {
- max_mixer_stages = std::min(UINT32(property_value), hw_resource_info_.num_blending_stages);
- }
- DisplayBase::SetMaxMixerStages(max_mixer_stages);
+ if (property_value >= 0) {
+ max_mixer_stages = std::min(UINT32(property_value), hw_resource_info_.num_blending_stages);
}
+ DisplayBase::SetMaxMixerStages(max_mixer_stages);
Debug::GetProperty(DISABLE_HDR_LUT_GEN, &disable_hdr_lut_gen_);
// TODO(user): Temporary changes, to be removed when DRM driver supports
@@ -289,12 +289,6 @@
return error;
}
- error = HandleHDR(layer_stack);
- if (error != kErrorNone) {
- DLOGW("HandleHDR failed");
- return error;
- }
-
if (color_mgr_ && color_mgr_->NeedsPartialUpdateDisable()) {
DisablePartialUpdateOneFrame();
}
@@ -327,16 +321,7 @@
comp_manager_->PostPrepare(display_comp_ctx_, &hw_layers_);
- if (error != kErrorNone) {
- return error;
- }
-
- error = ValidateHDR(layer_stack);
- if (error != kErrorNone) {
- DLOGW("ValidateHDR failed");
- }
-
- DLOGI_IF(kTagDisplay, "Exiting Prepare for display: %d-%d", display_id_, display_type_);
+ DLOGI_IF(kTagDisplay, "Exiting Prepare for display type : %d error: %d", display_type_, error);
return error;
}
@@ -841,11 +826,11 @@
if (!color_mgr_) {
return kErrorNotSupported;
}
-
- for (uint32_t i = 0; i < num_color_modes_; i++) {
- DLOGV_IF(kTagQDCM, "Color Mode[%d]: Name = %s mode_id = %d", i, color_modes_[i].name,
- color_modes_[i].id);
- color_modes->at(i) = color_modes_[i].name;
+ uint32_t i = 0;
+ for (ColorModeAttrMap::iterator it = color_mode_attr_map_.begin();
+ ((i < num_color_modes_) && (it != color_mode_attr_map_.end())); i++, it++) {
+ DLOGI("ColorMode name = %s", it->first.c_str());
+ color_modes->at(i) = it->first.c_str();
}
return kErrorNone;
@@ -877,59 +862,26 @@
return kErrorNotSupported;
}
- DynamicRangeType dynamic_range_type;
- if (IsSupportColorModeAttribute(color_mode)) {
- auto it_mode = color_mode_attr_map_.find(color_mode);
- std::string dynamic_range;
- GetValueOfModeAttribute(it_mode->second, kDynamicRangeAttribute, &dynamic_range);
- if (dynamic_range == kHdr) {
- dynamic_range_type = kHdrType;
- } else {
- dynamic_range_type = kSdrType;
- }
- } else {
- if (color_mode.find("hal_hdr") != std::string::npos) {
- dynamic_range_type = kHdrType;
- } else {
- dynamic_range_type = kSdrType;
- }
- }
-
DisplayError error = kErrorNone;
- if (disable_hdr_lut_gen_) {
- error = SetColorModeInternal(color_mode);
- if (error != kErrorNone) {
- return error;
- }
- // Store the new SDR color mode request by client
- if (dynamic_range_type == kSdrType) {
- current_color_mode_ = color_mode;
- }
+ error = SetColorModeInternal(color_mode);
+ if (error != kErrorNone) {
return error;
}
- if (hdr_playback_) {
- // HDR playback on, If incoming mode is SDR mode,
- // cache the mode and apply it after HDR playback stop.
- if (dynamic_range_type == kHdrType) {
- error = SetColorModeInternal(color_mode);
- if (error != kErrorNone) {
- return error;
- }
- } else if (dynamic_range_type == kSdrType) {
- current_color_mode_ = color_mode;
- }
- } else {
- // HDR playback off, do not apply HDR mode
- if (dynamic_range_type == kHdrType) {
- DLOGE("Failed: Forbid setting HDR Mode : %s when HDR playback off", color_mode.c_str());
- return kErrorNotSupported;
- }
- error = SetColorModeInternal(color_mode);
- if (error != kErrorNone) {
- return error;
- }
- current_color_mode_ = color_mode;
+ std::string dynamic_range = kSdr;
+ if (IsSupportColorModeAttribute(color_mode)) {
+ auto it_mode = color_mode_attr_map_.find(color_mode);
+ GetValueOfModeAttribute(it_mode->second, kDynamicRangeAttribute, &dynamic_range);
+ }
+
+ comp_manager_->ControlDpps(dynamic_range != kHdr);
+
+ current_color_mode_ = color_mode;
+ PrimariesTransfer blend_space = {};
+ blend_space = GetBlendSpaceFromColorMode();
+ error = comp_manager_->SetBlendSpace(display_comp_ctx_, blend_space);
+ if (error != kErrorNone) {
+ DLOGE("SetBlendSpace failed, error = %d display_type_=%d", error, display_type_);
}
return error;
@@ -984,25 +936,6 @@
return true;
}
-DisplayError DisplayBase::GetHdrColorMode(std::string *color_mode, bool *found_hdr) {
- if (!found_hdr || !color_mode) {
- return kErrorParameters;
- }
- *found_hdr = false;
- // get the default HDR mode which is value of picture quality equal to "standard"
- for (auto &it_hdr : color_mode_attr_map_) {
- std::string dynamic_range, pic_quality;
- GetValueOfModeAttribute(it_hdr.second, kDynamicRangeAttribute, &dynamic_range);
- GetValueOfModeAttribute(it_hdr.second, kPictureQualityAttribute, &pic_quality);
- if (dynamic_range == kHdr && pic_quality == kStandard) {
- *color_mode = it_hdr.first;
- *found_hdr = true;
- }
- }
-
- return kErrorNone;
-}
-
DisplayError DisplayBase::SetColorTransform(const uint32_t length, const double *color_transform) {
lock_guard<recursive_mutex> obj(recursive_mutex_);
if (!color_mgr_) {
@@ -1554,6 +1487,13 @@
auto it = color_mode_attr_map_.find(color_modes_[i].name);
if (it == color_mode_attr_map_.end()) {
color_mode_attr_map_.insert(std::make_pair(color_modes_[i].name, var));
+ // If target doesn't support SSPP tone maping and color mode is HDR,
+ // add bt2020pq and bt2020hlg color modes.
+ if (hw_resource_info_.src_tone_map.none() && IsHdrMode(var)) {
+ color_mode_map_.insert(std::make_pair(kBt2020Pq, &color_modes_[i]));
+ color_mode_map_.insert(std::make_pair(kBt2020Hlg, &color_modes_[i]));
+ InsertBT2020PqHlgModes();
+ }
}
std::vector<PrimariesTransfer> pt_list = {};
GetColorPrimaryTransferFromAttributes(var, &pt_list);
@@ -1575,110 +1515,6 @@
return kErrorNone;
}
-DisplayError DisplayBase::SetHDRMode(bool set) {
- DisplayError error = kErrorNone;
- std::string color_mode = "";
-
- if (color_mgr_ && !disable_hdr_lut_gen_) {
- // Do not apply HDR Mode when hdr lut generation is disabled
- if (set) {
- color_mode = "hal_hdr";
- if (IsSupportColorModeAttribute(current_color_mode_)) {
- bool found_hdr = false;
- error = GetHdrColorMode(&color_mode, &found_hdr);
- if (!found_hdr) {
- color_mode = "hal_hdr";
- }
- }
- } else {
- // HDR playback off - set prev mode
- color_mode = current_color_mode_;
- }
- DLOGI("Setting color mode = %s", color_mode.c_str());
- error = SetColorModeInternal(color_mode);
- }
-
- comp_manager_->ControlDpps(!set);
- hdr_mode_ = set;
-
- return error;
-}
-
-DisplayError DisplayBase::HandleHDR(LayerStack *layer_stack) {
- DisplayError error = kErrorNone;
-
- if (!NeedsHdrHandling()) {
- return kErrorNone;
- }
-
- if (hw_layers_.info.wide_color_primaries.empty()) {
- // HDR playback off - set prev mode
- if (hdr_playback_) {
- hdr_playback_ = false;
- if (hdr_mode_) {
- error = SetHDRMode(false);
- }
- }
- } else {
- // set HDR mode on legacy targets only
- if (SetHdrModeAtStart(layer_stack)) {
- if (!hdr_playback_ && !layer_stack->flags.animating) {
- // hdr is starting
- hdr_playback_ = true;
- error = SetHDRMode(true);
- if (error != kErrorNone) {
- DLOGW("Failed to set HDR mode");
- }
- } else if (hdr_playback_ && !hdr_mode_) {
- error = SetHDRMode(true);
- if (error != kErrorNone) {
- DLOGW("Failed to set HDR mode");
- }
- }
- }
- }
-
- return error;
-}
-
-DisplayError DisplayBase::ValidateHDR(LayerStack *layer_stack) {
- DisplayError error = kErrorNone;
-
- if (!NeedsHdrHandling()) {
- return kErrorNone;
- }
-
- bool hdr_mode = false;
- bool set = false; // indicates if we need to call SetHDRMode
- if (hw_resource_info_.src_tone_map.any()) {
- if (!hw_layers_.info.wide_color_primaries.empty()) {
- hdr_playback_ = true;
- // Need to set HDR mode on target with SSPP only when blend cs is BT2020
- if (layer_stack->blend_cs.primaries == ColorPrimaries_BT2020 && !hdr_mode_) {
- hdr_mode = true;
- set = true;
- }
- }
- } else if (hdr_playback_) { // legacy targets
- // HDR color mode is set when hdr layer is present in layer_stack.
- // If client flags HDR layer as skipped, then blending happens
- // in SDR color space. Hence, need to restore the SDR color mode.
- if (layer_stack->blend_cs.primaries != ColorPrimaries_BT2020) {
- hdr_mode = false;
- set = true;
- }
- }
-
- if (set) {
- error = SetHDRMode(hdr_mode);
- if (error != kErrorNone) {
- DLOGW("Setting HDR Mode %d failed", hdr_mode);
- }
- }
-
- return kErrorNone;
-}
-
DisplayError DisplayBase::GetClientTargetSupport(uint32_t width, uint32_t height,
LayerBufferFormat format,
const ColorMetaData &color_metadata) {
@@ -1911,4 +1747,65 @@
return (hw_resource_info_.src_tone_map.none() && layer_stack->flags.hdr_present);
}
+PrimariesTransfer DisplayBase::GetBlendSpaceFromColorMode() {
+ PrimariesTransfer pt = {};
+ auto current_color_attr_ = color_mode_attr_map_.find(current_color_mode_);
+ AttrVal attr = current_color_attr_->second;
+ std::string color_gamut = kNative, dynamic_range = kSdr, pic_quality = kStandard;
+ std::string transfer = {};
+
+ for (auto &it : attr) {
+ if (it.first.find(kColorGamutAttribute) != std::string::npos) {
+ color_gamut = it.second;
+ } else if (it.first.find(kDynamicRangeAttribute) != std::string::npos) {
+ dynamic_range = it.second;
+ } else if (it.first.find(kPictureQualityAttribute) != std::string::npos) {
+ pic_quality = it.second;
+ } else if (it.first.find(kGammaTransferAttribute) != std::string::npos) {
+ transfer = it.second;
+ }
+ }
+ // TODO(user): Check is if someone calls with hal_display_p3
+ if (hw_resource_info_.src_tone_map.none() &&
+ (pic_quality == kStandard && color_gamut == kBt2020)) {
+ pt.primaries = GetColorPrimariesFromAttribute(color_gamut);
+ if (transfer == kHlg) {
+ pt.transfer = Transfer_HLG;
+ } else {
+ pt.transfer = Transfer_SMPTE_ST2084;
+ }
+ } else if ((color_gamut == kDcip3 && dynamic_range == kSdr)) {
+ pt.primaries = GetColorPrimariesFromAttribute(color_gamut);
+ pt.transfer = Transfer_Gamma2_2;
+ } else {
+ DLOGE("Invalid color mode: %s", current_color_mode_.c_str());
+ }
+
+ return pt;
+}
+
+void DisplayBase::InsertBT2020PqHlgModes() {
+ AttrVal hdr_var = {};
+ hdr_var.push_back(std::make_pair(kColorGamutAttribute, kBt2020));
+ hdr_var.push_back(std::make_pair(kPictureQualityAttribute, kStandard));
+ hdr_var.push_back(std::make_pair(kGammaTransferAttribute, kSt2084));
+ color_mode_attr_map_.insert(std::make_pair(kBt2020Pq, hdr_var));
+ hdr_var.pop_back();
+ hdr_var.push_back(std::make_pair(kGammaTransferAttribute, kHlg));
+ color_mode_attr_map_.insert(std::make_pair(kBt2020Hlg, hdr_var));
+
+ return;
+}
+
+bool DisplayBase::IsHdrMode(const AttrVal &attr) {
+ std::string color_gamut, dynamic_range;
+ GetValueOfModeAttribute(attr, kColorGamutAttribute, &color_gamut);
+ GetValueOfModeAttribute(attr, kDynamicRangeAttribute, &dynamic_range);
+ if (color_gamut == kDcip3 && dynamic_range == kHdr) {
+ return true;
+ }
+
+ return false;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/display_base.h b/sdm/libs/core/display_base.h
index ff5c188..d6d5f15 100644
--- a/sdm/libs/core/display_base.h
+++ b/sdm/libs/core/display_base.h
@@ -129,13 +129,12 @@
virtual DisplayError InitializeColorModes();
protected:
+ const char *kBt2020Pq = "bt2020_pq";
+ const char *kBt2020Hlg = "bt2020_hlg";
DisplayError BuildLayerStackStats(LayerStack *layer_stack);
virtual DisplayError ValidateGPUTargetParams();
void CommitLayerParams(LayerStack *layer_stack);
void PostCommitLayerParams(LayerStack *layer_stack);
- DisplayError HandleHDR(LayerStack *layer_stack);
- DisplayError ValidateHDR(LayerStack *layer_stack);
- DisplayError SetHDRMode(bool set);
DisplayError ValidateScaling(uint32_t width, uint32_t height);
DisplayError ValidateDataspace(const ColorMetaData &color_metadata);
void HwRecovery(const HWRecoveryEvent sdm_event_code);
@@ -150,7 +149,6 @@
DisplayError SetColorModeInternal(const std::string &color_mode);
DisplayError GetValueOfModeAttribute(const AttrVal &attr, const std::string &type,
std::string *value);
- DisplayError GetHdrColorMode(std::string *color_mode, bool *found_hdr);
bool IsSupportColorModeAttribute(const std::string &color_mode);
DisplayState GetLastPowerMode();
void SetPUonDestScaler();
@@ -161,6 +159,9 @@
std::vector<PrimariesTransfer> *supported_pt);
bool DisplayPowerResetPending();
bool SetHdrModeAtStart(LayerStack *layer_stack);
+ PrimariesTransfer GetBlendSpaceFromColorMode();
+ bool IsHdrMode(const AttrVal &attr);
+ void InsertBT2020PqHlgModes();
recursive_mutex recursive_mutex_;
int32_t display_id_ = -1;
@@ -204,8 +205,6 @@
uint32_t req_mixer_width_ = 0;
uint32_t req_mixer_height_ = 0;
std::string current_color_mode_ = "hal_native";
- bool hdr_playback_ = false;
- bool hdr_mode_ = false;
int disable_hdr_lut_gen_ = 0;
DisplayState last_power_mode_ = kStateOff;
bool gpu_fallback_ = false;
diff --git a/sdm/libs/core/display_pluggable.cpp b/sdm/libs/core/display_pluggable.cpp
index 524d7c1..fc1a68f 100644
--- a/sdm/libs/core/display_pluggable.cpp
+++ b/sdm/libs/core/display_pluggable.cpp
@@ -327,21 +327,41 @@
DisplayError DisplayPluggable::InitializeColorModes() {
PrimariesTransfer pt = {};
+ AttrVal var = {};
color_modes_cs_.push_back(pt);
-
+ var.push_back(std::make_pair(kColorGamutAttribute, kSrgb));
+ var.push_back(std::make_pair(kDynamicRangeAttribute, kSdr));
+ var.push_back(std::make_pair(kPictureQualityAttribute, kStandard));
+ color_mode_attr_map_.insert(std::make_pair(kSrgb, var));
+ pt.primaries = ColorPrimaries_BT2020;
if (!hw_panel_info_.hdr_enabled) {
+ UpdateColorModes();
return kErrorNone;
+ } else {
+ pt.transfer = Transfer_Gamma2_2;
+ color_modes_cs_.push_back(pt);
+ var.clear();
+ var.push_back(std::make_pair(kColorGamutAttribute, kBt2020));
+ var.push_back(std::make_pair(kGammaTransferAttribute, kGamma2_2));
+ color_mode_attr_map_.insert(std::make_pair(kBt2020, var));
}
- pt.primaries = ColorPrimaries_BT2020;
+ var.clear();
+ var.push_back(std::make_pair(kColorGamutAttribute, kBt2020));
if (hw_panel_info_.hdr_eotf & kHdrEOTFHDR10) {
pt.transfer = Transfer_SMPTE_ST2084;
+ var.push_back(std::make_pair(kGammaTransferAttribute, kSt2084));
color_modes_cs_.push_back(pt);
+ color_mode_attr_map_.insert(std::make_pair(kBt2020Pq, var));
}
if (hw_panel_info_.hdr_eotf & kHdrEOTFHLG) {
pt.transfer = Transfer_HLG;
+ var.pop_back();
+ var.push_back(std::make_pair(kGammaTransferAttribute, kHlg));
color_modes_cs_.push_back(pt);
+ color_mode_attr_map_.insert(std::make_pair(kBt2020Hlg, var));
}
+ UpdateColorModes();
return kErrorNone;
}
@@ -357,4 +377,112 @@
return kErrorNone;
}
+static PrimariesTransfer GetBlendSpaceFromAttributes(const std::string &color_gamut,
+ const std::string &transfer) {
+ PrimariesTransfer blend_space_ = {};
+ if (color_gamut == kBt2020) {
+ blend_space_.primaries = ColorPrimaries_BT2020;
+ if (transfer == kHlg) {
+ blend_space_.transfer = Transfer_HLG;
+ } else if (transfer == kSt2084) {
+ blend_space_.transfer = Transfer_SMPTE_ST2084;
+ } else if (transfer == kGamma2_2) {
+ blend_space_.transfer = Transfer_Gamma2_2;
+ }
+ } else if (color_gamut == kSrgb) {
+ blend_space_.primaries = ColorPrimaries_BT709_5;
+ blend_space_.transfer = Transfer_sRGB;
+ } else {
+ DLOGW("Failed to Get blend space color_gamut = %s transfer = %s", color_gamut.c_str(),
+ transfer.c_str());
+ }
+ DLOGI("Blend Space Primaries = %d Transfer = %d", blend_space_.primaries, blend_space_.transfer);
+
+ return blend_space_;
+}
+
+DisplayError DisplayPluggable::SetColorMode(const std::string &color_mode) {
+ auto current_color_attr_ = color_mode_attr_map_.find(color_mode);
+ if (current_color_attr_ == color_mode_attr_map_.end()) {
+ DLOGE("Failed to get attribues for color mode = %s", color_mode.c_str());
+ return kErrorNone;
+ }
+ AttrVal attr = current_color_attr_->second;
+ std::string color_gamut = kNative, transfer = {};
+
+ for (auto &it : attr) {
+ if (it.first.find(kColorGamutAttribute) != std::string::npos) {
+ color_gamut = it.second;
+ } else if (it.first.find(kGammaTransferAttribute) != std::string::npos) {
+ transfer = it.second;
+ }
+ }
+
+ DisplayError error = kErrorNone;
+ error = comp_manager_->SetBlendSpace(display_comp_ctx_,
+ GetBlendSpaceFromAttributes(color_gamut, transfer));
+ if (error != kErrorNone) {
+ DLOGE("Failed Set blend space, error = %d display_type_=%d", error, display_type_);
+ }
+
+ return kErrorNone;
+}
+
+DisplayError DisplayPluggable::GetColorModeCount(uint32_t *mode_count) {
+ lock_guard<recursive_mutex> obj(recursive_mutex_);
+ if (!mode_count) {
+ return kErrorParameters;
+ }
+
+ DLOGI("Display = %d Number of modes = %d", display_type_, num_color_modes_);
+ *mode_count = num_color_modes_;
+
+ return kErrorNone;
+}
+
+DisplayError DisplayPluggable::GetColorModes(uint32_t *mode_count,
+ std::vector<std::string> *color_modes) {
+ lock_guard<recursive_mutex> obj(recursive_mutex_);
+ if (!mode_count || !color_modes) {
+ return kErrorParameters;
+ }
+
+ for (uint32_t i = 0; i < num_color_modes_; i++) {
+ DLOGI_IF(kTagDisplay, "ColorMode[%d] = %s", i, color_modes_[i].name);
+ color_modes->at(i) = color_modes_[i].name;
+ }
+
+ return kErrorNone;
+}
+
+DisplayError DisplayPluggable::GetColorModeAttr(const std::string &color_mode, AttrVal *attr) {
+ lock_guard<recursive_mutex> obj(recursive_mutex_);
+ if (!attr) {
+ return kErrorParameters;
+ }
+
+ auto it = color_mode_attr_map_.find(color_mode);
+ if (it == color_mode_attr_map_.end()) {
+ DLOGI("Mode %s has no attribute", color_mode.c_str());
+ return kErrorNotSupported;
+ }
+ *attr = it->second;
+
+ return kErrorNone;
+}
+
+void DisplayPluggable::UpdateColorModes() {
+ uint32_t i = 0;
+ num_color_modes_ = UINT32(color_mode_attr_map_.size());
+ color_modes_.resize(num_color_modes_);
+ for (ColorModeAttrMap::iterator it = color_mode_attr_map_.begin();
+ ((i < num_color_modes_) && (it != color_mode_attr_map_.end())); i++, it++) {
+ color_modes_[i].id = INT32(i);
+ strncpy(color_modes_[i].name, it->first.c_str(), sizeof(color_modes_[i].name));
+ color_mode_map_.insert(std::make_pair(color_modes_[i].name, &color_modes_[i]));
+ DLOGI("Attr map name = %s", it->first.c_str());
+ }
+ return;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/display_pluggable.h b/sdm/libs/core/display_pluggable.h
index aba1305..f3da05b 100644
--- a/sdm/libs/core/display_pluggable.h
+++ b/sdm/libs/core/display_pluggable.h
@@ -48,6 +48,10 @@
virtual bool IsUnderscanSupported();
virtual DisplayError OnMinHdcpEncryptionLevelChange(uint32_t min_enc_level);
virtual DisplayError InitializeColorModes();
+ virtual DisplayError SetColorMode(const std::string &color_mode);
+ virtual DisplayError GetColorModeCount(uint32_t *mode_count);
+ virtual DisplayError GetColorModes(uint32_t *mode_count, std::vector<std::string> *color_modes);
+ virtual DisplayError GetColorModeAttr(const std::string &color_mode, AttrVal *attr);
virtual DisplayError SetDisplayState(DisplayState state, int *release_fence);
// Implement the HWEventHandlers
@@ -61,6 +65,8 @@
virtual void PanelDead() {}
virtual void HwRecovery(const HWRecoveryEvent sdm_event_code);
+ void UpdateColorModes();
+
private:
uint32_t GetBestConfig(HWS3DMode s3d_mode);
void GetScanSupport();
diff --git a/sdm/libs/core/strategy.cpp b/sdm/libs/core/strategy.cpp
index d96c103..1281545 100644
--- a/sdm/libs/core/strategy.cpp
+++ b/sdm/libs/core/strategy.cpp
@@ -258,4 +258,11 @@
return kErrorNotSupported;
}
+DisplayError Strategy::SetBlendSpace(const PrimariesTransfer &blend_space) {
+ if (strategy_intf_) {
+ return strategy_intf_->SetBlendSpace(blend_space);
+ }
+ return kErrorNotSupported;
+}
+
} // namespace sdm
diff --git a/sdm/libs/core/strategy.h b/sdm/libs/core/strategy.h
index c79dff6..db10f11 100644
--- a/sdm/libs/core/strategy.h
+++ b/sdm/libs/core/strategy.h
@@ -55,6 +55,7 @@
DisplayError Purge();
DisplayError SetIdleTimeoutMs(uint32_t active_ms);
DisplayError SetColorModesInfo(const std::vector<PrimariesTransfer> &colormodes_cs);
+ DisplayError SetBlendSpace(const PrimariesTransfer &blend_space);
private:
void GenerateROI();
diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk
index e9511f7..d9ffa0b 100644
--- a/sdm/libs/hwc2/Android.mk
+++ b/sdm/libs/hwc2/Android.mk
@@ -24,7 +24,8 @@
vendor.display.config@1.0 \
android.hardware.graphics.mapper@2.0 \
android.hardware.graphics.mapper@2.1 \
- android.hardware.graphics.allocator@2.0
+ android.hardware.graphics.allocator@2.0 \
+ android.hardware.graphics.composer@2.2 \
ifeq ($(display_config_version), DISPLAY_CONFIG_1_1)
LOCAL_SHARED_LIBRARIES += vendor.display.config@1.1
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 7435f3e..ef65057 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -67,47 +67,77 @@
}
HWC2::Error HWCColorMode::DeInit() {
- color_mode_transform_map_.clear();
+ color_mode_map_.clear();
return HWC2::Error::None;
}
uint32_t HWCColorMode::GetColorModeCount() {
- uint32_t count = UINT32(color_mode_transform_map_.size());
+ uint32_t count = UINT32(color_mode_map_.size());
DLOGI("Supported color mode count = %d", count);
-
return std::max(1U, count);
}
-HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes,
- android_color_mode_t *out_modes) {
- auto it = color_mode_transform_map_.begin();
- *out_num_modes = std::min(*out_num_modes, UINT32(color_mode_transform_map_.size()));
+uint32_t HWCColorMode::GetRenderIntentCount(ColorMode mode) {
+ uint32_t count = UINT32(color_mode_map_[mode].size());
+ DLOGI("mode: %d supported rendering intent count = %d", mode, count);
+ return std::max(1U, count);
+}
+
+HWC2::Error HWCColorMode::GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes) {
+ auto it = color_mode_map_.begin();
+ *out_num_modes = std::min(*out_num_modes, UINT32(color_mode_map_.size()));
for (uint32_t i = 0; i < *out_num_modes; it++, i++) {
out_modes[i] = it->first;
- DLOGI("Supports color mode[%d] = %d", i, it->first);
+ DLOGI("Color mode = %d is supported", out_modes[i]);
}
-
return HWC2::Error::None;
}
-HWC2::Error HWCColorMode::SetColorMode(android_color_mode_t mode) {
+HWC2::Error HWCColorMode::GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
+ RenderIntent *out_intents) {
+ if (color_mode_map_.find(mode) == color_mode_map_.end()) {
+ return HWC2::Error::BadParameter;
+ }
+ auto it = color_mode_map_[mode].begin();
+ *out_num_intents = std::min(*out_num_intents, UINT32(color_mode_map_[mode].size()));
+ for (uint32_t i = 0; i < *out_num_intents; it++, i++) {
+ out_intents[i] = it->first;
+ DLOGI("Color mode = %d is supported with render intent = %d", mode, out_intents[i]);
+ }
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCColorMode::SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
DTRACE_SCOPED();
- // first mode in 2D matrix is the mode (identity)
- if (mode < HAL_COLOR_MODE_NATIVE || mode > HAL_COLOR_MODE_DISPLAY_P3) {
+ if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
DLOGE("Could not find mode: %d", mode);
return HWC2::Error::BadParameter;
}
- if (color_mode_transform_map_.find(mode) == color_mode_transform_map_.end()) {
+ if (color_mode_map_.find(mode) == color_mode_map_.end()) {
+ return HWC2::Error::Unsupported;
+ }
+ if (color_mode_map_[mode].find(intent) == color_mode_map_[mode].end()) {
return HWC2::Error::Unsupported;
}
- auto status = HandleColorModeTransform(mode, current_color_transform_, color_matrix_);
- if (status != HWC2::Error::None) {
- DLOGE("failed for mode = %d", mode);
+ if (current_color_mode_ == mode && current_render_intent_ == intent) {
+ return HWC2::Error::None;
}
- DLOGV_IF(kTagClient, "Color mode %d successfully set.", mode);
- return status;
+ auto mode_string = color_mode_map_[mode][intent];
+ DisplayError error = display_intf_->SetColorMode(mode_string);
+ if (error != kErrorNone) {
+ DLOGE("failed for mode = %d intent = %d name = %s", mode, intent, mode_string.c_str());
+ return HWC2::Error::Unsupported;
+ }
+ // The mode does not have the PCC configured, restore the transform
+ RestoreColorTransform();
+
+ current_color_mode_ = mode;
+ current_render_intent_ = intent;
+ DLOGV_IF(kTagClient, "Successfully applied mode = %d intent = %d name = %s", mode, intent,
+ mode_string.c_str());
+ return HWC2::Error::None;
}
HWC2::Error HWCColorMode::SetColorModeById(int32_t color_mode_id) {
@@ -130,80 +160,42 @@
return HWC2::Error::None;
}
-HWC2::Error HWCColorMode::SetColorTransform(const float *matrix, android_color_transform_t hint) {
+HWC2::Error HWCColorMode::SetColorTransform(const float *matrix,
+ android_color_transform_t /*hint*/) {
DTRACE_SCOPED();
+ auto status = HWC2::Error::None;
double color_matrix[kColorTransformMatrixCount] = {0};
CopyColorTransformMatrix(matrix, color_matrix);
- auto status = HandleColorModeTransform(current_color_mode_, hint, color_matrix);
- if (status != HWC2::Error::None) {
- DLOGE("failed for hint = %d", hint);
+ DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, color_matrix);
+ if (error != kErrorNone) {
+ DLOGE("Failed to set Color Transform Matrix");
+ status = HWC2::Error::Unsupported;
}
-
+ CopyColorTransformMatrix(matrix, color_matrix_);
return status;
}
-HWC2::Error HWCColorMode::HandleColorModeTransform(android_color_mode_t mode,
- android_color_transform_t hint,
- const double *matrix) {
- android_color_transform_t transform_hint = hint;
- std::string color_mode_transform;
- bool use_matrix = false;
- if (hint != HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX) {
- // if the mode + transfrom request from HWC matches one mode in SDM, set that
- if (color_mode_transform.empty()) {
- transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
- use_matrix = true;
- } else {
- color_mode_transform = color_mode_transform_map_[mode][hint];
- }
- } else {
- use_matrix = true;
- transform_hint = HAL_COLOR_TRANSFORM_IDENTITY;
+void HWCColorMode::FindRenderIntent(const ColorMode &mode, const std::string &mode_string) {
+ auto intent = RenderIntent::COLORIMETRIC;
+ if (mode_string.find("enhanced") != std::string::npos) {
+ intent = RenderIntent::ENHANCE;
}
-
- // if the mode count is 1, then only native mode is supported, so just apply matrix w/o
- // setting mode
- if (color_mode_transform_map_.size() > 1U && current_color_mode_ != mode) {
- color_mode_transform = color_mode_transform_map_[mode][transform_hint];
- DisplayError error = display_intf_->SetColorMode(color_mode_transform);
- if (error != kErrorNone) {
- DLOGE("Failed to set color_mode = %d transform_hint = %d", mode, hint);
- // failure to force client composition
- return HWC2::Error::Unsupported;
- }
- DLOGI("Setting Color Mode = %d Transform Hint = %d Success", mode, hint);
- }
-
- if (use_matrix) {
- DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount, matrix);
- if (error != kErrorNone) {
- DLOGE("Failed to set Color Transform Matrix");
- // failure to force client composition
- return HWC2::Error::Unsupported;
- }
- }
-
- current_color_mode_ = mode;
- current_color_transform_ = hint;
- CopyColorTransformMatrix(matrix, color_matrix_);
-
- return HWC2::Error::None;
+ color_mode_map_[mode][intent] = mode_string;
}
void HWCColorMode::PopulateColorModes() {
uint32_t color_mode_count = 0;
- // SDM returns modes which is string combination of mode + transform.
+ // SDM returns modes which have attributes defining mode and rendering intent
DisplayError error = display_intf_->GetColorModeCount(&color_mode_count);
if (error != kErrorNone || (color_mode_count == 0)) {
DLOGW("GetColorModeCount failed, use native color mode");
- PopulateTransform(HAL_COLOR_MODE_NATIVE, "native", "identity");
+ color_mode_map_[ColorMode::NATIVE][RenderIntent::COLORIMETRIC] = "hal_native_identity";
return;
}
DLOGV_IF(kTagClient, "Color Modes supported count = %d", color_mode_count);
- const std::string color_transform = "identity";
std::vector<std::string> color_modes(color_mode_count);
error = display_intf_->GetColorModes(&color_mode_count, &color_modes);
for (uint32_t i = 0; i < color_mode_count; i++) {
@@ -211,7 +203,7 @@
DLOGV_IF(kTagClient, "Color Mode[%d] = %s", i, mode_string.c_str());
AttrVal attr;
error = display_intf_->GetColorModeAttr(mode_string, &attr);
- std::string color_gamut, dynamic_range, pic_quality;
+ std::string color_gamut = kNative, dynamic_range = kSdr, pic_quality = kStandard, transfer;
if (!attr.empty()) {
for (auto &it : attr) {
if (it.first.find(kColorGamutAttribute) != std::string::npos) {
@@ -220,81 +212,66 @@
dynamic_range = it.second;
} else if (it.first.find(kPictureQualityAttribute) != std::string::npos) {
pic_quality = it.second;
+ } else if (it.first.find(kGammaTransferAttribute) != std::string::npos) {
+ transfer = it.second;
}
}
DLOGV_IF(kTagClient, "color_gamut : %s, dynamic_range : %s, pic_quality : %s",
color_gamut.c_str(), dynamic_range.c_str(), pic_quality.c_str());
-
- if (dynamic_range == kHdr) {
- continue;
+ if (color_gamut == kNative) {
+ color_mode_map_[ColorMode::NATIVE][RenderIntent::COLORIMETRIC] = mode_string;
}
- if ((color_gamut == kNative) &&
- (pic_quality.empty() || pic_quality == kStandard)) {
- PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, color_transform);
- } else if ((color_gamut == kSrgb) &&
- (pic_quality.empty() || pic_quality == kStandard)) {
- PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, color_transform);
- } else if ((color_gamut == kDcip3) &&
- (pic_quality.empty() || pic_quality == kStandard)) {
- PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
- } else if ((color_gamut == kDisplayP3) &&
- (pic_quality.empty() || pic_quality == kStandard)) {
- PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, color_transform);
- }
- }
- // Look at the mode name, if no color gamut is found
- if (color_gamut.empty()) {
+ if (color_gamut == kSrgb && dynamic_range == kSdr) {
+ if (pic_quality == kStandard) {
+ color_mode_map_[ColorMode::SRGB][RenderIntent::COLORIMETRIC] = mode_string;
+ }
+ if (pic_quality == kEnhanced) {
+ color_mode_map_[ColorMode::SRGB][RenderIntent::ENHANCE] = mode_string;
+ }
+ }
+
+ if (color_gamut == kDcip3 && dynamic_range == kSdr) {
+ if (pic_quality == kStandard) {
+ color_mode_map_[ColorMode::DISPLAY_P3][RenderIntent::COLORIMETRIC] = mode_string;
+ }
+ if (pic_quality == kEnhanced) {
+ color_mode_map_[ColorMode::DISPLAY_P3][RenderIntent::ENHANCE] = mode_string;
+ }
+ }
+ if (color_gamut == kDcip3 && pic_quality == kStandard && dynamic_range == kHdr) {
+ color_mode_map_[ColorMode::BT2100_PQ][RenderIntent::TONE_MAP_COLORIMETRIC] = mode_string;
+ color_mode_map_[ColorMode::BT2100_HLG][RenderIntent::TONE_MAP_COLORIMETRIC] = mode_string;
+ } else if (color_gamut == kBt2020) {
+ if (transfer == kSt2084) {
+ color_mode_map_[ColorMode::BT2100_PQ][RenderIntent::COLORIMETRIC] = mode_string;
+ } else if (transfer == kHlg) {
+ color_mode_map_[ColorMode::BT2100_HLG][RenderIntent::COLORIMETRIC] = mode_string;
+ } else if (transfer == kGamma2_2) {
+ color_mode_map_[ColorMode::BT2020][RenderIntent::COLORIMETRIC] = mode_string;
+ }
+ }
+ } else {
+ // Look at the mode names, if no attributes are found
if (mode_string.find("hal_native") != std::string::npos) {
- PopulateTransform(HAL_COLOR_MODE_NATIVE, mode_string, mode_string);
- } else if (mode_string.find("hal_srgb") != std::string::npos) {
- PopulateTransform(HAL_COLOR_MODE_SRGB, mode_string, mode_string);
- } else if (mode_string.find("hal_adobe") != std::string::npos) {
- PopulateTransform(HAL_COLOR_MODE_ADOBE_RGB, mode_string, mode_string);
- } else if (mode_string.find("hal_dci_p3") != std::string::npos) {
- PopulateTransform(HAL_COLOR_MODE_DCI_P3, mode_string, mode_string);
- } else if (mode_string.find("hal_display_p3") != std::string::npos) {
- PopulateTransform(HAL_COLOR_MODE_DISPLAY_P3, mode_string, mode_string);
+ color_mode_map_[ColorMode::NATIVE][RenderIntent::COLORIMETRIC] = mode_string;
}
}
}
}
-void HWCColorMode::PopulateTransform(const android_color_mode_t &mode,
- const std::string &color_mode,
- const std::string &color_transform) {
- // TODO(user): Check the substring from QDCM
- if (color_transform.find("identity") != std::string::npos) {
- color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_mode;
- } else if (color_transform.find("arbitrary") != std::string::npos) {
- // no color mode for arbitrary
- } else if (color_transform.find("inverse") != std::string::npos) {
- color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_VALUE_INVERSE] = color_mode;
- } else if (color_transform.find("grayscale") != std::string::npos) {
- color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_GRAYSCALE] = color_mode;
- } else if (color_transform.find("correct_protonopia") != std::string::npos) {
- color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_PROTANOPIA] = color_mode;
- } else if (color_transform.find("correct_deuteranopia") != std::string::npos) {
- color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_DEUTERANOPIA] = color_mode;
- } else if (color_transform.find("correct_tritanopia") != std::string::npos) {
- color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_CORRECT_TRITANOPIA] = color_mode;
- } else {
- color_mode_transform_map_[mode][HAL_COLOR_TRANSFORM_IDENTITY] = color_mode;
- }
-}
-
HWC2::Error HWCColorMode::ApplyDefaultColorMode() {
- android_color_mode_t color_mode = HAL_COLOR_MODE_NATIVE;
- if (color_mode_transform_map_.size() == 1U) {
- color_mode = color_mode_transform_map_.begin()->first;
- } else if (color_mode_transform_map_.size() > 1U) {
+ auto color_mode = ColorMode::NATIVE;
+ if (color_mode_map_.size() == 1U) {
+ color_mode = color_mode_map_.begin()->first;
+ } else if (color_mode_map_.size() > 1U) {
std::string default_color_mode;
bool found = false;
DisplayError error = display_intf_->GetDefaultColorMode(&default_color_mode);
if (error == kErrorNone) {
// get the default mode corresponding android_color_mode_t
- for (auto &it_mode : color_mode_transform_map_) {
+ for (auto &it_mode : color_mode_map_) {
for (auto &it : it_mode.second) {
if (it.second == default_color_mode) {
found = true;
@@ -308,20 +285,25 @@
}
}
- // return the first andrid_color_mode_t when we encouter if not found
+ // return the first color mode we encounter if not found
if (!found) {
- color_mode = color_mode_transform_map_.begin()->first;
+ color_mode = color_mode_map_.begin()->first;
}
}
- return SetColorMode(color_mode);
+ return SetColorModeWithRenderIntent(color_mode, RenderIntent::COLORIMETRIC);
}
void HWCColorMode::Dump(std::ostringstream* os) {
- *os << "color modes supported: ";
- for (auto it : color_mode_transform_map_) {
- *os << it.first <<" ";
+ *os << "color modes supported: \n";
+ for (auto it : color_mode_map_) {
+ *os << "mode: " << static_cast<int32_t>(it.first) << " RIs { ";
+ for (auto rit : color_mode_map_[it.first]) {
+ *os << static_cast<int32_t>(rit.first) << " ";
+ }
+ *os << "} \n";
}
- *os << "current mode: " << current_color_mode_ << std::endl;
+ *os << "current mode: " << static_cast<uint32_t>(current_color_mode_) << std::endl;
+ *os << "current render_intent: " << static_cast<uint32_t>(current_render_intent_) << std::endl;
*os << "current transform: ";
for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
if (i % 4 == 0) {
@@ -553,8 +535,12 @@
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_) {
- // dont honor HDR when its handling is disabled
+ if (hdr_layer && !disable_hdr_handling_ &&
+ (color_mode_->GetCurrentColorMode()) != ColorMode::NATIVE) {
+ // Dont honor HDR when its handling is disabled
+ // Also, when the color mode is native, it implies that
+ // SF has not correctly set the mode to BT2100_PQ in the presence of an HDR layer
+ // In such cases, we should not handle HDR as the HDR mode isn't applied
layer->input_buffer.flags.hdr = true;
layer_stack_.flags.hdr_present = true;
}
@@ -778,14 +764,27 @@
return HWC2::Error::None;
}
-HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes) {
+HWC2::Error HWCDisplay::GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes) {
if (out_modes == nullptr) {
*out_num_modes = 1;
} else if (out_modes && *out_num_modes > 0) {
*out_num_modes = 1;
- out_modes[0] = HAL_COLOR_MODE_NATIVE;
+ out_modes[0] = ColorMode::NATIVE;
}
+ return HWC2::Error::None;
+}
+HWC2::Error HWCDisplay::GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
+ RenderIntent *out_intents) {
+ if (mode != ColorMode::NATIVE) {
+ return HWC2::Error::Unsupported;
+ }
+ if (out_intents == nullptr) {
+ *out_num_intents = 1;
+ } else if (out_intents && *out_num_intents > 0) {
+ *out_num_intents = 1;
+ out_intents[0] = RenderIntent::COLORIMETRIC;
+ }
return HWC2::Error::None;
}
@@ -899,6 +898,29 @@
}
}
+HWC2::Error HWCDisplay::GetPerFrameMetadataKeys(uint32_t *out_num_keys,
+ PerFrameMetadataKey *out_keys) {
+ if (out_num_keys == nullptr) {
+ return HWC2::Error::BadParameter;
+ }
+ *out_num_keys = UINT32(PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL) + 1;
+ if (out_keys != nullptr) {
+ out_keys[0] = PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X;
+ out_keys[1] = PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y;
+ out_keys[2] = PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X;
+ out_keys[3] = PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y;
+ out_keys[4] = PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X;
+ out_keys[5] = PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y;
+ out_keys[6] = PerFrameMetadataKey::WHITE_POINT_X;
+ out_keys[7] = PerFrameMetadataKey::WHITE_POINT_Y;
+ out_keys[8] = PerFrameMetadataKey::MAX_LUMINANCE;
+ out_keys[9] = PerFrameMetadataKey::MIN_LUMINANCE;
+ out_keys[10] = PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL;
+ out_keys[11] = PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL;
+ }
+ return HWC2::Error::None;
+}
+
HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
if (out_config == nullptr) {
return HWC2::Error::BadDisplay;
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index d35ea23..b4bb554 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -20,12 +20,13 @@
#ifndef __HWC_DISPLAY_H__
#define __HWC_DISPLAY_H__
-#include <sys/stat.h>
#include <QService.h>
+#include <android/hardware/graphics/common/1.1/types.h>
#include <core/core_interface.h>
#include <hardware/hwcomposer.h>
#include <private/color_params.h>
#include <qdMetaData.h>
+#include <sys/stat.h>
#include <map>
#include <queue>
#include <set>
@@ -40,6 +41,10 @@
#include "display_null.h"
#include "hwc_display_event_handler.h"
+using android::hardware::graphics::common::V1_1::ColorMode;
+using android::hardware::graphics::common::V1_1::Dataspace;
+using android::hardware::graphics::common::V1_1::RenderIntent;
+
namespace sdm {
class BlitEngine;
@@ -68,20 +73,19 @@
HWC2::Error DeInit();
void Dump(std::ostringstream* os);
uint32_t GetColorModeCount();
- HWC2::Error GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes);
- HWC2::Error SetColorMode(android_color_mode_t mode);
+ uint32_t GetRenderIntentCount(ColorMode mode);
+ HWC2::Error GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes);
+ HWC2::Error GetRenderIntents(ColorMode mode, uint32_t *out_num_intents, RenderIntent *out_modes);
+ HWC2::Error SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent);
HWC2::Error SetColorModeById(int32_t color_mode_id);
HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
HWC2::Error RestoreColorTransform();
+ ColorMode GetCurrentColorMode() { return current_color_mode_; }
private:
static const uint32_t kColorTransformMatrixCount = 16;
-
- HWC2::Error HandleColorModeTransform(android_color_mode_t mode,
- android_color_transform_t hint, const double *matrix);
void PopulateColorModes();
- void PopulateTransform(const android_color_mode_t &mode,
- const std::string &color_mode, const std::string &color_transform);
+ void FindRenderIntent(const ColorMode &mode, const std::string &mode_string);
template <class T>
void CopyColorTransformMatrix(const T *input_matrix, double *output_matrix) {
for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
@@ -91,10 +95,12 @@
HWC2::Error ApplyDefaultColorMode();
DisplayInterface *display_intf_ = NULL;
- android_color_mode_t current_color_mode_ = HAL_COLOR_MODE_NATIVE;
- android_color_transform_t current_color_transform_ = HAL_COLOR_TRANSFORM_IDENTITY;
- typedef std::map<android_color_transform_t, std::string> TransformMap;
- std::map<android_color_mode_t, TransformMap> color_mode_transform_map_ = {};
+
+ ColorMode current_color_mode_ = ColorMode::NATIVE;
+ RenderIntent current_render_intent_ = RenderIntent::COLORIMETRIC;
+ typedef std::map<RenderIntent, std::string> RenderIntentMap;
+ // Initialize supported mode/render intent combination
+ std::map<ColorMode, RenderIntentMap> color_mode_map_ = {};
double color_matrix_[kColorTransformMatrixCount] = { 1.0, 0.0, 0.0, 0.0, \
0.0, 1.0, 0.0, 0.0, \
0.0, 0.0, 1.0, 0.0, \
@@ -203,7 +209,8 @@
virtual HWC2::Error SetActiveConfig(hwc2_config_t config);
virtual HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
int32_t dataspace, hwc_region_t damage);
- virtual HWC2::Error SetColorMode(android_color_mode_t mode) {
+ virtual HWC2::Error SetColorMode(ColorMode mode) { return HWC2::Error::Unsupported; }
+ virtual HWC2::Error SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
return HWC2::Error::Unsupported;
}
virtual HWC2::Error SetColorModeById(int32_t color_mode_id) {
@@ -225,7 +232,9 @@
int32_t *out_value);
virtual HWC2::Error GetClientTargetSupport(uint32_t width, uint32_t height, int32_t format,
int32_t dataspace);
- virtual HWC2::Error GetColorModes(uint32_t *outNumModes, android_color_mode_t *outModes);
+ virtual HWC2::Error GetColorModes(uint32_t *outNumModes, ColorMode *outModes);
+ virtual HWC2::Error GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
+ RenderIntent *out_intents);
virtual HWC2::Error GetChangedCompositionTypes(uint32_t *out_num_elements,
hwc2_layer_t *out_layers, int32_t *out_types);
virtual HWC2::Error GetDisplayRequests(int32_t *out_display_requests, uint32_t *out_num_elements,
@@ -246,6 +255,8 @@
float* out_max_luminance,
float* out_max_average_luminance,
float* out_min_luminance);
+ virtual HWC2::Error GetPerFrameMetadataKeys(uint32_t *out_num_keys,
+ PerFrameMetadataKey *out_keys);
virtual HWC2::Error SetDisplayAnimating(bool animating) {
animating_ = animating;
validated_ = false;
diff --git a/sdm/libs/hwc2/hwc_display_external.cpp b/sdm/libs/hwc2/hwc_display_external.cpp
index 70d7528..ad18868 100644
--- a/sdm/libs/hwc2/hwc_display_external.cpp
+++ b/sdm/libs/hwc2/hwc_display_external.cpp
@@ -95,6 +95,17 @@
return status;
}
+int HWCDisplayExternal::Init() {
+ int status = HWCDisplay::Init();
+ if (status) {
+ return status;
+ }
+ color_mode_ = new HWCColorMode(display_intf_);
+ color_mode_->Init();
+
+ return status;
+}
+
void HWCDisplayExternal::Destroy(HWCDisplay *hwc_display) {
hwc_display->Deinit();
delete hwc_display;
@@ -284,4 +295,40 @@
return display_intf_->Flush();
}
+HWC2::Error HWCDisplayExternal::GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes) {
+ if (out_modes == nullptr) {
+ *out_num_modes = color_mode_->GetColorModeCount();
+ } else {
+ color_mode_->GetColorModes(out_num_modes, out_modes);
+ }
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplayExternal::GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
+ RenderIntent *out_intents) {
+ if (out_intents == nullptr) {
+ *out_num_intents = color_mode_->GetRenderIntentCount(mode);
+ } else {
+ color_mode_->GetRenderIntents(mode, out_num_intents, out_intents);
+ }
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplayExternal::SetColorMode(ColorMode mode) {
+ return SetColorModeWithRenderIntent(mode, RenderIntent::COLORIMETRIC);
+}
+
+HWC2::Error HWCDisplayExternal::SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
+ auto status = color_mode_->SetColorModeWithRenderIntent(mode, intent);
+ if (status != HWC2::Error::None) {
+ DLOGE("failed for mode = %d intent = %d", mode, intent);
+ return status;
+ }
+
+ callbacks_->Refresh(HWC_DISPLAY_EXTERNAL);
+ validated_ = false;
+
+ return status;
+}
+
} // namespace sdm
diff --git a/sdm/libs/hwc2/hwc_display_external.h b/sdm/libs/hwc2/hwc_display_external.h
index 88b10e4..89ac87e 100644
--- a/sdm/libs/hwc2/hwc_display_external.h
+++ b/sdm/libs/hwc2/hwc_display_external.h
@@ -46,10 +46,16 @@
HWCCallbacks *callbacks, HWCDisplayEventHandler *event_handler,
qService::QService *qservice, HWCDisplay **hwc_display);
static void Destroy(HWCDisplay *hwc_display);
+ virtual int Init();
virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
virtual HWC2::Error Present(int32_t *out_retire_fence);
virtual int SetState(bool connected);
virtual DisplayError Flush();
+ virtual HWC2::Error GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes);
+ virtual HWC2::Error GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
+ RenderIntent *out_intents);
+ virtual HWC2::Error SetColorMode(ColorMode mode);
+ virtual HWC2::Error SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent);
private:
HWCDisplayExternal(CoreInterface *core_intf, HWCBufferAllocator *buffer_allocator,
diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp
index 36050d2..e285c04 100644
--- a/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -250,8 +250,7 @@
return status;
}
-HWC2::Error HWCDisplayPrimary::GetColorModes(uint32_t *out_num_modes,
- android_color_mode_t *out_modes) {
+HWC2::Error HWCDisplayPrimary::GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes) {
if (out_modes == nullptr) {
*out_num_modes = color_mode_->GetColorModeCount();
} else {
@@ -261,16 +260,28 @@
return HWC2::Error::None;
}
-HWC2::Error HWCDisplayPrimary::SetColorMode(android_color_mode_t mode) {
- auto status = color_mode_->SetColorMode(mode);
+HWC2::Error HWCDisplayPrimary::GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
+ RenderIntent *out_intents) {
+ if (out_intents == nullptr) {
+ *out_num_intents = color_mode_->GetRenderIntentCount(mode);
+ } else {
+ color_mode_->GetRenderIntents(mode, out_num_intents, out_intents);
+ }
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCDisplayPrimary::SetColorMode(ColorMode mode) {
+ return SetColorModeWithRenderIntent(mode, RenderIntent::COLORIMETRIC);
+}
+
+HWC2::Error HWCDisplayPrimary::SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
+ auto status = color_mode_->SetColorModeWithRenderIntent(mode, intent);
if (status != HWC2::Error::None) {
- DLOGE("failed for mode = %d", mode);
+ DLOGE("failed for mode = %d intent = %d", mode, intent);
return status;
}
-
callbacks_->Refresh(HWC_DISPLAY_PRIMARY);
validated_ = false;
-
return status;
}
diff --git a/sdm/libs/hwc2/hwc_display_primary.h b/sdm/libs/hwc2/hwc_display_primary.h
index c561f4c..8957855 100644
--- a/sdm/libs/hwc2/hwc_display_primary.h
+++ b/sdm/libs/hwc2/hwc_display_primary.h
@@ -55,8 +55,11 @@
virtual int Init();
virtual HWC2::Error Validate(uint32_t *out_num_types, uint32_t *out_num_requests);
virtual HWC2::Error Present(int32_t *out_retire_fence);
- virtual HWC2::Error GetColorModes(uint32_t *out_num_modes, android_color_mode_t *out_modes);
- virtual HWC2::Error SetColorMode(android_color_mode_t mode);
+ virtual HWC2::Error GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes);
+ virtual HWC2::Error SetColorMode(ColorMode mode);
+ virtual HWC2::Error GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
+ RenderIntent *out_intents);
+ virtual HWC2::Error SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent);
virtual HWC2::Error SetColorModeById(int32_t color_mode_id);
virtual HWC2::Error SetColorTransform(const float *matrix, android_color_transform_t hint);
virtual HWC2::Error RestoreColorTransform();
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 7aac16f..840119e 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -517,6 +517,56 @@
return HWC2::Error::None;
}
+HWC2::Error HWCLayer::SetLayerPerFrameMetadata(uint32_t num_elements,
+ const PerFrameMetadataKey *keys,
+ const float *metadata) {
+ auto &mastering_display = layer_->input_buffer.color_metadata.masteringDisplayInfo;
+ auto &content_light = layer_->input_buffer.color_metadata.contentLightLevel;
+ for (uint32_t i = 0; i < num_elements; i++) {
+ switch (keys[i]) {
+ case PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X:
+ mastering_display.colorVolumeSEIEnabled = true;
+ mastering_display.primaries.rgbPrimaries[0][0] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y:
+ mastering_display.primaries.rgbPrimaries[0][1] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X:
+ mastering_display.primaries.rgbPrimaries[1][0] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y:
+ mastering_display.primaries.rgbPrimaries[1][1] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X:
+ mastering_display.primaries.rgbPrimaries[2][0] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y:
+ mastering_display.primaries.rgbPrimaries[2][1] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::WHITE_POINT_X:
+ mastering_display.primaries.whitePoint[0] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::WHITE_POINT_Y:
+ mastering_display.primaries.whitePoint[1] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::MAX_LUMINANCE:
+ mastering_display.maxDisplayLuminance = UINT32(metadata[i]);
+ break;
+ case PerFrameMetadataKey::MIN_LUMINANCE:
+ mastering_display.minDisplayLuminance = UINT32(metadata[i] * 10000);
+ break;
+ case PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL:
+ content_light.lightLevelSEIEnabled = true;
+ content_light.maxContentLightLevel = UINT32(metadata[i]);
+ break;
+ case PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL:
+ content_light.minPicAverageLightLevel = UINT32(metadata[i] * 10000);
+ break;
+ }
+ }
+ return HWC2::Error::None;
+}
+
void HWCLayer::SetRect(const hwc_rect_t &source, LayerRect *target) {
target->left = FLOAT(source.left);
target->top = FLOAT(source.top);
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
index 0b08bb5..d72f07f 100644
--- a/sdm/libs/hwc2/hwc_layers.h
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -32,12 +32,16 @@
#include <hardware/hwcomposer2.h>
#undef HWC2_INCLUDE_STRINGIFICATION
#undef HWC2_USE_CPP11
-#include <map>
+#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
#include <deque>
+#include <map>
#include <set>
#include "core/buffer_allocator.h"
#include "hwc_buffer_allocator.h"
+using PerFrameMetadataKey =
+ android::hardware::graphics::composer::V2_2::IComposerClient::PerFrameMetadataKey;
+
namespace sdm {
DisplayError SetCSC(const private_handle_t *pvt_handle, ColorMetaData *color_metadata);
@@ -83,6 +87,8 @@
HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage);
HWC2::Error SetLayerTransform(HWC2::Transform transform);
HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
+ HWC2::Error SetLayerPerFrameMetadata(uint32_t num_elements, const PerFrameMetadataKey *keys,
+ const float *metadata);
HWC2::Error SetLayerZOrder(uint32_t z);
void SetComposition(const LayerComposition &sdm_composition);
HWC2::Composition GetClientRequestedCompositionType() { return client_requested_; }
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 237343f..10482ae 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -17,26 +17,27 @@
* limitations under the License.
*/
-#include <core/buffer_allocator.h>
-#include <private/color_params.h>
-#include <utils/constants.h>
-#include <utils/String16.h>
-#include <cutils/properties.h>
-#include <hardware_legacy/uevent.h>
-#include <sys/resource.h>
-#include <sys/prctl.h>
-#include <binder/Parcel.h>
#include <QService.h>
+#include <binder/Parcel.h>
+#include <core/buffer_allocator.h>
+#include <cutils/properties.h>
#include <display_config.h>
-#include <utils/debug.h>
-#include <sync/sync.h>
+#include <hardware_legacy/uevent.h>
+#include <private/color_params.h>
#include <qd_utils.h>
+#include <sync/sync.h>
+#include <sys/prctl.h>
+#include <sys/resource.h>
+#include <utils/String16.h>
+#include <utils/constants.h>
+#include <utils/debug.h>
#include <utils/utils.h>
#include <algorithm>
-#include <string>
#include <bitset>
-#include <thread>
#include <memory>
+#include <string>
+#include <thread>
+#include <vector>
#include "hwc_buffer_allocator.h"
#include "hwc_buffer_sync_handler.h"
@@ -440,8 +441,8 @@
}
static int32_t GetColorModes(hwc2_device_t *device, hwc2_display_t display, uint32_t *out_num_modes,
- int32_t /*android_color_mode_t*/ *int_out_modes) {
- auto out_modes = reinterpret_cast<android_color_mode_t *>(int_out_modes);
+ int32_t /*ColorMode*/ *int_out_modes) {
+ auto out_modes = reinterpret_cast<ColorMode *>(int_out_modes);
if (out_num_modes == nullptr) {
return HWC2_ERROR_BAD_PARAMETER;
}
@@ -449,6 +450,80 @@
out_modes);
}
+static int32_t GetRenderIntents(hwc2_device_t *device, hwc2_display_t display,
+ int32_t /*ColorMode*/ int_mode, uint32_t *out_num_intents,
+ int32_t /*RenderIntent*/ *int_out_intents) {
+ auto mode = static_cast<ColorMode>(int_mode);
+ auto out_intents = reinterpret_cast<RenderIntent *>(int_out_intents);
+ if (out_num_intents == nullptr) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+ return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetRenderIntents, mode,
+ out_num_intents, out_intents);
+}
+
+static int32_t GetDataspaceSaturationMatrix(hwc2_device_t *device,
+ int32_t /*Dataspace*/ int_dataspace,
+ float *out_matrix) {
+ auto dataspace = static_cast<Dataspace>(int_dataspace);
+ if (device == nullptr || out_matrix == nullptr || dataspace != Dataspace::SRGB_LINEAR) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+ // We only have the matrix for sRGB
+ float saturation_matrix[kDataspaceSaturationMatrixCount] = { 1.0, 0.0, 0.0, 0.0, \
+ 0.0, 1.0, 0.0, 0.0, \
+ 0.0, 0.0, 1.0, 0.0, \
+ 0.0, 0.0, 0.0, 1.0 };
+
+ // TODO(user): This value should ideally be retrieved from a QDCM configuration file
+ char value[kPropertyMax] = {};
+ if (Debug::Get()->GetProperty(DATASPACE_SATURATION_MATRIX_PROP, value) != kErrorNone) {
+ DLOGW("Undefined saturation matrix");
+ return HWC2_ERROR_BAD_CONFIG;
+ }
+ std::string value_string(value);
+ std::size_t start = 0, end = 0;
+ int index = 0;
+ while ((end = value_string.find(",", start)) != std::string::npos) {
+ saturation_matrix[index] = std::stof(value_string.substr(start, end - start));
+ start = end + 1;
+ index++;
+ // We expect a 3x3, SF needs 4x4, keep the last row/column identity
+ if ((index + 1) % 4 == 0) {
+ index++;
+ }
+ }
+ saturation_matrix[index] = std::stof(value_string.substr(start, end - start));
+ if (index < kDataspaceSaturationPropertyElements - 1) {
+ // The property must have kDataspaceSaturationPropertyElements delimited by commas
+ DLOGW("Invalid saturation matrix defined");
+ return HWC2_ERROR_BAD_CONFIG;
+ }
+ for (int32_t i = 0; i < kDataspaceSaturationMatrixCount; i += 4) {
+ DLOGD("%f %f %f %f", saturation_matrix[i], saturation_matrix[i + 1], saturation_matrix[i + 2],
+ saturation_matrix[i + 3]);
+ }
+ for (uint32_t i = 0; i < kDataspaceSaturationMatrixCount; i++) {
+ out_matrix[i] = saturation_matrix[i];
+ }
+ return HWC2_ERROR_NONE;
+}
+
+static int32_t GetPerFrameMetadataKeys(hwc2_device_t *device, hwc2_display_t display,
+ uint32_t *out_num_keys, int32_t *int_out_keys) {
+ auto out_keys = reinterpret_cast<PerFrameMetadataKey *>(int_out_keys);
+ return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetPerFrameMetadataKeys,
+ out_num_keys, out_keys);
+}
+
+static int32_t SetLayerPerFrameMetadata(hwc2_device_t *device, hwc2_display_t display,
+ hwc2_layer_t layer, uint32_t num_elements,
+ const int32_t *int_keys, const float *metadata) {
+ auto keys = reinterpret_cast<const PerFrameMetadataKey *>(int_keys);
+ return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPerFrameMetadata,
+ num_elements, keys, metadata);
+}
+
static int32_t GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display,
hwc2_config_t config, int32_t int_attribute,
int32_t *out_value) {
@@ -598,14 +673,26 @@
}
int32_t HWCSession::SetColorMode(hwc2_device_t *device, hwc2_display_t display,
- int32_t /*android_color_mode_t*/ int_mode) {
- if (int_mode < HAL_COLOR_MODE_NATIVE || int_mode > HAL_COLOR_MODE_DISPLAY_P3) {
+ int32_t /*ColorMode*/ int_mode) {
+ auto mode = static_cast<ColorMode>(int_mode);
+ if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
return HWC2_ERROR_BAD_PARAMETER;
}
- auto mode = static_cast<android_color_mode_t>(int_mode);
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
}
+int32_t HWCSession::SetColorModeWithRenderIntent(hwc2_device_t *device, hwc2_display_t display,
+ int32_t /*ColorMode*/ int_mode,
+ int32_t /*RenderIntent*/ int_render_intent) {
+ auto mode = static_cast<ColorMode>(int_mode);
+ if (mode < ColorMode::NATIVE || mode > ColorMode::BT2100_HLG) {
+ return HWC2_ERROR_BAD_PARAMETER;
+ }
+ auto render_intent = static_cast<RenderIntent>(int_render_intent);
+ return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetColorModeWithRenderIntent,
+ mode, render_intent);
+}
+
int32_t HWCSession::SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
const float *matrix,
int32_t /*android_color_transform_t*/ hint) {
@@ -892,6 +979,17 @@
return AsFP<HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES>(HWCSession::GetReadbackBufferAttributes);
case HWC2::FunctionDescriptor::GetReadbackBufferFence:
return AsFP<HWC2_PFN_GET_READBACK_BUFFER_FENCE>(HWCSession::GetReadbackBufferFence);
+ case HWC2::FunctionDescriptor::GetRenderIntents:
+ return AsFP<HWC2_PFN_GET_RENDER_INTENTS>(GetRenderIntents);
+ case HWC2::FunctionDescriptor::SetColorModeWithRenderIntent:
+ return AsFP<HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT>(
+ HWCSession::SetColorModeWithRenderIntent);
+ case HWC2::FunctionDescriptor::GetDataspaceSaturationMatrix:
+ return AsFP<HWC2_PFN_GET_DATASPACE_SATURATION_MATRIX>(GetDataspaceSaturationMatrix);
+ case HWC2::FunctionDescriptor::GetPerFrameMetadataKeys:
+ return AsFP<HWC2_PFN_GET_PER_FRAME_METADATA_KEYS>(GetPerFrameMetadataKeys);
+ case HWC2::FunctionDescriptor::SetLayerPerFrameMetadata:
+ return AsFP<HWC2_PFN_SET_LAYER_PER_FRAME_METADATA>(SetLayerPerFrameMetadata);
default:
DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
to_string(descriptor).c_str());
@@ -1202,6 +1300,14 @@
status = SetColorModeOverride(input_parcel);
break;
+ case qService::IQService::SET_COLOR_MODE_WITH_RENDER_INTENT:
+ if (!input_parcel) {
+ DLOGE("QService command = %d: input_parcel needed.", command);
+ break;
+ }
+ status = SetColorModeWithRenderIntentOverride(input_parcel);
+ break;
+
case qService::IQService::SET_COLOR_MODE_BY_ID:
if (!input_parcel) {
DLOGE("QService command = %d: input_parcel needed.", command);
@@ -1394,7 +1500,7 @@
android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_parcel) {
auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
- auto mode = static_cast<android_color_mode_t>(input_parcel->readInt32());
+ auto mode = static_cast<ColorMode>(input_parcel->readInt32());
auto device = static_cast<hwc2_device_t *>(this);
auto err = CallDisplayFunction(device, display, &HWCDisplay::SetColorMode, mode);
@@ -1404,6 +1510,20 @@
return 0;
}
+android::status_t HWCSession::SetColorModeWithRenderIntentOverride(
+ const android::Parcel *input_parcel) {
+ auto display = static_cast<hwc2_display_t>(input_parcel->readInt32());
+ auto mode = static_cast<ColorMode>(input_parcel->readInt32());
+ auto intent = static_cast<RenderIntent>(input_parcel->readInt32());
+ auto device = static_cast<hwc2_device_t *>(this);
+
+ auto err =
+ CallDisplayFunction(device, display, &HWCDisplay::SetColorModeWithRenderIntent, mode, intent);
+ if (err != HWC2_ERROR_NONE)
+ return -EINVAL;
+
+ return 0;
+}
android::status_t HWCSession::SetColorModeById(const android::Parcel *input_parcel) {
auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
auto mode = input_parcel->readInt32();
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index f74179b..119c931 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -73,6 +73,10 @@
bool init_done_ = false;
};
+constexpr int32_t kDataspaceSaturationMatrixCount = 16;
+constexpr int32_t kDataspaceSaturationPropertyElements = 9;
+constexpr int32_t kPropertyMax = 256;
+
class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qClient::BnQClient,
public HWCDisplayEventHandler {
public:
@@ -161,7 +165,10 @@
static int32_t ValidateDisplay(hwc2_device_t *device, hwc2_display_t display,
uint32_t *out_num_types, uint32_t *out_num_requests);
static int32_t SetColorMode(hwc2_device_t *device, hwc2_display_t display,
- int32_t /*android_color_mode_t*/ int_mode);
+ int32_t /*ColorMode*/ int_mode);
+ static int32_t SetColorModeWithRenderIntent(hwc2_device_t *device, hwc2_display_t display,
+ int32_t /*ColorMode*/ int_mode,
+ int32_t /*RenderIntent*/ int_render_intent);
static int32_t SetColorTransform(hwc2_device_t *device, hwc2_display_t display,
const float *matrix, int32_t /*android_color_transform_t*/ hint);
static int32_t GetReadbackBufferAttributes(hwc2_device_t *device, hwc2_display_t display,
@@ -258,6 +265,7 @@
android::Parcel *output_parcel);
android::status_t SetMixerResolution(const android::Parcel *input_parcel);
android::status_t SetColorModeOverride(const android::Parcel *input_parcel);
+ android::status_t SetColorModeWithRenderIntentOverride(const android::Parcel *input_parcel);
android::status_t SetColorModeById(const android::Parcel *input_parcel);
android::status_t getComposerStatus();