diff --git a/src/backends/meta-crtc-mode.h b/src/backends/meta-crtc-mode.h index 9c3e5cacc..0a75f3a67 100644 --- a/src/backends/meta-crtc-mode.h +++ b/src/backends/meta-crtc-mode.h @@ -44,6 +44,12 @@ typedef enum _MetaCrtcModeFlag META_CRTC_MODE_FLAG_MASK = 0x3fff } MetaCrtcModeFlag; +typedef enum _MetaCrtcRefreshRateMode +{ + META_CRTC_REFRESH_RATE_MODE_FIXED, + META_CRTC_REFRESH_RATE_MODE_VARIABLE, +} MetaCrtcRefreshRateMode; + typedef struct _MetaCrtcModeInfo { grefcount ref_count; @@ -51,6 +57,7 @@ typedef struct _MetaCrtcModeInfo int width; int height; float refresh_rate; + MetaCrtcRefreshRateMode refresh_rate_mode; int64_t vblank_duration_us; uint32_t pixel_clock_khz; MetaCrtcModeFlag flags; diff --git a/src/backends/native/meta-crtc-mode-kms.c b/src/backends/native/meta-crtc-mode-kms.c index d9a4b2613..5df1bedf6 100644 --- a/src/backends/native/meta-crtc-mode-kms.c +++ b/src/backends/native/meta-crtc-mode-kms.c @@ -39,8 +39,9 @@ meta_crtc_mode_kms_get_kms_mode (MetaCrtcModeKms *mode_kms) } MetaCrtcModeKms * -meta_crtc_mode_kms_new (MetaKmsMode *kms_mode, - uint64_t id) +meta_crtc_mode_kms_new (MetaKmsMode *kms_mode, + MetaCrtcRefreshRateMode refresh_rate_mode, + uint64_t id) { const drmModeModeInfo *drm_mode = meta_kms_mode_get_drm_mode (kms_mode); g_autoptr (MetaCrtcModeInfo) crtc_mode_info = NULL; @@ -53,6 +54,8 @@ meta_crtc_mode_kms_new (MetaKmsMode *kms_mode, crtc_mode_info->flags = drm_mode->flags; crtc_mode_info->refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); + crtc_mode_info->refresh_rate_mode = + refresh_rate_mode; crtc_mode_info->vblank_duration_us = meta_calculate_drm_mode_vblank_duration_us (drm_mode); crtc_mode_info->pixel_clock_khz = drm_mode->clock; diff --git a/src/backends/native/meta-crtc-mode-kms.h b/src/backends/native/meta-crtc-mode-kms.h index d3fe273e7..d85e36d66 100644 --- a/src/backends/native/meta-crtc-mode-kms.h +++ b/src/backends/native/meta-crtc-mode-kms.h @@ -30,5 +30,6 @@ G_DECLARE_FINAL_TYPE (MetaCrtcModeKms, meta_crtc_mode_kms, MetaKmsMode * meta_crtc_mode_kms_get_kms_mode (MetaCrtcModeKms *mode_kms); -MetaCrtcModeKms * meta_crtc_mode_kms_new (MetaKmsMode *kms_mode, - uint64_t id); +MetaCrtcModeKms * meta_crtc_mode_kms_new (MetaKmsMode *kms_mode, + MetaCrtcRefreshRateMode refresh_rate_mode, + uint64_t id); diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c index 7e88a5e91..3e0ad99c5 100644 --- a/src/backends/native/meta-gpu-kms.c +++ b/src/backends/native/meta-gpu-kms.c @@ -162,8 +162,9 @@ compare_outputs (gconstpointer one, } MetaCrtcMode * -meta_gpu_kms_get_mode_from_kms_mode (MetaGpuKms *gpu_kms, - MetaKmsMode *kms_mode) +meta_gpu_kms_get_mode_from_kms_mode (MetaGpuKms *gpu_kms, + MetaKmsMode *kms_mode, + MetaCrtcRefreshRateMode refresh_rate_mode) { MetaGpu *gpu = META_GPU (gpu_kms); GList *l; @@ -171,10 +172,22 @@ meta_gpu_kms_get_mode_from_kms_mode (MetaGpuKms *gpu_kms, for (l = meta_gpu_get_modes (gpu); l; l = l->next) { MetaCrtcModeKms *crtc_mode_kms = l->data; + MetaCrtcMode *crtc_mode; + const MetaCrtcModeInfo *crtc_mode_info; - if (meta_kms_mode_equal (kms_mode, - meta_crtc_mode_kms_get_kms_mode (crtc_mode_kms))) - return META_CRTC_MODE (crtc_mode_kms); + if (!meta_kms_mode_equal (kms_mode, + meta_crtc_mode_kms_get_kms_mode (crtc_mode_kms))) + continue; + + crtc_mode = META_CRTC_MODE (crtc_mode_kms); + + crtc_mode_info = meta_crtc_mode_get_info (crtc_mode); + g_assert (crtc_mode_info != NULL); + + if (refresh_rate_mode != crtc_mode_info->refresh_rate_mode) + continue; + + return META_CRTC_MODE (crtc_mode_kms); } g_assert_not_reached (); @@ -274,7 +287,19 @@ init_modes (MetaGpuKms *gpu_kms) MetaKmsMode *kms_mode = value; MetaCrtcModeKms *mode; - mode = meta_crtc_mode_kms_new (kms_mode, mode_id); + if (!meta_gpu_kms_disable_vrr (gpu_kms)) + { + mode = meta_crtc_mode_kms_new (kms_mode, + META_CRTC_REFRESH_RATE_MODE_VARIABLE, + mode_id); + modes = g_list_append (modes, mode); + + mode_id++; + } + + mode = meta_crtc_mode_kms_new (kms_mode, + META_CRTC_REFRESH_RATE_MODE_FIXED, + mode_id); modes = g_list_append (modes, mode); mode_id++; diff --git a/src/backends/native/meta-gpu-kms.h b/src/backends/native/meta-gpu-kms.h index b3705819a..e5004a24d 100644 --- a/src/backends/native/meta-gpu-kms.h +++ b/src/backends/native/meta-gpu-kms.h @@ -56,8 +56,9 @@ void meta_gpu_kms_set_power_save_mode (MetaGpuKms *gpu_kms, uint64_t state, MetaKmsUpdate *kms_update); -MetaCrtcMode * meta_gpu_kms_get_mode_from_kms_mode (MetaGpuKms *gpu_kms, - MetaKmsMode *kms_mode); +MetaCrtcMode * meta_gpu_kms_get_mode_from_kms_mode (MetaGpuKms *gpu_kms, + MetaKmsMode *kms_mode, + MetaCrtcRefreshRateMode refresh_rate_mode); MetaGpuKmsFlipClosureContainer * meta_gpu_kms_wrap_flip_closure (MetaGpuKms *gpu_kms, MetaCrtc *crtc, diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c index a25fdaf81..db2c54863 100644 --- a/src/backends/native/meta-output-kms.c +++ b/src/backends/native/meta-output-kms.c @@ -179,7 +179,9 @@ add_common_modes (MetaOutputInfo *output_info, if (is_duplicate) continue; - crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, fallback_mode); + crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, + fallback_mode, + META_CRTC_REFRESH_RATE_MODE_FIXED); g_ptr_array_add (array, crtc_mode); } @@ -280,7 +282,9 @@ init_output_modes (MetaOutputInfo *output_info, MetaKmsMode *kms_mode = l->data; MetaCrtcMode *crtc_mode; - crtc_mode = meta_gpu_kms_get_mode_from_kms_mode (gpu_kms, kms_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];