summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlinpeter <linpeter@google.com>2018-12-25 20:02:31 +0800
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-01-25 00:15:14 +0000
commit3babe4e2b500f7cf873aea676d5a96ae4b126184 (patch)
tree510a7cd442886bab031399a963112a3ba72a5649
parentc08505deb4f69b726c70b2d80bc6cc1a8e43f06f (diff)
downloadandroid_hardware_qcom_sdm710_display-3babe4e2b500f7cf873aea676d5a96ae4b126184.tar.gz
android_hardware_qcom_sdm710_display-3babe4e2b500f7cf873aea676d5a96ae4b126184.tar.bz2
android_hardware_qcom_sdm710_display-3babe4e2b500f7cf873aea676d5a96ae4b126184.zip
hwc2: Add saturation matrix
Using transfer matrix to boost adaptive color mode Bug: 121231574 Test: Color pattern check and switch mode test Change-Id: I1761800e3f0dec5a5f2ba961ea2da602c2215210 (cherry picked from commit a654775321b1c56626cc08a37cad9e0609cc1c5d)
-rw-r--r--include/display_properties.h3
-rw-r--r--sdm/libs/hwc2/hwc_display.cpp285
-rw-r--r--sdm/libs/hwc2/hwc_display.h172
-rw-r--r--sdm/libs/hwc2/hwc_display_primary.cpp6
-rw-r--r--sdm/libs/hwc2/hwc_display_primary.h2
-rw-r--r--sdm/libs/hwc2/hwc_session.cpp6
-rw-r--r--sdm/libs/hwc2/hwc_session.h2
7 files changed, 317 insertions, 159 deletions
diff --git a/include/display_properties.h b/include/display_properties.h
index 06f4e64f..e59e800e 100644
--- a/include/display_properties.h
+++ b/include/display_properties.h
@@ -94,7 +94,8 @@
#define ENABLE_DEFAULT_COLOR_MODE DISPLAY_PROP("enable_default_color_mode")
#define DISABLE_HDR DISPLAY_PROP("disable_hdr")
#define DATASPACE_SATURATION_MATRIX_PROP DISPLAY_PROP("dataspace_saturation_matrix")
-#define WHITE_POINT_COMPENSATED_COEFFICIENT_PROP DISPLAY_PROP("white_point_compensated_coefficient")
+#define ADAPTIVE_WHITE_COEFFICIENT_PROP DISPLAY_PROP("adaptive_white_coefficient")
+#define ADAPTIVE_SATURATION_PARAMETER_PROP DISPLAY_PROP("adaptive_saturation_parameter")
#define HDR_CONFIG_PROP RO_DISPLAY_PROP("hdr.config")
#define QDCM_PCC_TRANS_PROP DISPLAY_PROP("qdcm.pcc_for_trans")
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 03e4cc36..5940dc2c 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -54,8 +54,7 @@ HWCColorMode::HWCColorMode(DisplayInterface *display_intf) : display_intf_(displ
HWC2::Error HWCColorMode::Init() {
PopulateColorModes();
- if (GetWhitePointCompensatedCoefficients())
- white_point_compensated_ = PaserWhitePointCompensatedData();
+ InitColorCompensation();
return ApplyDefaultColorMode();
}
@@ -145,130 +144,238 @@ HWC2::Error HWCColorMode::SetColorModeById(int32_t color_mode_id) {
return HWC2::Error::None;
}
-HWC2::Error HWCColorMode::SetWhitePointCompensation(bool enabled) {
- white_point_compensated_ = enabled;
- if (white_point_compensated_) {
- PaserWhitePointCompensatedData();
- ApplyWhitePointCompensationToMatrix(white_point_compensated_color_matrix_, color_matrix_);
+HWC2::Error HWCColorMode::RestoreColorTransform() {
+ DisplayError error =
+ display_intf_->SetColorTransform(kColorTransformMatrixCount, PickTransferMatrix());
+ if (error != kErrorNone) {
+ DLOGE("Failed to set Color Transform");
+ return HWC2::Error::BadParameter;
}
- RestoreColorTransform();
-
- DLOGI("Set White Point Compensation: %d", enabled);
return HWC2::Error::None;
}
-HWC2::Error HWCColorMode::RestoreColorTransform() {
+void HWCColorMode::InitColorCompensation() {
+ char value[kPropertyMax] = {0};
+ if (Debug::Get()->GetProperty(ADAPTIVE_WHITE_COEFFICIENT_PROP, value) == kErrorNone) {
+ adaptive_white_ = std::make_unique<WhiteCompensation>(string(value));
+ adaptive_white_->SetEnabled(true);
+ }
+ std::memset(value, 0, sizeof(value));
+ if (Debug::Get()->GetProperty(ADAPTIVE_SATURATION_PARAMETER_PROP, value) == kErrorNone) {
+ adaptive_saturation_ = std::make_unique<SaturationCompensation>(string(value));
+ adaptive_saturation_->SetEnabled(true);
+ }
+}
- DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount,
- GetTransferMatrix());
- if (error != kErrorNone) {
- DLOGE("Failed to set Color Transform");
- return HWC2::Error::BadParameter;
+const double *HWCColorMode::PickTransferMatrix() {
+ double matrix[kColorTransformMatrixCount] = {0};
+ if (current_render_intent_ == RenderIntent::ENHANCE) {
+ CopyColorTransformMatrix(color_matrix_, matrix);
+ if (HasSaturationCompensation())
+ adaptive_saturation_->ApplyToMatrix(matrix);
+
+ if (HasWhiteCompensation())
+ adaptive_white_->ApplyToMatrix(matrix);
+
+ CopyColorTransformMatrix(matrix, compensated_color_matrix_);
+ return compensated_color_matrix_;
+ } else {
+ return color_matrix_;
}
+}
+
+HWC2::Error HWCColorMode::SetWhiteCompensation(bool enabled) {
+ if (adaptive_white_ == NULL)
+ return HWC2::Error::Unsupported;
+ if (adaptive_white_->SetEnabled(enabled) != HWC2::Error::None) {
+ return HWC2::Error::NotValidated;
+ }
+
+ RestoreColorTransform();
+
+ DLOGI("Set White Point Compensation: %d", enabled);
return HWC2::Error::None;
}
-bool HWCColorMode::PaserWhitePointCompensatedData() {
- static constexpr char kWhitePointCalibrationDataPath[] = "/persist/display/calibrated_rgb";
- FILE *fp = fopen(kWhitePointCalibrationDataPath, "r");
- int compensated_red = 0;
- int compensated_green = 0;
- int compensated_blue = 0;
+HWC2::Error HWCColorMatrix::SetEnabled(bool enabled) {
+ enabled_ = enabled;
+ return HWC2::Error::None;
+}
- if (!fp) {
- compensated_red_ratio_ = 1.0;
- compensated_green_ratio_ = 1.0;
- compensated_blue_ratio_ = 1.0;
- return false;
+bool HWCColorMatrix::ParseFloatValueByCommas(const string &values, uint32_t length,
+ std::vector<float> &elements) const {
+ std::istringstream data_stream(values);
+ string data;
+ uint32_t index = 0;
+ std::vector<float> temp_elements;
+ while (std::getline(data_stream, data, ',')) {
+ temp_elements.push_back(std::move(std::stof(data.c_str())));
+ index++;
+ }
+ if (index != length) {
+ DLOGW("Insufficient elements defined");
+ return false;
+ }
+ std::move(temp_elements.begin(), temp_elements.end(), elements.begin());
+ return true;
+}
+
+HWC2::Error WhiteCompensation::SetEnabled(bool enabled) {
+ //re-parse data when set enabled for retry calibration
+ if (enabled) {
+ if (!ConfigCoefficients() || !ParseWhiteCompensatedData()) {
+ enabled_ = false;
+ DLOGE("Failed to WhiteCompensation Set");
+ return HWC2::Error::NotValidated;
}
+ CalculateRGBRatio();
+ }
+ enabled_ = enabled;
+ return HWC2::Error::None;
+}
- fscanf(fp, "%d %d %d", &compensated_red, &compensated_green, &compensated_blue);
+bool WhiteCompensation::ParseWhiteCompensatedData() {
+ static constexpr char kWhitePointCalibrationDataPath[] = "/persist/display/calibrated_rgb";
+ FILE *fp = fopen(kWhitePointCalibrationDataPath, "r");
+ int ret;
- fclose(fp);
+ if (!fp) {
+ DLOGW("Failed to open white compensated data file");
+ return false;
+ }
- // r = r_coeffient2 * R^2 + r_coeffient1 * R + r_coeffient0
- // g = g_coeffient2 * G^2 + g_coeffient1 * G + g_coeffient0
- // b = b_coeffient2 * B^2 + b_coeffient1 * B + b_coeffient0
- // r_ratio = r/kCompensatedMaxRGB
- // g_ratio = g/kCompensatedMaxRGB
- // b_ratio = b/kCompensatedMaxRGB
- auto rgb_ratio = [=](int rgb, float c2, float c1, float c0) {
- return ((c2 * rgb * rgb + c1 * rgb + c0) / kCompensatedMaxRGB);};
+ ret = fscanf(fp, "%d %d %d", &compensated_red_, &compensated_green_, &compensated_blue_);
+ fclose(fp);
- compensated_red_ratio_ = rgb_ratio(CheckCompensatedRGB(compensated_red), white_point_compensated_Coefficients_[0],
- white_point_compensated_Coefficients_[1], white_point_compensated_Coefficients_[2]);
- compensated_green_ratio_ = rgb_ratio(CheckCompensatedRGB(compensated_green), white_point_compensated_Coefficients_[3],
- white_point_compensated_Coefficients_[4], white_point_compensated_Coefficients_[5]);
- compensated_blue_ratio_ = rgb_ratio(CheckCompensatedRGB(compensated_blue), white_point_compensated_Coefficients_[6],
- white_point_compensated_Coefficients_[7], white_point_compensated_Coefficients_[8]);
+ if ((ret == kNumOfCompensationData) && CheckCompensatedRGB(compensated_red_) &&
+ CheckCompensatedRGB(compensated_green_) && CheckCompensatedRGB(compensated_blue_)) {
+ DLOGD("Compensated RGB: %d %d %d", compensated_red_, compensated_green_, compensated_blue_);
return true;
+ } else {
+ compensated_red_ = kCompensatedMaxRGB;
+ compensated_green_ = kCompensatedMaxRGB;
+ compensated_blue_ = kCompensatedMaxRGB;
+ DLOGE("Failed to get white compensated data");
+ return false;
+ }
}
-bool HWCColorMode::GetWhitePointCompensatedCoefficients() {
- char value[kPropertyMax] = {};
- if (Debug::Get()->GetProperty(WHITE_POINT_COMPENSATED_COEFFICIENT_PROP, value) != kErrorNone) {
- DLOGW("Undefined Compensated Coefficients");
+bool WhiteCompensation::ConfigCoefficients() {
+ std::vector<float> CompensatedCoefficients(kCoefficientElements);
+ if (!ParseFloatValueByCommas(key_values_, kCoefficientElements, CompensatedCoefficients))
return false;
+ std::move(CompensatedCoefficients.begin(), CompensatedCoefficients.end(),
+ white_compensated_Coefficients_);
+ for (const auto &c : white_compensated_Coefficients_) {
+ DLOGD("white_compensated_Coefficients_=%f", c);
}
+ return true;
+}
- std::string value_string(value);
- std::size_t start = 0, end = 0;
- int index = 0;
- // We need 9 coneffients, 3 for red, 3 for green, 3 for blue.
- float CompensatedCoefficients[kCompensatedCoefficientElements] = { 1.0, 1.0, 1.0, \
- 1.0, 1.0, 1.0, \
- 1.0, 1.0, 1.0 };
+void WhiteCompensation::CalculateRGBRatio() {
+ // r = r_coeffient2 * R^2 + r_coeffient1 * R + r_coeffient0
+ // g = g_coeffient2 * G^2 + g_coeffient1 * G + g_coeffient0
+ // b = b_coeffient2 * B^2 + b_coeffient1 * B + b_coeffient0
+ // r_ratio = r/kCompensatedMaxRGB
+ // g_ratio = g/kCompensatedMaxRGB
+ // b_ratio = b/kCompensatedMaxRGB
+ auto rgb_ratio = [=](int rgb, float c2, float c1, float c0) {
+ return ((c2 * rgb * rgb + c1 * rgb + c0) / kCompensatedMaxRGB);
+ };
+
+ compensated_red_ratio_ =
+ rgb_ratio(compensated_red_, white_compensated_Coefficients_[0],
+ white_compensated_Coefficients_[1], white_compensated_Coefficients_[2]);
+ compensated_green_ratio_ =
+ rgb_ratio(compensated_green_, white_compensated_Coefficients_[3],
+ white_compensated_Coefficients_[4], white_compensated_Coefficients_[5]);
+ compensated_blue_ratio_ =
+ rgb_ratio(compensated_blue_, white_compensated_Coefficients_[6],
+ white_compensated_Coefficients_[7], white_compensated_Coefficients_[8]);
+ DLOGI("Compensated ratio %f %f %f", compensated_red_ratio_, compensated_green_ratio_,
+ compensated_blue_ratio_);
+}
+
+void WhiteCompensation::ApplyToMatrix(double *in) {
+ double matrix[kColorTransformMatrixCount] = {0};
+ for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
+ if ((i % 4) == 0)
+ matrix[i] = compensated_red_ratio_ * in[i];
+ else if ((i % 4) == 1)
+ matrix[i] = compensated_green_ratio_ * in[i];
+ else if ((i % 4) == 2)
+ matrix[i] = compensated_blue_ratio_ * in[i];
+ else if ((i % 4) == 3)
+ matrix[i] = in[i];
+ }
+ std::move(&matrix[0], &matrix[kColorTransformMatrixCount - 1], in);
+}
- // The property must have kCompensatedCoefficientElements delimited by commas
- while ((end = value_string.find(",", start)) != std::string::npos) {
- CompensatedCoefficients[index] = std::stof(value_string.substr(start, end - start));
- start = end + 1;
- index++;
- if (index > kCompensatedCoefficientElements - 1) {
- DLOGW("Over Compensated Coefficients defined");
- return false;
+HWC2::Error SaturationCompensation::SetEnabled(bool enabled) {
+ if (enabled == enabled_)
+ return HWC2::Error::None;
+
+ if (enabled) {
+ if (!ConfigSaturationParameter()) {
+ enabled_ = false;
+ return HWC2::Error::NotValidated;
}
}
+ enabled_ = enabled;
+ return HWC2::Error::None;
+}
- if (index < kCompensatedCoefficientElements - 1) {
- DLOGW("Less Compensated Coefficients defined");
+bool SaturationCompensation::ConfigSaturationParameter() {
+ std::vector<float> SaturationParameter(kSaturationParameters);
+ if (!ParseFloatValueByCommas(key_values_, kSaturationParameters, SaturationParameter))
return false;
- }
- CompensatedCoefficients[index] = std::stof(value_string.substr(start, end - start));
-
- for (int32_t i = 0; i < kCompensatedCoefficientElements; i++) {
- white_point_compensated_Coefficients_[i] = CompensatedCoefficients[i];
- DLOGD("CompensatedCoefficients[%d]=%f",i, CompensatedCoefficients[i]);
+ int32_t matrix_index = 0;
+ for (uint32_t i = 0; i < SaturationParameter.size(); i++) {
+ saturated_matrix_[matrix_index] = SaturationParameter.at(i);
+ // Put parameters to matrix and keep the last row/column identity
+ if ((i + 1) % 3 == 0) {
+ matrix_index += 2;
+ } else {
+ matrix_index++;
+ }
+ DLOGD("SaturationParameter[%d]=%f", i, SaturationParameter.at(i));
}
return true;
}
+void SaturationCompensation::ApplyToMatrix(double *in) {
+ double matrix[kColorTransformMatrixCount] = {0};
+ // 4 x 4 matrix multiplication
+ for (uint32_t i = 0; i < kNumOfRows; i++) {
+ for (uint32_t j = 0; j < kColumnsPerRow; j++) {
+ for (uint32_t k = 0; k < kColumnsPerRow; k++) {
+ matrix[j + (i * kColumnsPerRow)] +=
+ saturated_matrix_[k + (i * kColumnsPerRow)] * in[j + (k * kColumnsPerRow)];
+ }
+ }
+ }
+ std::move(&matrix[0], &matrix[kColorTransformMatrixCount - 1], in);
+}
+
HWC2::Error HWCColorMode::SetColorTransform(const float *matrix,
android_color_transform_t /*hint*/) {
DTRACE_SCOPED();
auto status = HWC2::Error::None;
- double color_matrix[kColorTransformMatrixCount] = {0};
- double white_point_compensated_color_matrix[kColorTransformMatrixCount] = {0};
- CopyColorTransformMatrix(matrix, color_matrix);
+ double color_matrix_restore[kColorTransformMatrixCount] = {0};
+ CopyColorTransformMatrix(color_matrix_, color_matrix_restore);
- if (white_point_compensated_)
- ApplyWhitePointCompensationToMatrix(white_point_compensated_color_matrix, color_matrix);
+ CopyColorTransformMatrix(matrix, color_matrix_);
- DisplayError error = display_intf_->SetColorTransform(kColorTransformMatrixCount,
- NeedWhitePointCompensated() ?
- white_point_compensated_color_matrix :
- color_matrix);
+ DisplayError error =
+ display_intf_->SetColorTransform(kColorTransformMatrixCount, PickTransferMatrix());
if (error != kErrorNone) {
+ CopyColorTransformMatrix(color_matrix_restore, color_matrix_);
DLOGE("Failed to set Color Transform Matrix");
status = HWC2::Error::Unsupported;
}
- CopyColorTransformMatrix(matrix, color_matrix_);
-
- if (white_point_compensated_)
- CopyColorTransformMatrix(white_point_compensated_color_matrix, white_point_compensated_color_matrix_);
return status;
}
@@ -418,16 +525,16 @@ void HWCColorMode::Dump(std::ostringstream* os) {
}
*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 << "Need white point compensated: " << NeedWhitePointCompensated() << ",RGB:["
- << std::fixed << std::setprecision(4)
- << compensated_red_ratio_ << ","
- << compensated_green_ratio_ << ","
- << compensated_blue_ratio_ << "] "<< std::endl;
+ *os << "Need WhiteCompensation: "
+ << (current_render_intent_ == RenderIntent::ENHANCE && HasWhiteCompensation()) << std::endl;
+ *os << "Need SaturationCompensation: "
+ << (current_render_intent_ == RenderIntent::ENHANCE && HasSaturationCompensation())
+ << std::endl;
*os << "current transform: ";
double color_matrix[kColorTransformMatrixCount] = {0};
- CopyColorTransformMatrix(GetTransferMatrix(), color_matrix);
+ CopyColorTransformMatrix(PickTransferMatrix(), color_matrix);
for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
if (i % 4 == 0) {
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index ff072174..4523cb58 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -46,6 +46,7 @@ namespace sdm {
class BlitEngine;
class HWCToneMapper;
+constexpr uint32_t kColorTransformMatrixCount = 16;
// Subclasses set this to their type. This has to be different from DisplayType.
// This is to avoid RTTI and dynamic_cast
@@ -56,6 +57,103 @@ enum DisplayClass {
DISPLAY_CLASS_NULL
};
+class HWCColorMatrix {
+ public:
+ HWCColorMatrix(const string &values) : key_values_(values){};
+ virtual ~HWCColorMatrix() = default;
+ virtual HWC2::Error SetEnabled(bool enabled);
+ bool GetEnabled() const { return enabled_; }
+ // Apply effect to input matrix
+ virtual void ApplyToMatrix(double *in) = 0;
+ bool ParseFloatValueByCommas(const string &values, uint32_t length,
+ std::vector<float> &elements) const;
+
+ protected:
+ bool enabled_ = false;
+ const string key_values_;
+};
+
+class WhiteCompensation : public HWCColorMatrix {
+ public:
+ WhiteCompensation(const string &values) : HWCColorMatrix(values){};
+ int GetCompensatedRed() const { return compensated_red_; }
+ int GetCompensatedGreen() const { return compensated_green_; }
+ int GetCompensatedBlue() const { return compensated_blue_; }
+ HWC2::Error SetEnabled(bool enabled) override;
+ /*
+ * Transform matrix is 4 x 4
+ * |r.r r.g r.b 0|
+ * |g.r g.g g.b 0|
+ * |b.r b.g b.b 0|
+ * |T.r T.g T.b 1|
+ * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
+ * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
+ * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
+ *
+ * Cr, Cg, Cb for white point compensation
+ * |r.r*Cr r.g*Cg r.b*Cb 0|
+ * |g.r*Cr g.g*Cg g.b*Cb 0|
+ * |b.r*Cr b.g*Cg b.b*Cb 0|
+ * |T.r*Cr T.g*Cg T.b*Cb 1|
+ * R_out = R_in * r.r * Cr + G_in * g.r * Cr + B_in * b.r * Cr + Tr * Cr
+ * G_out = R_in * r.g * Cg + G_in * g.g * Cg + B_in * b.g * Cg + Tg * Cg
+ * B_out = R_in * r.b * Cb + G_in * g.b * Cb + B_in * b.b * Cb + Tb * Cb
+ */
+ void ApplyToMatrix(double *in) override;
+
+ private:
+ static constexpr int kCompensatedMaxRGB = 255;
+ static constexpr int kCompensatedMinRGB = 230;
+ static constexpr int kNumOfCompensationData = 3;
+ int compensated_red_ = kCompensatedMaxRGB;
+ int compensated_green_ = kCompensatedMaxRGB;
+ int compensated_blue_ = kCompensatedMaxRGB;
+
+ double compensated_red_ratio_ = 1.0;
+ double compensated_green_ratio_ = 1.0;
+ double compensated_blue_ratio_ = 1.0;
+
+ static constexpr int kCoefficientElements = 9;
+ float white_compensated_Coefficients_[kCoefficientElements] = {0.0, 1.0, 0.0, 0.0, 1.0,
+ 0.0, 0.0, 1.0, 0.0};
+ bool ConfigCoefficients();
+ bool ParseWhiteCompensatedData();
+ inline static constexpr bool CheckCompensatedRGB(int value) {
+ return ((value >= kCompensatedMinRGB) && (value <= kCompensatedMaxRGB));
+ }
+ void CalculateRGBRatio();
+};
+
+class SaturationCompensation : public HWCColorMatrix {
+ public:
+ SaturationCompensation(const string &values) : HWCColorMatrix(values){};
+ HWC2::Error SetEnabled(bool enabled) override;
+ /* Saturated matrix is 4 x 4
+ * | s0 s1 s2 s3|
+ * | s4 s5 s6 s7|
+ * | s8 s9 s10 s11|
+ * | s12 s13 s14 s15|
+ * Transform matrix is 4 x 4
+ * |a0 a1 a2 a3|
+ * |a4 a5 a6 a7|
+ * |a8 a9 a10 a11|
+ * |a12 a13 a14 a15|
+ *
+ * Saturated matrix[] X Transform matrix[]
+ */
+ void ApplyToMatrix(double *in) override;
+
+ private:
+ static constexpr int kSaturationParameters = 9;
+ static constexpr int kNumOfRows = 4;
+ static constexpr int kColumnsPerRow = 4;
+ static_assert(kNumOfRows * kColumnsPerRow == kColorTransformMatrixCount,
+ "Rows x Columns should be equal to matrix count");
+ float saturated_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, 0.0, 0.0, 0.0, 1.0};
+ bool ConfigSaturationParameter();
+};
+
class HWCColorMode {
public:
explicit HWCColorMode(DisplayInterface *display_intf);
@@ -73,10 +171,9 @@ class HWCColorMode {
HWC2::Error RestoreColorTransform();
PrimariesTransfer GetWorkingColorSpace();
ColorMode GetCurrentColorMode() { return current_color_mode_; }
- HWC2::Error SetWhitePointCompensation(bool enabled);
+ HWC2::Error SetWhiteCompensation(bool enabled);
private:
- static const uint32_t kColorTransformMatrixCount = 16;
void PopulateColorModes();
void FindRenderIntent(const ColorMode &mode, const std::string &mode_string);
template <class T>
@@ -98,65 +195,18 @@ class HWCColorMode {
0.0, 1.0, 0.0, 0.0, \
0.0, 0.0, 1.0, 0.0, \
0.0, 0.0, 0.0, 1.0 };
- /*
- * Transform matrix is 4 x 4
- * |r.r r.g r.b 0|
- * |g.r g.g g.b 0|
- * |b.r b.g b.b 0|
- * |T.r T.g T.b 1|
- * R_out = R_in * r.r + G_in * g.r + B_in * b.r + Tr
- * G_out = R_in * r.g + G_in * g.g + B_in * b.g + Tg
- * B_out = R_in * r.b + G_in * g.b + B_in * b.b + Tb
- *
- * Cr, Cg, Cb for white point compensation
- * |r.r*Cr r.g*Cg r.b*Cb 0|
- * |g.r*Cr g.g*Cg g.b*Cb 0|
- * |b.r*Cr b.g*Cg b.b*Cb 0|
- * |T.r*Cr T.g*Cg T.b*Cb 1|
- * R_out = R_in * r.r * Cr + G_in * g.r * Cr + B_in * b.r * Cr + Tr * Cr
- * G_out = R_in * r.g * Cg + G_in * g.g * Cg + B_in * b.g * Cg + Tg * Cg
- * B_out = R_in * r.b * Cb + G_in * g.b * Cb + B_in * b.b * Cb + Tb * Cb
- */
- static constexpr int kCompensatedMaxRGB = 255;
- static constexpr int kCompensatedMinRGB = 230;
- static constexpr int kCompensatedCoefficientElements = 9;
- double white_point_compensated_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, \
- 0.0, 0.0, 0.0, 1.0 };
- bool PaserWhitePointCompensatedData();
- float white_point_compensated_Coefficients_[kCompensatedCoefficientElements] = {
- 1.0, 1.0, 1.0, \
- 1.0, 1.0, 1.0, \
- 1.0, 1.0, 1.0 };
-
- bool GetWhitePointCompensatedCoefficients();
- bool NeedWhitePointCompensated() { return (current_render_intent_ == RenderIntent::ENHANCE) &&
- white_point_compensated_; }
- double * GetTransferMatrix() { return NeedWhitePointCompensated() ? white_point_compensated_color_matrix_
- : color_matrix_;}
- bool white_point_compensated_ = false;
- double compensated_red_ratio_ = 1.0;
- double compensated_green_ratio_ = 1.0;
- double compensated_blue_ratio_ = 1.0;
- inline static constexpr int CheckCompensatedRGB (int value) {
- return ((value < kCompensatedMinRGB) ? kCompensatedMinRGB :
- (value > kCompensatedMaxRGB) ? kCompensatedMaxRGB : value);
- }
-
- void ApplyWhitePointCompensationToMatrix(double *out, double *in) {
- for (uint32_t i = 0; i < kColorTransformMatrixCount; i++) {
- if ((i % 4) == 0)
- out[i] = compensated_red_ratio_ * in[i];
- else if ((i % 4) == 1)
- out[i] = compensated_green_ratio_ * in[i];
- else if ((i % 4) == 2)
- out[i] = compensated_blue_ratio_ * in[i];
- else if ((i % 4) == 3)
- out[i] = in[i];
- }
+ void InitColorCompensation();
+ std::unique_ptr<WhiteCompensation> adaptive_white_;
+ std::unique_ptr<SaturationCompensation> adaptive_saturation_;
+ double compensated_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, \
+ 0.0, 0.0, 0.0, 1.0};
+ bool HasWhiteCompensation() { return (adaptive_white_ && adaptive_white_->GetEnabled()); }
+ bool HasSaturationCompensation() {
+ return (adaptive_saturation_ && adaptive_saturation_->GetEnabled());
}
+ const double *PickTransferMatrix();
};
class HWCDisplay : public DisplayEventHandler {
@@ -262,7 +312,7 @@ class HWCDisplay : public DisplayEventHandler {
virtual HWC2::Error SetClientTarget(buffer_handle_t target, int32_t acquire_fence,
int32_t dataspace, hwc_region_t damage);
virtual HWC2::Error SetColorMode(ColorMode mode) { return HWC2::Error::Unsupported; }
- virtual HWC2::Error SetWhitePointCompensation(bool enabled) { return HWC2::Error::Unsupported; }
+ virtual HWC2::Error SetWhiteCompensation(bool enabled) { return HWC2::Error::Unsupported; }
virtual HWC2::Error SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent) {
return HWC2::Error::Unsupported;
}
diff --git a/sdm/libs/hwc2/hwc_display_primary.cpp b/sdm/libs/hwc2/hwc_display_primary.cpp
index 6eaf11db..4d70d7fa 100644
--- a/sdm/libs/hwc2/hwc_display_primary.cpp
+++ b/sdm/libs/hwc2/hwc_display_primary.cpp
@@ -343,10 +343,10 @@ HWC2::Error HWCDisplayPrimary::SetColorMode(ColorMode mode) {
return SetColorModeWithRenderIntent(mode, RenderIntent::COLORIMETRIC);
}
-HWC2::Error HWCDisplayPrimary::SetWhitePointCompensation(bool enabled) {
- auto status = color_mode_->SetWhitePointCompensation(enabled);
+HWC2::Error HWCDisplayPrimary::SetWhiteCompensation(bool enabled) {
+ auto status = color_mode_->SetWhiteCompensation(enabled);
if (status != HWC2::Error::None) {
- DLOGE("failed for SetWhitePointCompensation to %d", enabled);
+ DLOGE("failed for SetWhiteCompensation to %d", enabled);
return status;
}
diff --git a/sdm/libs/hwc2/hwc_display_primary.h b/sdm/libs/hwc2/hwc_display_primary.h
index d6dcc530..0794b94a 100644
--- a/sdm/libs/hwc2/hwc_display_primary.h
+++ b/sdm/libs/hwc2/hwc_display_primary.h
@@ -58,7 +58,7 @@ class HWCDisplayPrimary : public HWCDisplay {
virtual HWC2::Error Present(int32_t *out_retire_fence);
virtual HWC2::Error GetColorModes(uint32_t *out_num_modes, ColorMode *out_modes);
virtual HWC2::Error SetColorMode(ColorMode mode);
- virtual HWC2::Error SetWhitePointCompensation(bool enabled);
+ virtual HWC2::Error SetWhiteCompensation(bool enabled);
virtual HWC2::Error GetRenderIntents(ColorMode mode, uint32_t *out_num_intents,
RenderIntent *out_intents);
virtual HWC2::Error SetColorModeWithRenderIntent(ColorMode mode, RenderIntent intent);
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index 2691a42f..570e0fe3 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -1360,7 +1360,7 @@ android::status_t HWCSession::notifyCallback(uint32_t command, const android::Pa
DLOGE("QService command = %d: input_parcel needed.", command);
break;
}
- status = SetWhitePointCompensation(input_parcel);
+ status = SetWhiteCompensation(input_parcel);
break;
default:
@@ -1559,12 +1559,12 @@ android::status_t HWCSession::SetColorModeOverride(const android::Parcel *input_
return 0;
}
-android::status_t HWCSession::SetWhitePointCompensation(const android::Parcel *input_parcel) {
+android::status_t HWCSession::SetWhiteCompensation(const android::Parcel *input_parcel) {
auto display = static_cast<hwc2_display_t >(input_parcel->readInt32());
auto enabled = static_cast<bool >(input_parcel->readInt32());
auto device = static_cast<hwc2_device_t *>(this);
- auto err = CallDisplayFunction(device, display, &HWCDisplay::SetWhitePointCompensation, enabled);
+ auto err = CallDisplayFunction(device, display, &HWCDisplay::SetWhiteCompensation, enabled);
if (err != HWC2_ERROR_NONE)
return -EINVAL;
diff --git a/sdm/libs/hwc2/hwc_session.h b/sdm/libs/hwc2/hwc_session.h
index 8eb70167..6271e61d 100644
--- a/sdm/libs/hwc2/hwc_session.h
+++ b/sdm/libs/hwc2/hwc_session.h
@@ -271,7 +271,7 @@ class HWCSession : hwc2_device_t, HWCUEventListener, IDisplayConfig, public qCli
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 SetWhitePointCompensation(const android::Parcel *input_parcel);
+ android::status_t SetWhiteCompensation(const android::Parcel *input_parcel);
android::status_t SetColorModeById(const android::Parcel *input_parcel);
android::status_t getComposerStatus();