hwc2: Add per layer matrix transformation support
This change adds support for the HWC2.3 per layer
matrix transform API.
CRs-Fixed: 2411786
Change-Id: I900f3a8a426be43cf24f05b5dd6be9582c9b5a6c
diff --git a/sdm/include/core/layer_stack.h b/sdm/include/core/layer_stack.h
index 8d429a2..9aba8fa 100644
--- a/sdm/include/core/layer_stack.h
+++ b/sdm/include/core/layer_stack.h
@@ -152,6 +152,9 @@
uint32_t single_buffer : 1; //!< This flag shall be set by client to indicate that the layer
//!< uses only a single buffer that will not be swapped out
+
+ uint32_t color_transform : 1; //!< This flag will be set by SDM when the layer
+ //!< has a custom matrix
};
uint32_t flags = 0; //!< For initialization purpose only.
@@ -361,6 +364,10 @@
//!< needed on this layer.
LayerSolidFill solid_fill_info = {}; //!< solid fill info along with depth.
std::shared_ptr<LayerBufferMap> buffer_map = nullptr; //!< Map of handle_id and fb_id.
+ float color_transform_matrix[kColorTransformMatrixSize] = { 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 };
};
/*! @brief This structure defines the color space + transfer of a given layer.
diff --git a/sdm/include/utils/constants.h b/sdm/include/utils/constants.h
index 342f436..e34ce60 100644
--- a/sdm/include/utils/constants.h
+++ b/sdm/include/utils/constants.h
@@ -78,6 +78,11 @@
const int kPageSize = 4096;
const uint32_t kGridSize = 129; // size used for non-linear transformation before Tone-mapping
const uint32_t kLutDim = 17; // Dim of the 3d LUT for tone-mapping.
+ const int kColorTransformMatrixSize = 16;
+ const float kIdentityMatrix[kColorTransformMatrixSize] = { 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 };
typedef void * Handle;
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 5a12549..ee55829 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -669,7 +669,6 @@
metadata_refresh_rate_ = 0;
layer_stack_.flags.animating = animating_;
layer_stack_.flags.fast_path = fast_path_enabled_ && fast_path_composition_;
-
// Add one layer for fb target
for (auto hwc_layer : layer_set_) {
// Reset layer data which SDM may change
@@ -790,6 +789,10 @@
layer->flags.updating = IsLayerUpdating(hwc_layer);
}
+ if (hwc_layer->IsColorTransformSet()) {
+ layer->flags.color_transform = true;
+ }
+
layer_stack_.layers.push_back(layer);
}
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 04896bc..8cdf63d 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -534,6 +534,20 @@
geometry_changes_ |= kZOrder;
z_ = z;
}
+
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerColorTransform(const float *matrix) {
+ std::memcpy(layer_->color_transform_matrix, matrix, sizeof(layer_->color_transform_matrix));
+ needs_validate_ = true;
+
+ if (!std::memcmp(matrix, kIdentityMatrix, sizeof(kIdentityMatrix))) {
+ color_transform_matrix_set_ = false;
+ } else {
+ color_transform_matrix_set_ = true;
+ }
+
return HWC2::Error::None;
}
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
index f628b53..b21c2bb 100644
--- a/sdm/libs/hwc2/hwc_layers.h
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -90,6 +90,7 @@
HWC2::Error SetLayerPerFrameMetadata(uint32_t num_elements, const PerFrameMetadataKey *keys,
const float *metadata);
HWC2::Error SetLayerZOrder(uint32_t z);
+ HWC2::Error SetLayerColorTransform(const float *matrix);
void SetComposition(const LayerComposition &sdm_composition);
HWC2::Composition GetClientRequestedCompositionType() { return client_requested_; }
void UpdateClientCompositionType(HWC2::Composition type) { client_requested_ = type; }
@@ -111,6 +112,7 @@
void SetPartialUpdate(bool enabled) { partial_update_enabled_ = enabled; }
bool IsNonIntegralSourceCrop() { return non_integral_source_crop_; }
bool HasMetaDataRefreshRate() { return has_metadata_refresh_rate_; }
+ bool IsColorTransformSet() { return color_transform_matrix_set_; }
private:
Layer *layer_ = nullptr;
@@ -131,6 +133,7 @@
bool surface_updated_ = true;
bool non_integral_source_crop_ = false;
bool has_metadata_refresh_rate_ = false;
+ bool color_transform_matrix_set_ = false;
// Composition requested by client(SF)
HWC2::Composition client_requested_ = HWC2::Composition::Device;
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index aa19a89..90aecb1 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -883,6 +883,12 @@
return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::SetLayerZOrder, layer, z);
}
+static int32_t SetLayerColorTransform(hwc2_device_t *device, hwc2_display_t display,
+ hwc2_layer_t layer, const float *matrix) {
+ return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerColorTransform,
+ matrix);
+}
+
int32_t HWCSession::SetOutputBuffer(hwc2_device_t *device, hwc2_display_t display,
buffer_handle_t buffer, int32_t releaseFence) {
if (!device) {
@@ -1133,6 +1139,8 @@
case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
return AsFP<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>
(HWCSession::GetDisplayIdentificationData);
+ case HWC2::FunctionDescriptor::SetLayerColorTransform:
+ return AsFP<HWC2_PFN_SET_LAYER_COLOR_TRANSFORM>(SetLayerColorTransform);
default:
DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
to_string(descriptor).c_str());