summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Wick <sebastian.wick@redhat.com>2023-03-02 02:06:24 +0100
committerMarge Bot <marge-bot@gnome.org>2023-03-04 09:30:41 +0000
commit650d30c7bffb00f63cc00af0575f135f7117fa77 (patch)
tree778b9f1693e67a55efbd72717662bb5e35576ede
parentf092b6c78c6fd7ce919c1467ad92733e7f1fc871 (diff)
downloadmutter-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.h3
-rw-r--r--src/backends/native/meta-kms-connector.c158
-rw-r--r--src/backends/native/meta-kms-impl-device-atomic.c49
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;
}