backends/native: Process color space and HDR md updates
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2879>
This commit is contained in:
parent
f092b6c78c
commit
650d30c7bf
3 changed files with 181 additions and 29 deletions
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue