kms: Add support for color encoding and range plane properties

Which are required for correct YUV->RGB conversion. Note that encoding refers
to the matrix coefficients.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4204>
This commit is contained in:
Robert Mader 2025-01-06 21:33:00 +01:00 committed by Marge Bot
parent fd39ca9f20
commit 5bb7a0f13e
6 changed files with 186 additions and 0 deletions

View File

@ -757,6 +757,39 @@ process_plane_assignment (MetaKmsImplDevice *impl_device,
error))
return FALSE;
}
if (plane_assignment->color_encoding.has_update)
{
meta_topic (META_DEBUG_KMS,
"[atomic] Setting plane (%u, %s) color encoding to %u",
meta_kms_plane_get_id (plane),
meta_kms_impl_device_get_path (impl_device),
plane_assignment->color_encoding.value);
if (!add_plane_property (impl_device,
plane, req,
META_KMS_PLANE_PROP_YCBCR_COLOR_ENCODING,
plane_assignment->color_encoding.value,
error))
return FALSE;
}
if (plane_assignment->color_range.has_update)
{
meta_topic (META_DEBUG_KMS,
"[atomic] Setting plane (%u, %s) color range to %u",
meta_kms_plane_get_id (plane),
meta_kms_impl_device_get_path (impl_device),
plane_assignment->color_range.value);
if (!add_plane_property (impl_device,
plane, req,
META_KMS_PLANE_PROP_YCBCR_COLOR_RANGE,
plane_assignment->color_range.value,
error))
return FALSE;
}
return TRUE;
}

View File

@ -43,6 +43,8 @@ typedef enum _MetaKmsPlaneProp
META_KMS_PLANE_PROP_HOTSPOT_X,
META_KMS_PLANE_PROP_HOTSPOT_Y,
META_KMS_PLANE_PROP_SIZE_HINTS,
META_KMS_PLANE_PROP_YCBCR_COLOR_ENCODING,
META_KMS_PLANE_PROP_YCBCR_COLOR_RANGE,
META_KMS_PLANE_N_PROPS
} MetaKmsPlaneProp;

View File

