diff options
author | Sebastian Wick <sebastian.wick@redhat.com> | 2023-03-02 02:06:24 +0100 |
---|---|---|
committer | Marge Bot <marge-bot@gnome.org> | 2023-03-04 09:30:41 +0000 |
commit | 650d30c7bffb00f63cc00af0575f135f7117fa77 (patch) | |
tree | 778b9f1693e67a55efbd72717662bb5e35576ede | |
parent | f092b6c78c6fd7ce919c1467ad92733e7f1fc871 (diff) | |
download | mutter-650d30c7bffb00f63cc00af0575f135f7117fa77.tar.gz |
backends/native: Process color space and HDR md updates
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2879>
-rw-r--r-- | src/backends/native/meta-kms-connector-private.h | 3 | ||||
-rw-r--r-- | src/backends/native/meta-kms-connector.c | 158 | ||||
-rw-r--r-- | src/backends/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,42 +1171,53 @@ 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) - { - MetaKmsConnectorUpdate *connector_update = l->data; + if (connector_update->connector != connector) + continue; - 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)) + { + 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 (connector_update->privacy_screen.has_update && - !(current_state->privacy_screen_state & - META_PRIVACY_SCREEN_LOCKED)) + current_state->privacy_screen_state = + META_PRIVACY_SCREEN_ENABLED; + } + else { - if (connector_update->privacy_screen.is_enabled) - { - 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; - } + 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; + } } impl_device = meta_kms_device_get_impl_device (connector->device); 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; } |