hwc2: Add support for HDR10PLUS
- Add support HDR10PLUS hdr capability.
- Add support for SetLayerPerFrameMetadataBlobs from composer 2.3.
- Populate the dynamic metadata from the new composer API into
the layer structure and set validate if the data changes.
- Prioritize PerFrameMetadata/Blob over ColorMetaData.
Change-Id: Idd9b6f4f104d1584cce31a4cb7022e11eb2751ad
CRs-Fixed: 2545757
Signed-off-by: Karthi Kandasamy <kartka@codeaurora.org>
diff --git a/sdm/libs/hwc2/Android.mk b/sdm/libs/hwc2/Android.mk
index 0ec89da..306ff72 100644
--- a/sdm/libs/hwc2/Android.mk
+++ b/sdm/libs/hwc2/Android.mk
@@ -28,6 +28,7 @@
android.hardware.graphics.allocator@2.0 \
android.hardware.graphics.allocator@3.0 \
android.hardware.graphics.composer@2.2 \
+ android.hardware.graphics.composer@2.3 \
vendor.display.config@1.0 \
vendor.display.config@1.1 \
vendor.display.config@1.2 \
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 22b9f89..14ca3e6 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -1111,20 +1111,14 @@
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;
+ const uint32_t num_keys = UINT32(PerFrameMetadataKey::HDR10_PLUS_SEI) + 1;
+ if (out_keys == nullptr) {
+ *out_num_keys = num_keys;
+ } else {
+ uint32_t max_out_key_elements = std::min(*out_num_keys, num_keys);
+ for (int32_t i = 0; i < max_out_key_elements; i++) {
+ out_keys[i] = static_cast<PerFrameMetadataKey>(i);
+ }
}
return HWC2::Error::None;
}
@@ -1474,12 +1468,13 @@
}
if (out_types == nullptr) {
- // We support HDR10 and HLG
- *out_num_types = 2;
+ // We support HDR10, HLG and HDR10_PLUS.
+ *out_num_types = 3;
} else {
- // HDR10 and HLG are supported
+ // HDR10, HLG and HDR10_PLUS are supported.
out_types[0] = HAL_HDR_HDR10;
out_types[1] = HAL_HDR_HLG;
+ out_types[2] = HAL_HDR_HDR10_PLUS;
*out_max_luminance = fixed_info.max_luminance;
*out_max_average_luminance = fixed_info.average_luminance;
*out_min_luminance = fixed_info.min_luminance;
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index d8c8c4e..8bbd97e 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -551,6 +551,8 @@
HWC2::Error HWCLayer::SetLayerPerFrameMetadata(uint32_t num_elements,
const PerFrameMetadataKey *keys,
const float *metadata) {
+ auto old_mastering_display = layer_->input_buffer.color_metadata.masteringDisplayInfo;
+ auto old_content_light = layer_->input_buffer.color_metadata.contentLightLevel;
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++) {
@@ -593,6 +595,51 @@
case PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL:
content_light.minPicAverageLightLevel = UINT32(metadata[i] * 10000);
break;
+ default:
+ break;
+ }
+ }
+ if ((!SameConfig(&old_mastering_display, &mastering_display, UINT32(sizeof(MasteringDisplay)))) ||
+ (!SameConfig(&old_content_light, &content_light, UINT32(sizeof(ContentLightLevel))))) {
+ per_frame_hdr_metadata_ = true;
+ layer_->update_mask.set(kMetadataUpdate);
+ geometry_changes_ |= kDataspace;
+ }
+ return HWC2::Error::None;
+}
+
+HWC2::Error HWCLayer::SetLayerPerFrameMetadataBlobs(uint32_t num_elements,
+ const PerFrameMetadataKey *keys,
+ const uint32_t *sizes,
+ const uint8_t* metadata) {
+ if (!keys || !sizes || !metadata) {
+ DLOGE("metadata or sizes or keys is null");
+ return HWC2::Error::BadParameter;
+ }
+
+ ColorMetaData &color_metadata = layer_->input_buffer.color_metadata;
+ for (uint32_t i = 0; i < num_elements; i++) {
+ switch (keys[i]) {
+ case PerFrameMetadataKey::HDR10_PLUS_SEI:
+ if (sizes[i] > HDR_DYNAMIC_META_DATA_SZ) {
+ DLOGE("Size of HDR10_PLUS_SEI = %d", sizes[i]);
+ return HWC2::Error::BadParameter;
+ }
+ per_frame_hdr_metadata_ = false;
+ // if dynamic metadata changes, store and set needs validate
+ if (!SameConfig(static_cast<const uint8_t*>(color_metadata.dynamicMetaDataPayload),
+ metadata, sizes[i])) {
+ geometry_changes_ |= kDataspace;
+ color_metadata.dynamicMetaDataValid = true;
+ color_metadata.dynamicMetaDataLen = sizes[i];
+ std::memcpy(color_metadata.dynamicMetaDataPayload, metadata, sizes[i]);
+ per_frame_hdr_metadata_ = true;
+ layer_->update_mask.set(kMetadataUpdate);
+ }
+ break;
+ default:
+ DLOGW("Invalid key = %d", keys[i]);
+ return HWC2::Error::BadParameter;
}
}
return HWC2::Error::None;
@@ -882,6 +929,11 @@
}
void HWCLayer::ValidateAndSetCSC(const private_handle_t *handle) {
+ if (per_frame_hdr_metadata_) {
+ // Since client has set PerFrameMetadata, dataspace will be valid
+ // so we can skip reading from ColorMetaData.
+ return;
+ }
LayerBuffer *layer_buffer = &layer_->input_buffer;
bool use_color_metadata = true;
ColorMetaData csc = {};
@@ -920,6 +972,9 @@
(layer_buffer->color_metadata.range != old_meta_data.range)) {
layer_->update_mask.set(kMetadataUpdate);
}
+ DLOGV_IF(kTagClient, "Dynamic Metadata valid = %d size = %d",
+ layer_buffer->color_metadata.dynamicMetaDataValid,
+ layer_buffer->color_metadata.dynamicMetaDataLen);
if (layer_buffer->color_metadata.dynamicMetaDataValid &&
!SameConfig(layer_buffer->color_metadata.dynamicMetaDataPayload,
old_meta_data.dynamicMetaDataPayload, HDR_DYNAMIC_META_DATA_SZ)) {
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
index 10d7156..76b7c14 100644
--- a/sdm/libs/hwc2/hwc_layers.h
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -33,7 +33,7 @@
#include <hardware/hwcomposer2.h>
#undef HWC2_INCLUDE_STRINGIFICATION
#undef HWC2_USE_CPP11
-#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
+#include <android/hardware/graphics/composer/2.3/IComposerClient.h>
#include <deque>
#include <map>
#include <set>
@@ -41,7 +41,7 @@
#include "hwc_buffer_allocator.h"
using PerFrameMetadataKey =
- android::hardware::graphics::composer::V2_2::IComposerClient::PerFrameMetadataKey;
+ android::hardware::graphics::composer::V2_3::IComposerClient::PerFrameMetadataKey;
namespace sdm {
@@ -91,6 +91,8 @@
HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
HWC2::Error SetLayerPerFrameMetadata(uint32_t num_elements, const PerFrameMetadataKey *keys,
const float *metadata);
+ HWC2::Error SetLayerPerFrameMetadataBlobs(uint32_t num_elements, const PerFrameMetadataKey *keys,
+ const uint32_t *sizes, const uint8_t* metadata);
HWC2::Error SetLayerZOrder(uint32_t z);
void SetComposition(const LayerComposition &sdm_composition);
HWC2::Composition GetClientRequestedCompositionType() { return client_requested_; }
@@ -136,6 +138,7 @@
bool non_integral_source_crop_ = false;
bool has_metadata_refresh_rate_ = false;
bool buffer_flipped_ = false;
+ bool per_frame_hdr_metadata_ = false; // used to track if perframe metadata and blob is set.
// 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 7a8c4e2..8663705 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -677,6 +677,16 @@
num_elements, keys, metadata);
}
+static int32_t SetLayerPerFrameMetadataBlobs(hwc2_device_t *device, hwc2_display_t display,
+ hwc2_layer_t layer, uint32_t num_elements,
+ const int32_t *int_keys, const uint32_t *sizes,
+ const uint8_t *metadata) {
+ auto keys = reinterpret_cast<const PerFrameMetadataKey *>(int_keys);
+ return HWCSession::CallLayerFunction(device, display, layer,
+ &HWCLayer::SetLayerPerFrameMetadataBlobs,
+ num_elements, keys, sizes, 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) {
@@ -1290,6 +1300,8 @@
return AsFP<HWC2_PFN_GET_PER_FRAME_METADATA_KEYS>(GetPerFrameMetadataKeys);
case HWC2::FunctionDescriptor::SetLayerPerFrameMetadata:
return AsFP<HWC2_PFN_SET_LAYER_PER_FRAME_METADATA>(SetLayerPerFrameMetadata);
+ case HWC2::FunctionDescriptor::SetLayerPerFrameMetadataBlobs:
+ return AsFP<HWC2_PFN_SET_LAYER_PER_FRAME_METADATA_BLOBS>(SetLayerPerFrameMetadataBlobs);
case HWC2::FunctionDescriptor::GetDisplayIdentificationData:
return AsFP<HWC2_PFN_GET_DISPLAY_IDENTIFICATION_DATA>
(HWCSession::GetDisplayIdentificationData);