drm_hwcomposer: Remove CTM property check for SKIP_CLIENT_COLOR_TRANSFORM
CTM property does not support 4x4 matrices. Allow client composition in
these cases.
Ensure that when all layers are client composited, we clear DRM CTM.
Change-Id: Id922afff7c2b7a4786ee36c1094892e0ef27fd57
Signed-off-by: Sasha McIntosh <sashamcintosh@google.com>
diff --git a/hwc2_device/HwcDisplay.cpp b/hwc2_device/HwcDisplay.cpp
index abc15fd..02e3b0c 100644
--- a/hwc2_device/HwcDisplay.cpp
+++ b/hwc2_device/HwcDisplay.cpp
@@ -48,6 +48,11 @@
0.0F, 0.0F, 1.0F, 0.0F, 0.0F, 0.0F, 0.0F, 1.0F,
};
+bool float_equals(float a, float b) {
+ const float epsilon = 0.001F;
+ return std::abs(a - b) < epsilon;
+}
+
uint64_t To3132FixPt(float in) {
constexpr uint64_t kSignMask = (1ULL << 63);
constexpr uint64_t kValueMask = ~(1ULL << 63);
@@ -57,6 +62,16 @@
return static_cast<uint64_t>(in * kValueScale) & kValueMask;
}
+bool TransformHasOffsetValue(const float *matrix) {
+ for (int i = 12; i < 14; i++) {
+ if (!float_equals(matrix[i], 0.F)) {
+ ALOGW("DRM API does not support CTM with offsets.");
+ return true;
+ }
+ }
+ return false;
+}
+
auto ToColorTransform(const std::array<float, 16> &color_transform_matrix) {
/* HAL provides a 4x4 float type matrix:
* | 0 1 2 3|
@@ -134,35 +149,31 @@
if (type_ == HWC2::DisplayType::Virtual) {
writeback_layer_ = std::make_unique<HwcLayer>(this);
}
+
+ identity_color_matrix_ = ToColorTransform(kIdentityMatrix);
}
void HwcDisplay::SetColorTransformMatrix(
const std::array<float, 16> &color_transform_matrix) {
- auto almost_equal = [](auto a, auto b) {
- const float epsilon = 0.001F;
- return std::abs(a - b) < epsilon;
- };
const bool is_identity = std::equal(color_transform_matrix.begin(),
color_transform_matrix.end(),
- kIdentityMatrix.begin(), almost_equal);
+ kIdentityMatrix.begin(), float_equals);
color_transform_hint_ = is_identity ? HAL_COLOR_TRANSFORM_IDENTITY
: HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX;
+ ctm_has_offset_ = false;
+
if (color_transform_hint_ == is_identity) {
SetColorMatrixToIdentity();
} else {
+ if (TransformHasOffsetValue(color_transform_matrix.data()))
+ ctm_has_offset_ = true;
+
color_matrix_ = ToColorTransform(color_transform_matrix);
}
}
void HwcDisplay::SetColorMatrixToIdentity() {
- color_matrix_ = std::make_shared<drm_color_ctm>();
- for (int i = 0; i < kCtmCols; i++) {
- for (int j = 0; j < kCtmRows; j++) {
- constexpr uint64_t kOne = (1ULL << 32); /* 1.0 in s31.32 format */
- color_matrix_->matrix[(i * kCtmRows) + j] = (i == j) ? kOne : 0;
- }
- }
-
+ color_matrix_ = identity_color_matrix_;
color_transform_hint_ = HAL_COLOR_TRANSFORM_IDENTITY;
}
@@ -781,6 +792,7 @@
}
// order the layers by z-order
+ size_t client_layer_count = 0;
bool use_client_layer = false;
uint32_t client_z_order = UINT32_MAX;
std::map<uint32_t, HwcLayer *> z_map;
@@ -802,12 +814,20 @@
case HWC2::Composition::Client:
// Place it at the z_order of the lowest client layer
use_client_layer = true;
+ client_layer_count++;
client_z_order = std::min(client_z_order, layer.GetZOrder());
break;
default:
continue;
}
}
+
+ // CTM will be applied by the client, don't apply DRM CTM
+ if (client_layer_count == layers_.size())
+ a_args.color_matrix = identity_color_matrix_;
+ else
+ a_args.color_matrix = color_matrix_;
+
if (use_client_layer) {
z_map.emplace(client_z_order, &client_layer_);
@@ -971,6 +991,7 @@
return HWC2::Error::BadParameter;
color_transform_hint_ = static_cast<android_color_transform_t>(hint);
+ ctm_has_offset_ = false;
if (IsInHeadlessMode())
return HWC2::Error::None;
@@ -985,10 +1006,9 @@
case HAL_COLOR_TRANSFORM_ARBITRARY_MATRIX:
// Without HW support, we cannot correctly process matrices with an offset.
{
- for (int i = 12; i < 14; i++) {
- if (matrix[i] != 0.F)
- return HWC2::Error::Unsupported;
- }
+ if (TransformHasOffsetValue(matrix))
+ ctm_has_offset_ = true;
+
std::array<float, 16> aidl_matrix = kIdentityMatrix;
memcpy(aidl_matrix.data(), matrix, aidl_matrix.size() * sizeof(float));
color_matrix_ = ToColorTransform(aidl_matrix);
@@ -1005,7 +1025,7 @@
if (color_transform_hint_ == HAL_COLOR_TRANSFORM_IDENTITY)
return false;
- if (GetPipe().crtc->Get()->GetCtmProperty())
+ if (GetPipe().crtc->Get()->GetCtmProperty() && !ctm_has_offset_)
return false;
if (GetHwc()->GetResMan().GetCtmHandling() == CtmHandling::kDrmOrIgnore)
@@ -1278,11 +1298,6 @@
if (GetHwc()->GetResMan().GetCtmHandling() == CtmHandling::kDrmOrIgnore)
skip_ctm = true;
- // Skip client CTM if DRM can handle it
- if (!skip_ctm && !IsInHeadlessMode() &&
- GetPipe().crtc->Get()->GetCtmProperty())
- skip_ctm = true;
-
if (!skip_ctm) {
*outNumCapabilities = 0;
return HWC2::Error::None;