mirror of
https://github.com/brl/mutter.git
synced 2024-11-30 03:50:47 -05:00
kms/connector: Add support for the Broadcast RGB property
It can be used to force a specific RGB range. Some monitors don't follow the specification and expect a signal different from what we send. This property allows to force a mode which hopefully then works correctly for the sink. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3535>
This commit is contained in:
parent
d45104c14a
commit
c4399bd94d
@ -40,6 +40,14 @@ typedef enum
|
|||||||
META_OUTPUT_HDR_METADATA_EOTF_HLG,
|
META_OUTPUT_HDR_METADATA_EOTF_HLG,
|
||||||
} MetaOutputHdrMetadataEOTF;
|
} MetaOutputHdrMetadataEOTF;
|
||||||
|
|
||||||
|
typedef enum _MetaOutputRGBRange
|
||||||
|
{
|
||||||
|
META_OUTPUT_RGB_RANGE_UNKNOWN = 0,
|
||||||
|
META_OUTPUT_RGB_RANGE_AUTO,
|
||||||
|
META_OUTPUT_RGB_RANGE_FULL,
|
||||||
|
META_OUTPUT_RGB_RANGE_LIMITED,
|
||||||
|
} MetaOutputRGBRange;
|
||||||
|
|
||||||
typedef struct _MetaOutputHdrMetadata
|
typedef struct _MetaOutputHdrMetadata
|
||||||
{
|
{
|
||||||
gboolean active;
|
gboolean active;
|
||||||
|
@ -39,6 +39,7 @@ typedef enum _MetaKmsConnectorProp
|
|||||||
META_KMS_CONNECTOR_PROP_MAX_BPC,
|
META_KMS_CONNECTOR_PROP_MAX_BPC,
|
||||||
META_KMS_CONNECTOR_PROP_COLORSPACE,
|
META_KMS_CONNECTOR_PROP_COLORSPACE,
|
||||||
META_KMS_CONNECTOR_PROP_HDR_OUTPUT_METADATA,
|
META_KMS_CONNECTOR_PROP_HDR_OUTPUT_METADATA,
|
||||||
|
META_KMS_CONNECTOR_PROP_BROADCAST_RGB,
|
||||||
META_KMS_CONNECTOR_N_PROPS
|
META_KMS_CONNECTOR_N_PROPS
|
||||||
} MetaKmsConnectorProp;
|
} MetaKmsConnectorProp;
|
||||||
|
|
||||||
@ -113,6 +114,15 @@ typedef enum _MetaKmsConnectorColorspace
|
|||||||
META_KMS_CONNECTOR_COLORSPACE_UNKNOWN,
|
META_KMS_CONNECTOR_COLORSPACE_UNKNOWN,
|
||||||
} MetaKmsConnectorColorspace;
|
} MetaKmsConnectorColorspace;
|
||||||
|
|
||||||
|
typedef enum _MetaKmsConnectorBroadcastRGB
|
||||||
|
{
|
||||||
|
META_KMS_CONNECTOR_BROADCAST_RGB_AUTOMATIC = 0,
|
||||||
|
META_KMS_CONNECTOR_BROADCAST_RGB_FULL,
|
||||||
|
META_KMS_CONNECTOR_BROADCAST_RGB_LIMITED_16_235,
|
||||||
|
META_KMS_CONNECTOR_BROADCAST_RGB_N_PROPS,
|
||||||
|
META_KMS_CONNECTOR_BROADCAST_RGB_UNKNOWN,
|
||||||
|
} MetaKmsConnectorBroadcastRGB;
|
||||||
|
|
||||||
uint32_t meta_kms_connector_get_prop_id (MetaKmsConnector *connector,
|
uint32_t meta_kms_connector_get_prop_id (MetaKmsConnector *connector,
|
||||||
MetaKmsConnectorProp prop);
|
MetaKmsConnectorProp prop);
|
||||||
|
|
||||||
@ -141,6 +151,8 @@ gboolean meta_kms_connector_is_same_as (MetaKmsConnector *connector,
|
|||||||
|
|
||||||
uint64_t meta_output_color_space_to_drm_color_space (MetaOutputColorspace color_space);
|
uint64_t meta_output_color_space_to_drm_color_space (MetaOutputColorspace color_space);
|
||||||
|
|
||||||
|
uint64_t meta_output_rgb_range_to_drm_broadcast_rgb (MetaOutputRGBRange rgb_range);
|
||||||
|
|
||||||
META_EXPORT_TEST
|
META_EXPORT_TEST
|
||||||
void meta_set_drm_hdr_metadata (MetaOutputHdrMetadata *metadata,
|
void meta_set_drm_hdr_metadata (MetaOutputHdrMetadata *metadata,
|
||||||
struct hdr_output_metadata *drm_metadata);
|
struct hdr_output_metadata *drm_metadata);
|
||||||
|
@ -56,6 +56,7 @@ typedef struct _MetaKmsConnectorPropTable
|
|||||||
MetaKmsEnum scaling_mode_enum[META_KMS_CONNECTOR_SCALING_MODE_N_PROPS];
|
MetaKmsEnum scaling_mode_enum[META_KMS_CONNECTOR_SCALING_MODE_N_PROPS];
|
||||||
MetaKmsEnum panel_orientation_enum[META_KMS_CONNECTOR_PANEL_ORIENTATION_N_PROPS];
|
MetaKmsEnum panel_orientation_enum[META_KMS_CONNECTOR_PANEL_ORIENTATION_N_PROPS];
|
||||||
MetaKmsEnum colorspace_enum[META_KMS_CONNECTOR_COLORSPACE_N_PROPS];
|
MetaKmsEnum colorspace_enum[META_KMS_CONNECTOR_COLORSPACE_N_PROPS];
|
||||||
|
MetaKmsEnum broadcast_rgb_enum[META_KMS_CONNECTOR_BROADCAST_RGB_N_PROPS];
|
||||||
} MetaKmsConnectorPropTable;
|
} MetaKmsConnectorPropTable;
|
||||||
|
|
||||||
struct _MetaKmsConnector
|
struct _MetaKmsConnector
|
||||||
@ -253,6 +254,13 @@ meta_kms_connector_is_hdr_metadata_supported (MetaKmsConnector *connector)
|
|||||||
return connector->current_state->hdr.supported;
|
return connector->current_state->hdr.supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_kms_connector_is_broadcast_rgb_supported (MetaKmsConnector *connector,
|
||||||
|
MetaOutputRGBRange broadcast_rgb)
|
||||||
|
{
|
||||||
|
return !!(connector->current_state->broadcast_rgb.supported & (1 << broadcast_rgb));
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_panel_orientation (MetaKmsConnectorState *state,
|
set_panel_orientation (MetaKmsConnectorState *state,
|
||||||
MetaKmsProp *panel_orientation)
|
MetaKmsProp *panel_orientation)
|
||||||
@ -355,6 +363,53 @@ meta_output_color_space_to_drm_color_space (MetaOutputColorspace color_space)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static MetaOutputRGBRange
|
||||||
|
drm_broadcast_rgb_to_output_rgb_range (uint64_t drm_broadcast_rgb)
|
||||||
|
{
|
||||||
|
switch (drm_broadcast_rgb)
|
||||||
|
{
|
||||||
|
case META_KMS_CONNECTOR_BROADCAST_RGB_AUTOMATIC:
|
||||||
|
return META_OUTPUT_RGB_RANGE_AUTO;
|
||||||
|
case META_KMS_CONNECTOR_BROADCAST_RGB_FULL:
|
||||||
|
return META_OUTPUT_RGB_RANGE_FULL;
|
||||||
|
case META_KMS_CONNECTOR_BROADCAST_RGB_LIMITED_16_235:
|
||||||
|
return META_OUTPUT_RGB_RANGE_LIMITED;
|
||||||
|
default:
|
||||||
|
return META_OUTPUT_RGB_RANGE_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t
|
||||||
|
supported_drm_broadcast_rgb_to_output_rgb_range (uint64_t drm_support)
|
||||||
|
{
|
||||||
|
uint64_t supported = 0;
|
||||||
|
|
||||||
|
if (drm_support & (1 << META_KMS_CONNECTOR_BROADCAST_RGB_AUTOMATIC))
|
||||||
|
supported |= (1 << META_OUTPUT_RGB_RANGE_AUTO);
|
||||||
|
if (drm_support & (1 << META_KMS_CONNECTOR_BROADCAST_RGB_FULL))
|
||||||
|
supported |= (1 << META_OUTPUT_RGB_RANGE_FULL);
|
||||||
|
if (drm_support & (1 << META_KMS_CONNECTOR_BROADCAST_RGB_LIMITED_16_235))
|
||||||
|
supported |= (1 << META_OUTPUT_RGB_RANGE_LIMITED);
|
||||||
|
|
||||||
|
return supported;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t
|
||||||
|
meta_output_rgb_range_to_drm_broadcast_rgb (MetaOutputRGBRange rgb_range)
|
||||||
|
{
|
||||||
|
switch (rgb_range)
|
||||||
|
{
|
||||||
|
case META_OUTPUT_RGB_RANGE_FULL:
|
||||||
|
return META_KMS_CONNECTOR_BROADCAST_RGB_FULL;
|
||||||
|
case META_OUTPUT_RGB_RANGE_LIMITED:
|
||||||
|
return META_KMS_CONNECTOR_BROADCAST_RGB_LIMITED_16_235;
|
||||||
|
case META_OUTPUT_RGB_RANGE_UNKNOWN:
|
||||||
|
case META_OUTPUT_RGB_RANGE_AUTO:
|
||||||
|
default:
|
||||||
|
return META_KMS_CONNECTOR_BROADCAST_RGB_AUTOMATIC;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
state_set_properties (MetaKmsConnectorState *state,
|
state_set_properties (MetaKmsConnectorState *state,
|
||||||
MetaKmsImplDevice *impl_device,
|
MetaKmsImplDevice *impl_device,
|
||||||
@ -408,6 +463,15 @@ state_set_properties (MetaKmsConnectorState *state,
|
|||||||
state->colorspace.supported =
|
state->colorspace.supported =
|
||||||
supported_drm_color_spaces_to_output_color_spaces (prop->supported_variants);
|
supported_drm_color_spaces_to_output_color_spaces (prop->supported_variants);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prop = &props[META_KMS_CONNECTOR_PROP_BROADCAST_RGB];
|
||||||
|
if (prop->prop_id)
|
||||||
|
{
|
||||||
|
state->broadcast_rgb.value =
|
||||||
|
drm_broadcast_rgb_to_output_rgb_range (prop->value);
|
||||||
|
state->broadcast_rgb.supported =
|
||||||
|
supported_drm_broadcast_rgb_to_output_rgb_range (prop->supported_variants);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static CoglSubpixelOrder
|
static CoglSubpixelOrder
|
||||||
@ -1013,6 +1077,10 @@ meta_kms_connector_state_changes (MetaKmsConnectorState *state,
|
|||||||
!hdr_metadata_equal (&state->hdr.value, &new_state->hdr.value))
|
!hdr_metadata_equal (&state->hdr.value, &new_state->hdr.value))
|
||||||
return META_KMS_RESOURCE_CHANGE_FULL;
|
return META_KMS_RESOURCE_CHANGE_FULL;
|
||||||
|
|
||||||
|
if (state->broadcast_rgb.value != new_state->broadcast_rgb.value ||
|
||||||
|
state->broadcast_rgb.supported != new_state->broadcast_rgb.supported)
|
||||||
|
return META_KMS_RESOURCE_CHANGE_FULL;
|
||||||
|
|
||||||
if (state->privacy_screen_state != new_state->privacy_screen_state)
|
if (state->privacy_screen_state != new_state->privacy_screen_state)
|
||||||
return META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN;
|
return META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN;
|
||||||
|
|
||||||
@ -1224,6 +1292,14 @@ meta_kms_connector_predict_state_in_impl (MetaKmsConnector *connector,
|
|||||||
connector));
|
connector));
|
||||||
current_state->hdr.value = connector_update->hdr.value;
|
current_state->hdr.value = connector_update->hdr.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (connector_update->broadcast_rgb.has_update)
|
||||||
|
{
|
||||||
|
g_warn_if_fail (meta_kms_connector_is_broadcast_rgb_supported (
|
||||||
|
connector,
|
||||||
|
connector_update->broadcast_rgb.value));
|
||||||
|
current_state->broadcast_rgb.value = connector_update->broadcast_rgb.value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sync_fd_held (connector, connector->impl_device);
|
sync_fd_held (connector, connector->impl_device);
|
||||||
@ -1350,6 +1426,14 @@ init_properties (MetaKmsConnector *connector,
|
|||||||
.name = "HDR_OUTPUT_METADATA",
|
.name = "HDR_OUTPUT_METADATA",
|
||||||
.type = DRM_MODE_PROP_BLOB,
|
.type = DRM_MODE_PROP_BLOB,
|
||||||
},
|
},
|
||||||
|
[META_KMS_CONNECTOR_PROP_BROADCAST_RGB] =
|
||||||
|
{
|
||||||
|
.name = "Broadcast RGB",
|
||||||
|
.type = DRM_MODE_PROP_ENUM,
|
||||||
|
.enum_values = prop_table->broadcast_rgb_enum,
|
||||||
|
.num_enum_values = META_KMS_CONNECTOR_BROADCAST_RGB_N_PROPS,
|
||||||
|
.default_value = META_KMS_CONNECTOR_BROADCAST_RGB_UNKNOWN,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
.dpms_enum = {
|
.dpms_enum = {
|
||||||
[META_KMS_CONNECTOR_DPMS_ON] =
|
[META_KMS_CONNECTOR_DPMS_ON] =
|
||||||
@ -1521,6 +1605,20 @@ init_properties (MetaKmsConnector *connector,
|
|||||||
.name = "DCI-P3_RGB_Theater",
|
.name = "DCI-P3_RGB_Theater",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
.broadcast_rgb_enum = {
|
||||||
|
[META_KMS_CONNECTOR_BROADCAST_RGB_AUTOMATIC] =
|
||||||
|
{
|
||||||
|
.name = "Automatic",
|
||||||
|
},
|
||||||
|
[META_KMS_CONNECTOR_BROADCAST_RGB_FULL] =
|
||||||
|
{
|
||||||
|
.name = "Full",
|
||||||
|
},
|
||||||
|
[META_KMS_CONNECTOR_BROADCAST_RGB_LIMITED_16_235] =
|
||||||
|
{
|
||||||
|
.name = "Limited 16:235",
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +69,11 @@ typedef struct _MetaKmsConnectorState
|
|||||||
gboolean supported;
|
gboolean supported;
|
||||||
gboolean unknown;
|
gboolean unknown;
|
||||||
} hdr;
|
} hdr;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
MetaOutputRGBRange value;
|
||||||
|
uint64_t supported;
|
||||||
|
} broadcast_rgb;
|
||||||
} MetaKmsConnectorState;
|
} MetaKmsConnectorState;
|
||||||
|
|
||||||
META_EXPORT_TEST
|
META_EXPORT_TEST
|
||||||
@ -98,4 +103,7 @@ const MetaKmsRange * meta_kms_connector_get_max_bpc (MetaKmsConnector *connector
|
|||||||
gboolean meta_kms_connector_is_color_space_supported (MetaKmsConnector *connector,
|
gboolean meta_kms_connector_is_color_space_supported (MetaKmsConnector *connector,
|
||||||
MetaOutputColorspace color_space);
|
MetaOutputColorspace color_space);
|
||||||
|
|
||||||
|
gboolean meta_kms_connector_is_broadcast_rgb_supported (MetaKmsConnector *connector,
|
||||||
|
MetaOutputRGBRange broadcast_rgb);
|
||||||
|
|
||||||
gboolean meta_kms_connector_is_hdr_metadata_supported (MetaKmsConnector *connector);
|
gboolean meta_kms_connector_is_hdr_metadata_supported (MetaKmsConnector *connector);
|
||||||
|
@ -292,6 +292,25 @@ process_connector_update (MetaKmsImplDevice *impl_device,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (connector_update->broadcast_rgb.has_update)
|
||||||
|
{
|
||||||
|
MetaOutputRGBRange rgb_range = connector_update->broadcast_rgb.value;
|
||||||
|
uint64_t value = meta_output_rgb_range_to_drm_broadcast_rgb (rgb_range);
|
||||||
|
|
||||||
|
meta_topic (META_DEBUG_KMS,
|
||||||
|
"[atomic] Setting Broadcast RGB to %u on connector %u (%s)",
|
||||||
|
rgb_range,
|
||||||
|
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_BROADCAST_RGB,
|
||||||
|
value,
|
||||||
|
error))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,6 +110,11 @@ typedef struct _MetaKmsConnectorUpdate
|
|||||||
gboolean has_update;
|
gboolean has_update;
|
||||||
MetaOutputHdrMetadata value;
|
MetaOutputHdrMetadata value;
|
||||||
} hdr;
|
} hdr;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
gboolean has_update;
|
||||||
|
MetaOutputRGBRange value;
|
||||||
|
} broadcast_rgb;
|
||||||
} MetaKmsConnectorUpdate;
|
} MetaKmsConnectorUpdate;
|
||||||
|
|
||||||
typedef struct _MetaKmsPageFlipListener
|
typedef struct _MetaKmsPageFlipListener
|
||||||
|
@ -444,8 +444,6 @@ meta_kms_update_set_color_space (MetaKmsUpdate *update,
|
|||||||
MetaKmsConnectorUpdate *connector_update;
|
MetaKmsConnectorUpdate *connector_update;
|
||||||
|
|
||||||
g_assert (meta_kms_connector_get_device (connector) == update->device);
|
g_assert (meta_kms_connector_get_device (connector) == update->device);
|
||||||
g_return_if_fail (meta_kms_connector_is_color_space_supported (connector,
|
|
||||||
color_space));
|
|
||||||
|
|
||||||
connector_update = ensure_connector_update (update, connector);
|
connector_update = ensure_connector_update (update, connector);
|
||||||
connector_update->colorspace.has_update = TRUE;
|
connector_update->colorspace.has_update = TRUE;
|
||||||
@ -470,6 +468,22 @@ meta_kms_update_set_hdr_metadata (MetaKmsUpdate *update,
|
|||||||
update->needs_modeset = TRUE;
|
update->needs_modeset = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
meta_kms_update_set_broadcast_rgb (MetaKmsUpdate *update,
|
||||||
|
MetaKmsConnector *connector,
|
||||||
|
MetaOutputRGBRange rgb_range)
|
||||||
|
{
|
||||||
|
MetaKmsConnectorUpdate *connector_update;
|
||||||
|
|
||||||
|
g_assert (meta_kms_connector_get_device (connector) == update->device);
|
||||||
|
g_return_if_fail (meta_kms_connector_is_broadcast_rgb_supported (connector,
|
||||||
|
rgb_range));
|
||||||
|
|
||||||
|
connector_update = ensure_connector_update (update, connector);
|
||||||
|
connector_update->broadcast_rgb.has_update = TRUE;
|
||||||
|
connector_update->broadcast_rgb.value = rgb_range;
|
||||||
|
}
|
||||||
|
|
||||||
static MetaKmsCrtcColorUpdate *
|
static MetaKmsCrtcColorUpdate *
|
||||||
ensure_color_update (MetaKmsUpdate *update,
|
ensure_color_update (MetaKmsUpdate *update,
|
||||||
MetaKmsCrtc *crtc)
|
MetaKmsCrtc *crtc)
|
||||||
|
@ -134,6 +134,10 @@ void meta_kms_update_set_hdr_metadata (MetaKmsUpdate *update,
|
|||||||
MetaKmsConnector *connector,
|
MetaKmsConnector *connector,
|
||||||
MetaOutputHdrMetadata *metadata);
|
MetaOutputHdrMetadata *metadata);
|
||||||
|
|
||||||
|
void meta_kms_update_set_broadcast_rgb (MetaKmsUpdate *update,
|
||||||
|
MetaKmsConnector *connector,
|
||||||
|
MetaOutputRGBRange rgb_range);
|
||||||
|
|
||||||
META_EXPORT_TEST
|
META_EXPORT_TEST
|
||||||
void meta_kms_update_set_power_save (MetaKmsUpdate *update);
|
void meta_kms_update_set_power_save (MetaKmsUpdate *update);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user