kms: Allow setting the "VRR_ENABLED" property on a CRTC
Add functions to update and monitor the value of the "VRR_ENABLED" KMS property. This requires the addition of functions to process CRTC property updates in both the atomic and the simple KMS backends. The implementation is similar to the implemention of processing connector updates. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
This commit is contained in:
parent
b7128b1d12
commit
4ad282cf26
@ -28,6 +28,7 @@ typedef enum _MetaKmsCrtcProp
|
||||
META_KMS_CRTC_PROP_ACTIVE,
|
||||
META_KMS_CRTC_PROP_GAMMA_LUT,
|
||||
META_KMS_CRTC_PROP_GAMMA_LUT_SIZE,
|
||||
META_KMS_CRTC_PROP_VRR_ENABLED,
|
||||
META_KMS_CRTC_N_PROPS
|
||||
} MetaKmsCrtcProp;
|
||||
|
||||
|
@ -227,6 +227,9 @@ meta_kms_crtc_state_changes (MetaKmsCrtcState *state,
|
||||
if (!meta_drm_mode_equal (&state->drm_mode, &other_state->drm_mode))
|
||||
return META_KMS_RESOURCE_CHANGE_FULL;
|
||||
|
||||
if (state->vrr_enabled != other_state->vrr_enabled)
|
||||
return META_KMS_RESOURCE_CHANGE_FULL;
|
||||
|
||||
if (!gamma_equal (state, other_state))
|
||||
return META_KMS_RESOURCE_CHANGE_GAMMA;
|
||||
|
||||
@ -241,7 +244,7 @@ meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
|
||||
{
|
||||
MetaKmsCrtcState crtc_state = {0};
|
||||
MetaKmsResourceChanges changes = META_KMS_RESOURCE_CHANGE_NONE;
|
||||
MetaKmsProp *active_prop;
|
||||
MetaKmsProp *prop;
|
||||
|
||||
meta_kms_impl_device_update_prop_table (impl_device,
|
||||
drm_props->props,
|
||||
@ -260,13 +263,17 @@ meta_kms_crtc_read_state (MetaKmsCrtc *crtc,
|
||||
crtc_state.is_drm_mode_valid = drm_crtc->mode_valid;
|
||||
crtc_state.drm_mode = drm_crtc->mode;
|
||||
|
||||
active_prop = &crtc->prop_table.props[META_KMS_CRTC_PROP_ACTIVE];
|
||||
prop = &crtc->prop_table.props[META_KMS_CRTC_PROP_ACTIVE];
|
||||
|
||||
if (active_prop->prop_id)
|
||||
crtc_state.is_active = !!active_prop->value;
|
||||
if (prop->prop_id)
|
||||
crtc_state.is_active = !!prop->value;
|
||||
else
|
||||
crtc_state.is_active = drm_crtc->mode_valid;
|
||||
|
||||
prop = &crtc->prop_table.props[META_KMS_CRTC_PROP_VRR_ENABLED];
|
||||
if (prop->prop_id)
|
||||
crtc_state.vrr_enabled = !!prop->value;
|
||||
|
||||
read_gamma_state (crtc, &crtc_state, impl_device, drm_crtc);
|
||||
|
||||
if (!crtc_state.is_active)
|
||||
@ -343,6 +350,7 @@ meta_kms_crtc_predict_state_in_impl (MetaKmsCrtc *crtc,
|
||||
MetaKmsUpdate *update)
|
||||
{
|
||||
GList *mode_sets;
|
||||
GList *crtc_updates;
|
||||
GList *crtc_color_updates;
|
||||
GList *l;
|
||||
|
||||
@ -380,6 +388,20 @@ meta_kms_crtc_predict_state_in_impl (MetaKmsCrtc *crtc,
|
||||
break;
|
||||
}
|
||||
|
||||
crtc_updates = meta_kms_update_get_crtc_updates (update);
|
||||
for (l = crtc_updates; l; l = l->next)
|
||||
{
|
||||
MetaKmsCrtcUpdate *crtc_update = l->data;
|
||||
|
||||
if (crtc_update->crtc != crtc)
|
||||
continue;
|
||||
|
||||
if (crtc_update->vrr.has_update)
|
||||
crtc->current_state.vrr_enabled = !!crtc_update->vrr.is_enabled;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
crtc_color_updates = meta_kms_update_get_crtc_color_updates (update);
|
||||
for (l = crtc_color_updates; l; l = l->next)
|
||||
{
|
||||
@ -430,6 +452,11 @@ init_properties (MetaKmsCrtc *crtc,
|
||||
.name = "GAMMA_LUT_SIZE",
|
||||
.type = DRM_MODE_PROP_RANGE,
|
||||
},
|
||||
[META_KMS_CRTC_PROP_VRR_ENABLED] =
|
||||
{
|
||||
.name = "VRR_ENABLED",
|
||||
.type = DRM_MODE_PROP_RANGE,
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -34,6 +34,8 @@ typedef struct _MetaKmsCrtcState
|
||||
gboolean is_drm_mode_valid;
|
||||
drmModeModeInfo drm_mode;
|
||||
|
||||
gboolean vrr_enabled;
|
||||
|
||||
struct {
|
||||
MetaGammaLut *value;
|
||||
int size;
|
||||
|
@ -362,6 +362,31 @@ add_crtc_property (MetaKmsImplDevice *impl_device,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_crtc_update (MetaKmsImplDevice *impl_device,
|
||||
MetaKmsUpdate *update,
|
||||
drmModeAtomicReq *req,
|
||||
GArray *blob_ids,
|
||||
gpointer update_entry,
|
||||
gpointer user_data,
|
||||
GError **error)
|
||||
{
|
||||
MetaKmsCrtcUpdate *crtc_update = update_entry;
|
||||
MetaKmsCrtc *crtc = crtc_update->crtc;
|
||||
|
||||
if (crtc_update->vrr.has_update)
|
||||
{
|
||||
if (!add_crtc_property (impl_device,
|
||||
crtc, req,
|
||||
META_KMS_CRTC_PROP_VRR_ENABLED,
|
||||
!!crtc_update->vrr.is_enabled,
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_mode_set (MetaKmsImplDevice *impl_device,
|
||||
MetaKmsUpdate *update,
|
||||
@ -1086,6 +1111,16 @@ meta_kms_impl_device_atomic_process_update (MetaKmsImplDevice *impl_device,
|
||||
&error))
|
||||
goto err;
|
||||
|
||||
if (!process_entries (impl_device,
|
||||
update,
|
||||
req,
|
||||
blob_ids,
|
||||
meta_kms_update_get_crtc_updates (update),
|
||||
NULL,
|
||||
process_crtc_update,
|
||||
&error))
|
||||
goto err;
|
||||
|
||||
if (!process_entries (impl_device,
|
||||
update,
|
||||
req,
|
||||
|
@ -179,6 +179,47 @@ set_connector_property (MetaKmsImplDevice *impl_device,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
set_crtc_property (MetaKmsImplDevice *impl_device,
|
||||
MetaKmsCrtc *crtc,
|
||||
MetaKmsCrtcProp prop,
|
||||
uint64_t value,
|
||||
GError **error)
|
||||
{
|
||||
uint32_t prop_id;
|
||||
int fd;
|
||||
int ret;
|
||||
|
||||
prop_id = meta_kms_crtc_get_prop_id (crtc, prop);
|
||||
if (!prop_id)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
|
||||
"Property (%s) not found on CRTC %u",
|
||||
meta_kms_crtc_get_prop_name (crtc, prop),
|
||||
meta_kms_crtc_get_id (crtc));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
fd = meta_kms_impl_device_get_fd (impl_device);
|
||||
|
||||
ret = drmModeObjectSetProperty (fd,
|
||||
meta_kms_crtc_get_id (crtc),
|
||||
DRM_MODE_OBJECT_CRTC,
|
||||
prop_id,
|
||||
value);
|
||||
if (ret != 0)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (-ret),
|
||||
"Failed to set CRTC %u property %u: %s",
|
||||
meta_kms_crtc_get_id (crtc),
|
||||
prop_id,
|
||||
g_strerror (-ret));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_connector_update (MetaKmsImplDevice *impl_device,
|
||||
MetaKmsUpdate *update,
|
||||
@ -268,6 +309,28 @@ process_connector_update (MetaKmsImplDevice *impl_device,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
process_crtc_update (MetaKmsImplDevice *impl_device,
|
||||
MetaKmsUpdate *update,
|
||||
gpointer update_entry,
|
||||
GError **error)
|
||||
{
|
||||
MetaKmsCrtcUpdate *crtc_update = update_entry;
|
||||
MetaKmsCrtc *crtc = crtc_update->crtc;
|
||||
|
||||
if (crtc_update->vrr.has_update)
|
||||
{
|
||||
if (!set_crtc_property (impl_device,
|
||||
crtc,
|
||||
META_KMS_CRTC_PROP_VRR_ENABLED,
|
||||
!!crtc_update->vrr.is_enabled,
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static CachedModeSet *
|
||||
cached_mode_set_new (GList *connectors,
|
||||
const drmModeModeInfo *drm_mode,
|
||||
@ -1548,6 +1611,13 @@ meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device,
|
||||
&error))
|
||||
goto err;
|
||||
|
||||
if (!process_entries (impl_device,
|
||||
update,
|
||||
meta_kms_update_get_crtc_updates (update),
|
||||
process_crtc_update,
|
||||
&error))
|
||||
goto err;
|
||||
|
||||
if (!process_plane_assignments (impl_device, update, &failed_planes, &error))
|
||||
goto err;
|
||||
|
||||
|
@ -117,6 +117,16 @@ typedef struct _MetaKmsConnectorUpdate
|
||||
} broadcast_rgb;
|
||||
} MetaKmsConnectorUpdate;
|
||||
|
||||
typedef struct _MetaKmsCrtcUpdate
|
||||
{
|
||||
MetaKmsCrtc *crtc;
|
||||
|
||||
struct {
|
||||
gboolean has_update;
|
||||
gboolean is_enabled;
|
||||
} vrr;
|
||||
} MetaKmsCrtcUpdate;
|
||||
|
||||
typedef struct _MetaKmsPageFlipListener
|
||||
{
|
||||
gatomicrefcount ref_count;
|
||||
@ -182,6 +192,9 @@ GList * meta_kms_update_get_page_flip_listeners (MetaKmsUpdate *update);
|
||||
META_EXPORT_TEST
|
||||
GList * meta_kms_update_get_connector_updates (MetaKmsUpdate *update);
|
||||
|
||||
META_EXPORT_TEST
|
||||
GList * meta_kms_update_get_crtc_updates (MetaKmsUpdate *update);
|
||||
|
||||
META_EXPORT_TEST
|
||||
GList * meta_kms_update_get_crtc_color_updates (MetaKmsUpdate *update);
|
||||
|
||||
|
@ -40,6 +40,7 @@ struct _MetaKmsUpdate
|
||||
GList *mode_sets;
|
||||
GList *plane_assignments;
|
||||
GList *connector_updates;
|
||||
GList *crtc_updates;
|
||||
GList *crtc_color_updates;
|
||||
|
||||
MetaKmsCustomPageFlip *custom_page_flip;
|
||||
@ -481,6 +482,46 @@ meta_kms_update_set_broadcast_rgb (MetaKmsUpdate *update,
|
||||
connector_update->broadcast_rgb.value = rgb_range;
|
||||
}
|
||||
|
||||
static MetaKmsCrtcUpdate *
|
||||
ensure_crtc_update (MetaKmsUpdate *update,
|
||||
MetaKmsCrtc *crtc)
|
||||
{
|
||||
GList *l;
|
||||
MetaKmsCrtcUpdate *crtc_update;
|
||||
|
||||
for (l = update->crtc_updates; l; l = l->next)
|
||||
{
|
||||
crtc_update = l->data;
|
||||
|
||||
if (crtc_update->crtc == crtc)
|
||||
return crtc_update;
|
||||
}
|
||||
|
||||
crtc_update = g_new0 (MetaKmsCrtcUpdate, 1);
|
||||
crtc_update->crtc = crtc;
|
||||
|
||||
update->crtc_updates = g_list_prepend (update->crtc_updates,
|
||||
crtc_update);
|
||||
|
||||
return crtc_update;
|
||||
}
|
||||
|
||||
void
|
||||
meta_kms_update_set_vrr (MetaKmsUpdate *update,
|
||||
MetaKmsCrtc *crtc,
|
||||
gboolean enabled)
|
||||
{
|
||||
MetaKmsCrtcUpdate *crtc_update;
|
||||
|
||||
g_assert (meta_kms_crtc_get_device (crtc) == update->device);
|
||||
|
||||
crtc_update = ensure_crtc_update (update, crtc);
|
||||
crtc_update->vrr.has_update = TRUE;
|
||||
crtc_update->vrr.is_enabled = enabled;
|
||||
|
||||
update_latch_crtc (update, crtc);
|
||||
}
|
||||
|
||||
static MetaKmsCrtcColorUpdate *
|
||||
ensure_color_update (MetaKmsUpdate *update,
|
||||
MetaKmsCrtc *crtc)
|
||||
@ -746,6 +787,12 @@ meta_kms_update_get_connector_updates (MetaKmsUpdate *update)
|
||||
return update->connector_updates;
|
||||
}
|
||||
|
||||
GList *
|
||||
meta_kms_update_get_crtc_updates (MetaKmsUpdate *update)
|
||||
{
|
||||
return update->crtc_updates;
|
||||
}
|
||||
|
||||
GList *
|
||||
meta_kms_update_get_crtc_color_updates (MetaKmsUpdate *update)
|
||||
{
|
||||
@ -921,6 +968,55 @@ merge_crtc_color_updates_from (MetaKmsUpdate *update,
|
||||
}
|
||||
}
|
||||
|
||||
static GList *
|
||||
find_crtc_update_link_for (MetaKmsUpdate *update,
|
||||
MetaKmsCrtc *crtc)
|
||||
{
|
||||
GList *l;
|
||||
|
||||
for (l = update->crtc_updates; l; l = l->next)
|
||||
{
|
||||
MetaKmsCrtcUpdate *crtc_update = l->data;
|
||||
|
||||
if (crtc_update->crtc == crtc)
|
||||
return l;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
merge_crtc_updates_from (MetaKmsUpdate *update,
|
||||
MetaKmsUpdate *other_update)
|
||||
{
|
||||
while (other_update->crtc_updates)
|
||||
{
|
||||
GList *l = other_update->crtc_updates;
|
||||
MetaKmsCrtcUpdate *other_crtc_update = l->data;
|
||||
MetaKmsCrtc *crtc = other_crtc_update->crtc;
|
||||
GList *el;
|
||||
|
||||
other_update->crtc_updates =
|
||||
g_list_remove_link (other_update->crtc_updates, l);
|
||||
|
||||
el = find_crtc_update_link_for (update, crtc);
|
||||
if (el)
|
||||
{
|
||||
MetaKmsCrtcUpdate *crtc_update = el->data;
|
||||
|
||||
if (other_crtc_update->vrr.has_update)
|
||||
crtc_update->vrr = other_crtc_update->vrr;
|
||||
}
|
||||
else
|
||||
{
|
||||
update->crtc_updates =
|
||||
g_list_insert_before_link (update->crtc_updates,
|
||||
update->crtc_updates,
|
||||
l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static GList *
|
||||
find_connector_update_link_for (MetaKmsUpdate *update,
|
||||
MetaKmsConnector *connector)
|
||||
@ -1034,6 +1130,7 @@ meta_kms_update_merge_from (MetaKmsUpdate *update,
|
||||
|
||||
merge_mode_sets (update, other_update);
|
||||
merge_plane_assignments_from (update, other_update);
|
||||
merge_crtc_updates_from (update, other_update);
|
||||
merge_crtc_color_updates_from (update, other_update);
|
||||
merge_connector_updates_from (update, other_update);
|
||||
merge_custom_page_flip_from (update, other_update);
|
||||
@ -1074,6 +1171,7 @@ meta_kms_update_free (MetaKmsUpdate *update)
|
||||
g_list_free_full (update->page_flip_listeners,
|
||||
(GDestroyNotify) meta_kms_page_flip_listener_unref);
|
||||
g_list_free_full (update->connector_updates, g_free);
|
||||
g_list_free_full (update->crtc_updates, g_free);
|
||||
g_list_free_full (update->crtc_color_updates,
|
||||
(GDestroyNotify) meta_kms_crtc_color_updates_free);
|
||||
g_clear_pointer (&update->custom_page_flip, meta_kms_custom_page_flip_free);
|
||||
@ -1108,5 +1206,6 @@ meta_kms_update_is_empty (MetaKmsUpdate *update)
|
||||
return (!update->mode_sets &&
|
||||
!update->plane_assignments &&
|
||||
!update->connector_updates &&
|
||||
!update->crtc_updates &&
|
||||
!update->crtc_color_updates);
|
||||
}
|
||||
|
@ -147,6 +147,11 @@ void meta_kms_update_mode_set (MetaKmsUpdate *update,
|
||||
GList *connectors,
|
||||
MetaKmsMode *mode);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_kms_update_set_vrr (MetaKmsUpdate *update,
|
||||
MetaKmsCrtc *crtc,
|
||||
gboolean enabled);
|
||||
|
||||
META_EXPORT_TEST
|
||||
void meta_kms_update_set_crtc_gamma (MetaKmsUpdate *update,
|
||||
MetaKmsCrtc *crtc,
|
||||
|
@ -111,6 +111,8 @@ assert_crtc_state_equals (const MetaKmsCrtcState *crtc_state1,
|
||||
crtc_state2->drm_mode.name);
|
||||
}
|
||||
|
||||
g_assert_true (crtc_state1->vrr_enabled == crtc_state2->vrr_enabled);
|
||||
|
||||
g_assert_true (meta_gamma_lut_equal (crtc_state1->gamma.value,
|
||||
crtc_state2->gamma.value));
|
||||
}
|
||||
@ -208,6 +210,9 @@ copy_crtc_state (const MetaKmsCrtcState *crtc_state)
|
||||
g_assert_nonnull (crtc_state);
|
||||
|
||||
new_state = *crtc_state;
|
||||
|
||||
new_state.vrr_enabled = crtc_state->vrr_enabled;
|
||||
|
||||
if (crtc_state->gamma.value)
|
||||
new_state.gamma.value = meta_gamma_lut_copy (crtc_state->gamma.value);
|
||||
else
|
||||
|
@ -95,6 +95,7 @@ meta_test_kms_update_sanity (void)
|
||||
g_assert_null (meta_kms_update_get_mode_sets (update));
|
||||
g_assert_null (meta_kms_update_get_page_flip_listeners (update));
|
||||
g_assert_null (meta_kms_update_get_connector_updates (update));
|
||||
g_assert_null (meta_kms_update_get_crtc_updates (update));
|
||||
g_assert_null (meta_kms_update_get_crtc_color_updates (update));
|
||||
meta_kms_update_free (update);
|
||||
}
|
||||
@ -430,6 +431,8 @@ meta_test_kms_update_merge (void)
|
||||
GList *plane_assignments;
|
||||
MetaKmsPlaneAssignment *plane_assignment;
|
||||
MetaGammaLut *crtc_gamma;
|
||||
GList *crtc_updates;
|
||||
MetaKmsCrtcUpdate *crtc_update;
|
||||
GList *connector_updates;
|
||||
MetaKmsConnectorUpdate *connector_update;
|
||||
|
||||
@ -475,6 +478,10 @@ meta_test_kms_update_merge (void)
|
||||
meta_kms_plane_assignment_set_cursor_hotspot (cursor_plane_assignment,
|
||||
10, 11);
|
||||
|
||||
meta_kms_update_set_vrr (update1,
|
||||
crtc,
|
||||
TRUE);
|
||||
|
||||
meta_kms_update_set_underscanning (update1,
|
||||
connector,
|
||||
123, 456);
|
||||
@ -605,6 +612,14 @@ meta_test_kms_update_merge (void)
|
||||
}
|
||||
}
|
||||
|
||||
crtc_updates = meta_kms_update_get_crtc_updates (update1);
|
||||
g_assert_cmpuint (g_list_length (crtc_updates), ==, 1);
|
||||
crtc_update = crtc_updates->data;
|
||||
g_assert_nonnull (crtc_update);
|
||||
|
||||
g_assert_true (crtc_update->vrr.has_update);
|
||||
g_assert_true (crtc_update->vrr.is_enabled);
|
||||
|
||||
connector_updates = meta_kms_update_get_connector_updates (update1);
|
||||
g_assert_cmpuint (g_list_length (connector_updates), ==, 1);
|
||||
connector_update = connector_updates->data;
|
||||
|
Loading…
Reference in New Issue
Block a user