From be36c18787b146bfbefe16f833dee5c8eee7dfff Mon Sep 17 00:00:00 2001 From: Dor Askayo Date: Fri, 10 Jun 2022 19:45:47 +0300 Subject: [PATCH] output/kms: Initialize variable refresh rate output modes Add variable refresh rate output modes for connectors that are VRR capable when VRR is not disabled for the GPU. Variable refresh rate output modes are sorted before their fixed refresh rate counterparts. They are also marked as the preferred mode for the output between the two. Part-of: --- src/backends/native/meta-output-kms.c | 55 ++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c index db2c54863..c82b7b29c 100644 --- a/src/backends/native/meta-output-kms.c +++ b/src/backends/native/meta-output-kms.c @@ -108,7 +108,8 @@ meta_output_kms_read_edid (MetaOutputNative *output_native) static void add_common_modes (MetaOutputInfo *output_info, - MetaGpuKms *gpu_kms) + MetaGpuKms *gpu_kms, + gboolean add_vrr_modes) { MetaCrtcMode *crtc_mode; GPtrArray *array; @@ -179,6 +180,14 @@ add_common_modes (MetaOutputInfo *output_info, if (is_duplicate) continue; + if (add_vrr_modes) + { + crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, + fallback_mode, + META_CRTC_REFRESH_RATE_MODE_VARIABLE); + g_ptr_array_add (array, crtc_mode); + } + crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, fallback_mode, META_CRTC_REFRESH_RATE_MODE_FIXED); @@ -212,6 +221,9 @@ compare_modes (const void *one, if (crtc_mode_info_one->refresh_rate != crtc_mode_info_two->refresh_rate) return (crtc_mode_info_one->refresh_rate > crtc_mode_info_two->refresh_rate ? -1 : 1); + if (crtc_mode_info_one->refresh_rate_mode != crtc_mode_info_two->refresh_rate_mode) + return (crtc_mode_info_one->refresh_rate_mode > + crtc_mode_info_two->refresh_rate_mode) ? -1 : 1; return g_strcmp0 (meta_crtc_mode_get_name (crtc_mode_one), meta_crtc_mode_get_name (crtc_mode_two)); @@ -241,7 +253,8 @@ static void maybe_add_fallback_modes (const MetaKmsConnectorState *connector_state, MetaOutputInfo *output_info, MetaGpuKms *gpu_kms, - MetaKmsConnector *kms_connector) + MetaKmsConnector *kms_connector, + gboolean add_vrr_modes) { if (!connector_state->modes) return; @@ -256,7 +269,7 @@ maybe_add_fallback_modes (const MetaKmsConnectorState *connector_state, meta_topic (META_DEBUG_KMS, "Adding common modes to connector %u on %s", meta_kms_connector_get_id (kms_connector), meta_gpu_kms_get_file_path (gpu_kms)); - add_common_modes (output_info, gpu_kms); + add_common_modes (output_info, gpu_kms, add_vrr_modes); } static gboolean @@ -267,6 +280,7 @@ init_output_modes (MetaOutputInfo *output_info, { const MetaKmsConnectorState *connector_state; MetaKmsMode *kms_preferred_mode; + gboolean add_vrr_modes; GList *l; int i; @@ -275,22 +289,45 @@ init_output_modes (MetaOutputInfo *output_info, output_info->preferred_mode = NULL; - output_info->n_modes = g_list_length (connector_state->modes); + add_vrr_modes = connector_state->vrr_capable && + !meta_gpu_kms_disable_vrr (gpu_kms); + + if (add_vrr_modes) + output_info->n_modes = g_list_length (connector_state->modes) * 2; + else + output_info->n_modes = g_list_length (connector_state->modes); + output_info->modes = g_new0 (MetaCrtcMode *, output_info->n_modes); - for (l = connector_state->modes, i = 0; l; l = l->next, i++) + + for (l = connector_state->modes, i = 0; l; l = l->next) { MetaKmsMode *kms_mode = l->data; MetaCrtcMode *crtc_mode; + if (add_vrr_modes) + { + crtc_mode = + meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, + kms_mode, + META_CRTC_REFRESH_RATE_MODE_VARIABLE); + output_info->modes[i++] = crtc_mode; + if (!output_info->preferred_mode && kms_mode == kms_preferred_mode) + output_info->preferred_mode = crtc_mode; + } + crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, kms_mode, META_CRTC_REFRESH_RATE_MODE_FIXED); - output_info->modes[i] = crtc_mode; - if (kms_mode == kms_preferred_mode) - output_info->preferred_mode = output_info->modes[i]; + output_info->modes[i++] = crtc_mode; + if (!output_info->preferred_mode && kms_mode == kms_preferred_mode) + output_info->preferred_mode = crtc_mode; } - maybe_add_fallback_modes (connector_state, output_info, gpu_kms, kms_connector); + maybe_add_fallback_modes (connector_state, + output_info, + gpu_kms, + kms_connector, + add_vrr_modes); if (!output_info->modes) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,