@ -34,6 +34,8 @@ typedef struct _MetaKmsPlanePropTable
{
MetaKmsProp props[META_KMS_PLANE_N_PROPS];
MetaKmsEnum rotation_bitmask[META_KMS_PLANE_ROTATION_BIT_N_PROPS];
MetaKmsEnum color_encodings[META_KMS_PLANE_YCBCR_COLOR_ENCODING_N_PROPS];
MetaKmsEnum color_ranges[META_KMS_PLANE_YCBCR_COLOR_RANGE_N_PROPS];
} MetaKmsPlanePropTable;
struct _MetaKmsPlane
@ -177,6 +179,34 @@ meta_kms_plane_update_set_rotation (MetaKmsPlane *plane,
meta_kms_plane_assignment_set_rotation (plane_assignment, kms_rotation);
}
void
meta_kms_plane_update_set_color_encoding (MetaKmsPlane *plane,
MetaKmsPlaneAssignment *plane_assignment,
MetaKmsPlaneYCbCrColorEncoding encoding)
{
MetaKmsProp *prop =
&plane->prop_table.props[META_KMS_PLANE_PROP_YCBCR_COLOR_ENCODING];
g_return_if_fail (meta_kms_plane_is_color_encoding_handled (plane, encoding));
if (prop->value != encoding)
meta_kms_plane_assignment_set_color_encoding (plane_assignment, encoding);
}
void
meta_kms_plane_update_set_color_range (MetaKmsPlane *plane,
MetaKmsPlaneAssignment *plane_assignment,
MetaKmsPlaneYCbCrColorRange range)
{
MetaKmsProp *prop =
&plane->prop_table.props[META_KMS_PLANE_YCBCR_COLOR_RANGE_LIMITED];
g_return_if_fail (meta_kms_plane_is_color_range_handled (plane, range));
if (prop->value != range)
meta_kms_plane_assignment_set_color_range (plane_assignment, range);
}
gboolean
meta_kms_plane_is_transform_handled (MetaKmsPlane *plane,
MtkMonitorTransform transform)
@ -209,6 +239,26 @@ meta_kms_plane_is_transform_handled (MetaKmsPlane *plane,
return FALSE;
}
gboolean
meta_kms_plane_is_color_encoding_handled (MetaKmsPlane *plane,
MetaKmsPlaneYCbCrColorEncoding encoding)
{
MetaKmsProp *prop =
&plane->prop_table.props[META_KMS_PLANE_PROP_YCBCR_COLOR_ENCODING];
return prop->supported_variants & (1 << encoding);
}
gboolean
meta_kms_plane_is_color_range_handled (MetaKmsPlane *plane,
MetaKmsPlaneYCbCrColorRange range)
{
MetaKmsProp *prop =
&plane->prop_table.props[META_KMS_PLANE_PROP_YCBCR_COLOR_RANGE];
return prop->supported_variants & (1 << range);
}
gboolean
meta_kms_plane_supports_cursor_hotspot (MetaKmsPlane *plane)
{
@ -618,6 +668,22 @@ init_properties (MetaKmsPlane *plane,
.name = "SIZE_HINTS",
.type = DRM_MODE_PROP_BLOB,
},
[META_KMS_PLANE_PROP_YCBCR_COLOR_ENCODING] =
{
.name = "COLOR_ENCODING",
.type = DRM_MODE_PROP_ENUM,
.enum_values = prop_table->color_encodings,
.num_enum_values = META_KMS_PLANE_YCBCR_COLOR_ENCODING_N_PROPS,
.default_value = META_KMS_PLANE_YCBCR_COLOR_ENCODING_BT709,
},
[META_KMS_PLANE_PROP_YCBCR_COLOR_RANGE] =
{
.name = "COLOR_RANGE",
.type = DRM_MODE_PROP_ENUM,
.enum_values = prop_table->color_ranges,
.num_enum_values = META_KMS_PLANE_YCBCR_COLOR_RANGE_N_PROPS,
.default_value = META_KMS_PLANE_YCBCR_COLOR_RANGE_LIMITED,
},
},
.rotation_bitmask = {
[META_KMS_PLANE_ROTATION_BIT_ROTATE_0] =
@ -651,6 +717,30 @@ init_properties (MetaKmsPlane *plane,
.bitmask = META_KMS_PLANE_ROTATION_REFLECT_Y,
},
},
.color_encodings = {
[META_KMS_PLANE_YCBCR_COLOR_ENCODING_BT601] =
{
.name = "ITU-R BT.601 YCbCr",
},
[META_KMS_PLANE_YCBCR_COLOR_ENCODING_BT709] =
{
.name = "ITU-R BT.709 YCbCr",
},
[META_KMS_PLANE_YCBCR_COLOR_ENCODING_BT2020] =
{
.name = "ITU-R BT.2020 YCbCr",
},
},
.color_ranges = {
[META_KMS_PLANE_YCBCR_COLOR_RANGE_LIMITED] =
{
.name = "YCbCr limited range",
},
[META_KMS_PLANE_YCBCR_COLOR_RANGE_FULL] =
{
.name = "YCbCr full range",
},
},
};
}

View File

