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,