sdm: hwc2: Plumb render intent APIs
* Add support for color mode with render intents.
* Remove transform hints as they are unused.
* Add saturation matrix, read from a property by default.
Change-Id: Ic8526854cbdcb8f6fe1f2b2b260b3999a5c4571a
CRs-Fixed: 2235178
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 2cc97cb..7cb8e72 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -67,47 +67,73 @@
}
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);
+ 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();
- DLOGV_IF(kTagClient, "Color mode %d successfully set.", mode);
- return status;
+ 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 +156,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 +199,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;
if (!attr.empty()) {
for (auto &it : attr) {
if (it.first.find(kColorGamutAttribute) != std::string::npos) {
@@ -225,76 +213,52 @@
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 (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 {
+ // 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 +272,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) {
@@ -778,14 +747,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;
}
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index d35ea23..dc7d7b7 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,18 @@
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();
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 +94,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 +208,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 +231,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,
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_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 237343f..d9409a8 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,65 @@
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 GetDisplayAttribute(hwc2_device_t *device, hwc2_display_t display,
hwc2_config_t config, int32_t int_attribute,
int32_t *out_value) {
@@ -598,14 +658,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 +964,13 @@
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);
default:
DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
to_string(descriptor).c_str());
@@ -1202,6 +1281,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 +1481,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 +1491,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();