@ -32,6 +32,21 @@ enum _MetaKmsPlaneType
META_KMS_PLANE_TYPE_OVERLAY,
};
typedef enum _MetaKmsPlaneYCbCrColorEncoding
{
META_KMS_PLANE_YCBCR_COLOR_ENCODING_BT601 = 0,
META_KMS_PLANE_YCBCR_COLOR_ENCODING_BT709,
META_KMS_PLANE_YCBCR_COLOR_ENCODING_BT2020,
META_KMS_PLANE_YCBCR_COLOR_ENCODING_N_PROPS,
} MetaKmsPlaneYCbCrColorEncoding;
typedef enum _MetaKmsPlaneYCbCrColorRanges
{
META_KMS_PLANE_YCBCR_COLOR_RANGE_LIMITED = 0,
META_KMS_PLANE_YCBCR_COLOR_RANGE_FULL,
META_KMS_PLANE_YCBCR_COLOR_RANGE_N_PROPS,
} MetaKmsPlaneYCbCrColorRange;
typedef struct _MetaKmsPlaneCursorSizeHints
{
gboolean has_size_hints;
@ -59,6 +74,12 @@ meta_kms_plane_get_cursor_size_hints (MetaKmsPlane *plane);
gboolean meta_kms_plane_is_transform_handled (MetaKmsPlane *plane,
MtkMonitorTransform transform);
gboolean meta_kms_plane_is_color_encoding_handled (MetaKmsPlane *plane,
MetaKmsPlaneYCbCrColorEncoding encoding);
gboolean meta_kms_plane_is_color_range_handled (MetaKmsPlane *plane,
MetaKmsPlaneYCbCrColorRange range);
gboolean meta_kms_plane_supports_cursor_hotspot (MetaKmsPlane *plane);
GArray * meta_kms_plane_get_modifiers_for_format (MetaKmsPlane *plane,
@ -77,4 +98,12 @@ void meta_kms_plane_update_set_rotation (MetaKmsPlane *plane,
MetaKmsPlaneAssignment *plane_assignment,
MtkMonitorTransform transform);
void meta_kms_plane_update_set_color_encoding (MetaKmsPlane *plane,
MetaKmsPlaneAssignment *plane_assignment,
MetaKmsPlaneYCbCrColorEncoding encoding);
void meta_kms_plane_update_set_color_range (MetaKmsPlane *plane,
MetaKmsPlaneAssignment *plane_assignment,
MetaKmsPlaneYCbCrColorRange range);
const char * meta_kms_plane_type_to_string (MetaKmsPlaneType plane_type);

View File

@ -71,6 +71,16 @@ typedef struct _MetaKmsPlaneAssignment
int x;
int y;
} cursor_hotspot;
struct {
gboolean has_update;
MetaKmsPlaneYCbCrColorEncoding value;
} color_encoding;
struct {
gboolean has_update;
MetaKmsPlaneYCbCrColorRange value;
} color_range;
} MetaKmsPlaneAssignment;
typedef struct _MetaKmsModeSet
@ -172,6 +182,12 @@ MetaKmsFeedback * meta_kms_feedback_new_failed (GList *failed_planes,
void meta_kms_plane_assignment_set_rotation (MetaKmsPlaneAssignment *plane_assignment,
MetaKmsPlaneRotation rotation);
void meta_kms_plane_assignment_set_color_encoding (MetaKmsPlaneAssignment *plane_assignment,
MetaKmsPlaneYCbCrColorEncoding color_encoding);
void meta_kms_plane_assignment_set_color_range (MetaKmsPlaneAssignment *plane_assignment,
MetaKmsPlaneYCbCrColorRange range);
META_EXPORT_TEST
MetaKmsPlaneAssignment * meta_kms_update_get_primary_plane_assignment (MetaKmsUpdate *update,
MetaKmsCrtc *crtc);

View File

@ -660,6 +660,22 @@ meta_kms_plane_assignment_set_rotation (MetaKmsPlaneAssignment *plane_assignment
plane_assignment->rotation = rotation;
}
void
meta_kms_plane_assignment_set_color_encoding (MetaKmsPlaneAssignment *plane_assignment,
MetaKmsPlaneYCbCrColorEncoding encoding)
{
plane_assignment->color_encoding.has_update = TRUE;
plane_assignment->color_encoding.value = encoding;
}
void
meta_kms_plane_assignment_set_color_range (MetaKmsPlaneAssignment *plane_assignment,
MetaKmsPlaneYCbCrColorRange range)
{
plane_assignment->color_range.has_update = TRUE;
plane_assignment->color_range.value = range;
}
void
meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane_assignment,
int x,