hwc2: Add support for per frame layer metadata
Change-Id: Icd7093690954b30ce99e72119a740c6bfb636a7d
CRs-Fixed: 2237407
diff --git a/sdm/libs/hwc2/hwc_display.cpp b/sdm/libs/hwc2/hwc_display.cpp
index 2619d75..c2a5cb4 100644
--- a/sdm/libs/hwc2/hwc_display.cpp
+++ b/sdm/libs/hwc2/hwc_display.cpp
@@ -885,6 +885,29 @@
}
}
+HWC2::Error HWCDisplay::GetPerFrameMetadataKeys(uint32_t *out_num_keys,
+ PerFrameMetadataKey *out_keys) {
+ 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;
+ }
+ return HWC2::Error::None;
+}
+
HWC2::Error HWCDisplay::GetActiveConfig(hwc2_config_t *out_config) {
if (out_config == nullptr) {
return HWC2::Error::BadDisplay;
diff --git a/sdm/libs/hwc2/hwc_display.h b/sdm/libs/hwc2/hwc_display.h
index 3e4271d..b4bb554 100644
--- a/sdm/libs/hwc2/hwc_display.h
+++ b/sdm/libs/hwc2/hwc_display.h
@@ -255,6 +255,8 @@
float* out_max_luminance,
float* out_max_average_luminance,
float* out_min_luminance);
+ virtual HWC2::Error GetPerFrameMetadataKeys(uint32_t *out_num_keys,
+ PerFrameMetadataKey *out_keys);
virtual HWC2::Error SetDisplayAnimating(bool animating) {
animating_ = animating;
validated_ = false;
diff --git a/sdm/libs/hwc2/hwc_layers.cpp b/sdm/libs/hwc2/hwc_layers.cpp
index 7aac16f..840119e 100644
--- a/sdm/libs/hwc2/hwc_layers.cpp
+++ b/sdm/libs/hwc2/hwc_layers.cpp
@@ -517,6 +517,56 @@
return HWC2::Error::None;
}
+HWC2::Error HWCLayer::SetLayerPerFrameMetadata(uint32_t num_elements,
+ const PerFrameMetadataKey *keys,
+ const float *metadata) {
+ 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++) {
+ switch (keys[i]) {
+ case PerFrameMetadataKey::DISPLAY_RED_PRIMARY_X:
+ mastering_display.colorVolumeSEIEnabled = true;
+ mastering_display.primaries.rgbPrimaries[0][0] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::DISPLAY_RED_PRIMARY_Y:
+ mastering_display.primaries.rgbPrimaries[0][1] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_X:
+ mastering_display.primaries.rgbPrimaries[1][0] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::DISPLAY_GREEN_PRIMARY_Y:
+ mastering_display.primaries.rgbPrimaries[1][1] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_X:
+ mastering_display.primaries.rgbPrimaries[2][0] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::DISPLAY_BLUE_PRIMARY_Y:
+ mastering_display.primaries.rgbPrimaries[2][1] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::WHITE_POINT_X:
+ mastering_display.primaries.whitePoint[0] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::WHITE_POINT_Y:
+ mastering_display.primaries.whitePoint[1] = UINT32(metadata[i] * 50000);
+ break;
+ case PerFrameMetadataKey::MAX_LUMINANCE:
+ mastering_display.maxDisplayLuminance = UINT32(metadata[i]);
+ break;
+ case PerFrameMetadataKey::MIN_LUMINANCE:
+ mastering_display.minDisplayLuminance = UINT32(metadata[i] * 10000);
+ break;
+ case PerFrameMetadataKey::MAX_CONTENT_LIGHT_LEVEL:
+ content_light.lightLevelSEIEnabled = true;
+ content_light.maxContentLightLevel = UINT32(metadata[i]);
+ break;
+ case PerFrameMetadataKey::MAX_FRAME_AVERAGE_LIGHT_LEVEL:
+ content_light.minPicAverageLightLevel = UINT32(metadata[i] * 10000);
+ break;
+ }
+ }
+ return HWC2::Error::None;
+}
+
void HWCLayer::SetRect(const hwc_rect_t &source, LayerRect *target) {
target->left = FLOAT(source.left);
target->top = FLOAT(source.top);
diff --git a/sdm/libs/hwc2/hwc_layers.h b/sdm/libs/hwc2/hwc_layers.h
index 0b08bb5..d72f07f 100644
--- a/sdm/libs/hwc2/hwc_layers.h
+++ b/sdm/libs/hwc2/hwc_layers.h
@@ -32,12 +32,16 @@
#include <hardware/hwcomposer2.h>
#undef HWC2_INCLUDE_STRINGIFICATION
#undef HWC2_USE_CPP11
-#include <map>
+#include <android/hardware/graphics/composer/2.2/IComposerClient.h>
#include <deque>
+#include <map>
#include <set>
#include "core/buffer_allocator.h"
#include "hwc_buffer_allocator.h"
+using PerFrameMetadataKey =
+ android::hardware::graphics::composer::V2_2::IComposerClient::PerFrameMetadataKey;
+
namespace sdm {
DisplayError SetCSC(const private_handle_t *pvt_handle, ColorMetaData *color_metadata);
@@ -83,6 +87,8 @@
HWC2::Error SetLayerSurfaceDamage(hwc_region_t damage);
HWC2::Error SetLayerTransform(HWC2::Transform transform);
HWC2::Error SetLayerVisibleRegion(hwc_region_t visible);
+ HWC2::Error SetLayerPerFrameMetadata(uint32_t num_elements, const PerFrameMetadataKey *keys,
+ const float *metadata);
HWC2::Error SetLayerZOrder(uint32_t z);
void SetComposition(const LayerComposition &sdm_composition);
HWC2::Composition GetClientRequestedCompositionType() { return client_requested_; }
diff --git a/sdm/libs/hwc2/hwc_session.cpp b/sdm/libs/hwc2/hwc_session.cpp
index d9409a8..10482ae 100644
--- a/sdm/libs/hwc2/hwc_session.cpp
+++ b/sdm/libs/hwc2/hwc_session.cpp
@@ -509,6 +509,21 @@
return HWC2_ERROR_NONE;
}
+static int32_t GetPerFrameMetadataKeys(hwc2_device_t *device, hwc2_display_t display,
+ uint32_t *out_num_keys, int32_t *int_out_keys) {
+ auto out_keys = reinterpret_cast<PerFrameMetadataKey *>(int_out_keys);
+ return HWCSession::CallDisplayFunction(device, display, &HWCDisplay::GetPerFrameMetadataKeys,
+ out_num_keys, out_keys);
+}
+
+static int32_t SetLayerPerFrameMetadata(hwc2_device_t *device, hwc2_display_t display,
+ hwc2_layer_t layer, uint32_t num_elements,
+ const int32_t *int_keys, const float *metadata) {
+ auto keys = reinterpret_cast<const PerFrameMetadataKey *>(int_keys);
+ return HWCSession::CallLayerFunction(device, display, layer, &HWCLayer::SetLayerPerFrameMetadata,
+ num_elements, keys, 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) {
@@ -971,6 +986,10 @@
HWCSession::SetColorModeWithRenderIntent);
case HWC2::FunctionDescriptor::GetDataspaceSaturationMatrix:
return AsFP<HWC2_PFN_GET_DATASPACE_SATURATION_MATRIX>(GetDataspaceSaturationMatrix);
+ case HWC2::FunctionDescriptor::GetPerFrameMetadataKeys:
+ return AsFP<HWC2_PFN_GET_PER_FRAME_METADATA_KEYS>(GetPerFrameMetadataKeys);
+ case HWC2::FunctionDescriptor::SetLayerPerFrameMetadata:
+ return AsFP<HWC2_PFN_SET_LAYER_PER_FRAME_METADATA>(SetLayerPerFrameMetadata);
default:
DLOGD("Unknown/Unimplemented function descriptor: %d (%s)", int_descriptor,
to_string(descriptor).c_str());