From 650d30c7bffb00f63cc00af0575f135f7117fa77 Mon Sep 17 00:00:00 2001 From: Sebastian Wick Date: Thu, 2 Mar 2023 02:06:24 +0100 Subject: [PATCH] backends/native: Process color space and HDR md updates Part-of: --- .../native/meta-kms-connector-private.h | 3 + src/backends/native/meta-kms-connector.c | 158 ++++++++++++++---- .../native/meta-kms-impl-device-atomic.c | 49 ++++++ 3 files changed, 181 insertions(+), 29 deletions(-) diff --git a/src/backends/native/meta-kms-connector-private.h b/src/backends/native/meta-kms-connector-private.h index 562c90845..1e58c0ba2 100644 --- a/src/backends/native/meta-kms-connector-private.h +++ b/src/backends/native/meta-kms-connector-private.h @@ -142,4 +142,7 @@ MetaKmsConnector * meta_kms_connector_new (MetaKmsImplDevice *impl_device, gboolean meta_kms_connector_is_same_as (MetaKmsConnector *connector, drmModeConnector *drm_connector); +void meta_set_drm_hdr_metadata (MetaOutputHdrMetadata *metadata, + struct hdr_output_metadata *drm_metadata); + #endif /* META_KMS_CONNECTOR_PRIVATE_H */ diff --git a/src/backends/native/meta-kms-connector.c b/src/backends/native/meta-kms-connector.c index 6b614f455..7cd2b66e6 100644 --- a/src/backends/native/meta-kms-connector.c +++ b/src/backends/native/meta-kms-connector.c @@ -563,6 +563,94 @@ set_output_hdr_metadata (struct hdr_output_metadata *drm_metadata, return TRUE; } +static uint16_t +encode_u16_chromaticity (double value) +{ + /* CTA-861.3 HDR Static Metadata Extension, 3.2.1 Static Metadata Type 1 */ + value = MAX (MIN (value, 1.0), 0.0); + return round (value / 0.00002); +} + +static uint16_t +encode_u16_max_luminance (double value) +{ + /* CTA-861.3 HDR Static Metadata Extension, 3.2.1 Static Metadata Type 1 */ + return round (MAX (MIN (value, 65535.0), 0.0)); +} + +static uint16_t +encode_u16_min_luminance (double value) +{ + /* CTA-861.3 HDR Static Metadata Extension, 3.2.1 Static Metadata Type 1 */ + value = MAX (MIN (value, 6.5535), 0.0); + return round (value / 0.0001); +} + +static uint16_t +encode_u16_max_cll (double value) +{ + /* CTA-861.3 HDR Static Metadata Extension, 3.2.1 Static Metadata Type 1 */ + return round (MAX (MIN (value, 65535.0), 0.0)); +} + +static uint16_t +encode_u16_max_fall (double value) +{ + /* CTA-861.3 HDR Static Metadata Extension, 3.2.1 Static Metadata Type 1 */ + return round (MAX (MIN (value, 65535.0), 0.0)); +} + +void +meta_set_drm_hdr_metadata (MetaOutputHdrMetadata *metadata, + struct hdr_output_metadata *drm_metadata) +{ + struct hdr_metadata_infoframe *infoframe = &drm_metadata->hdmi_metadata_type1; + + drm_metadata->metadata_type = HDR_STATIC_METADATA_TYPE_1; + infoframe->metadata_type = HDR_STATIC_METADATA_TYPE_1; + + switch (metadata->eotf) + { + case META_OUTPUT_HDR_METADATA_EOTF_TRADITIONAL_GAMMA_SDR: + infoframe->eotf = HDR_METADATA_EOTF_TRADITIONAL_GAMMA_SDR; + break; + case META_OUTPUT_HDR_METADATA_EOTF_TRADITIONAL_GAMMA_HDR: + infoframe->eotf = HDR_METADATA_EOTF_TRADITIONAL_GAMMA_HDR; + break; + case META_OUTPUT_HDR_METADATA_EOTF_PQ: + infoframe->eotf = HDR_METADATA_EOTF_PERCEPTUAL_QUANTIZER; + break; + case META_OUTPUT_HDR_METADATA_EOTF_HLG: + infoframe->eotf = HDR_METADATA_EOTF_HYBRID_LOG_GAMMA; + break; + } + + infoframe->display_primaries[0].x = + encode_u16_chromaticity (metadata->mastering_display_primaries[0].x); + infoframe->display_primaries[0].y = + encode_u16_chromaticity (metadata->mastering_display_primaries[0].y); + infoframe->display_primaries[1].x = + encode_u16_chromaticity (metadata->mastering_display_primaries[1].x); + infoframe->display_primaries[1].y = + encode_u16_chromaticity (metadata->mastering_display_primaries[1].y); + infoframe->display_primaries[2].x = + encode_u16_chromaticity (metadata->mastering_display_primaries[2].x); + infoframe->display_primaries[2].y = + encode_u16_chromaticity (metadata->mastering_display_primaries[2].y); + infoframe->white_point.x = + encode_u16_chromaticity (metadata->mastering_display_white_point.x); + infoframe->white_point.y = + encode_u16_chromaticity (metadata->mastering_display_white_point.y); + + infoframe->max_display_mastering_luminance = + encode_u16_max_luminance (metadata->mastering_display_max_luminance); + infoframe->min_display_mastering_luminance = + encode_u16_min_luminance (metadata->mastering_display_min_luminance); + + infoframe->max_cll = encode_u16_max_cll (metadata->max_cll); + infoframe->max_fall = encode_u16_max_fall (metadata->max_fall); +} + static void state_set_hdr_output_metadata (MetaKmsConnectorState *state, MetaKmsConnector *connector, @@ -1054,6 +1142,7 @@ meta_kms_connector_predict_state_in_impl (MetaKmsConnector *connector, GList *mode_sets; GList *l; MetaKmsResourceChanges changes = META_KMS_RESOURCE_CHANGE_NONE; + GList *connector_updates; current_state = connector->current_state; if (!current_state) @@ -1082,41 +1171,52 @@ meta_kms_connector_predict_state_in_impl (MetaKmsConnector *connector, } } - if (has_privacy_screen_software_toggle (connector)) + connector_updates = meta_kms_update_get_connector_updates (update); + for (l = connector_updates; l; l = l->next) { - GList *connector_updates; + MetaKmsConnectorUpdate *connector_update = l->data; - connector_updates = meta_kms_update_get_connector_updates (update); - for (l = connector_updates; l; l = l->next) + if (connector_update->connector != connector) + continue; + + if (has_privacy_screen_software_toggle (connector) && + connector_update->privacy_screen.has_update && + !(current_state->privacy_screen_state & + META_PRIVACY_SCREEN_LOCKED)) { - MetaKmsConnectorUpdate *connector_update = l->data; - - if (connector_update->connector != connector) - continue; - - if (connector_update->privacy_screen.has_update && - !(current_state->privacy_screen_state & - META_PRIVACY_SCREEN_LOCKED)) + if (connector_update->privacy_screen.is_enabled) { - if (connector_update->privacy_screen.is_enabled) - { - if (current_state->privacy_screen_state != - META_PRIVACY_SCREEN_ENABLED) - changes |= META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN; + if (current_state->privacy_screen_state != + META_PRIVACY_SCREEN_ENABLED) + changes |= META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN; - current_state->privacy_screen_state = - META_PRIVACY_SCREEN_ENABLED; - } - else - { - if (current_state->privacy_screen_state != - META_PRIVACY_SCREEN_DISABLED) - changes |= META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN; - - current_state->privacy_screen_state = - META_PRIVACY_SCREEN_DISABLED; - } + current_state->privacy_screen_state = + META_PRIVACY_SCREEN_ENABLED; } + else + { + if (current_state->privacy_screen_state != + META_PRIVACY_SCREEN_DISABLED) + changes |= META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN; + + current_state->privacy_screen_state = + META_PRIVACY_SCREEN_DISABLED; + } + } + + if (connector_update->colorspace.has_update) + { + g_warn_if_fail (meta_kms_connector_is_color_space_supported ( + connector, + connector_update->colorspace.value)); + current_state->colorspace.value = connector_update->colorspace.value; + } + + if (connector_update->hdr.has_update) + { + g_warn_if_fail (meta_kms_connector_is_hdr_metadata_supported ( + connector)); + current_state->hdr.value = connector_update->hdr.value; } } diff --git a/src/backends/native/meta-kms-impl-device-atomic.c b/src/backends/native/meta-kms-impl-device-atomic.c index e0b2ce1dd..2566cd936 100644 --- a/src/backends/native/meta-kms-impl-device-atomic.c +++ b/src/backends/native/meta-kms-impl-device-atomic.c @@ -234,6 +234,55 @@ process_connector_update (MetaKmsImplDevice *impl_device, return FALSE; } + if (connector_update->colorspace.has_update) + { + meta_topic (META_DEBUG_KMS, + "[atomic] Setting colorspace to %u on connector %u (%s)", + connector_update->colorspace.value, + meta_kms_connector_get_id (connector), + meta_kms_impl_device_get_path (impl_device)); + + if (!add_connector_property (impl_device, + connector, req, + META_KMS_CONNECTOR_PROP_COLORSPACE, + connector_update->colorspace.value, + error)) + return FALSE; + } + + if (connector_update->hdr.has_update) + { + uint32_t hdr_blob_id; + + meta_topic (META_DEBUG_KMS, + "[atomic] Setting HDR metadata on connector %u (%s)", + meta_kms_connector_get_id (connector), + meta_kms_impl_device_get_path (impl_device)); + + hdr_blob_id = 0; + if (connector_update->hdr.value.active) + { + struct hdr_output_metadata metadata; + + meta_set_drm_hdr_metadata (&connector_update->hdr.value, &metadata); + + hdr_blob_id = store_new_blob (impl_device, + blob_ids, + &metadata, + sizeof (metadata), + error); + if (!hdr_blob_id) + return FALSE; + } + + if (!add_connector_property (impl_device, + connector, req, + META_KMS_CONNECTOR_PROP_HDR_OUTPUT_METADATA, + hdr_blob_id, + error)) + return FALSE; + } + return TRUE; }