diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c index 0100d532c..3587cf8fd 100644 --- a/src/backends/native/meta-gpu-kms.c +++ b/src/backends/native/meta-gpu-kms.c @@ -48,8 +48,6 @@ #include "backends/native/meta-launcher.h" #include "backends/native/meta-output-kms.h" -#include "meta-default-modes.h" - struct _MetaGpuKms { MetaGpu parent; @@ -395,12 +393,12 @@ static void init_modes (MetaGpuKms *gpu_kms) { MetaGpu *gpu = META_GPU (gpu_kms); + MetaKmsDevice *kms_device = gpu_kms->kms_device; GHashTable *modes_table; GList *l; GList *modes; GHashTableIter iter; drmModeModeInfo *drm_mode; - int i; long mode_id; /* @@ -427,6 +425,15 @@ init_modes (MetaGpuKms *gpu_kms) } } + for (l = meta_kms_device_get_fallback_modes (kms_device); l; l = l->next) + { + MetaKmsMode *fallback_mode = l->data; + const drmModeModeInfo *drm_mode; + + drm_mode = meta_kms_mode_get_drm_mode (fallback_mode); + g_hash_table_add (modes_table, (drmModeModeInfo *) drm_mode); + } + modes = NULL; g_hash_table_iter_init (&iter, modes_table); @@ -443,28 +450,6 @@ init_modes (MetaGpuKms *gpu_kms) g_hash_table_destroy (modes_table); - for (i = 0; i < G_N_ELEMENTS (meta_default_landscape_drm_mode_infos); i++) - { - MetaCrtcModeKms *mode; - - mode = meta_crtc_mode_kms_new (&meta_default_landscape_drm_mode_infos[i], - mode_id); - modes = g_list_append (modes, mode); - - mode_id++; - } - - for (i = 0; i < G_N_ELEMENTS (meta_default_portrait_drm_mode_infos); i++) - { - MetaCrtcModeKms *mode; - - mode = meta_crtc_mode_kms_new (&meta_default_portrait_drm_mode_infos[i], - mode_id); - modes = g_list_append (modes, mode); - - mode_id++; - } - meta_gpu_take_modes (gpu, modes); } diff --git a/src/backends/native/meta-kms-device.c b/src/backends/native/meta-kms-device.c index 937d44a2c..e3779896c 100644 --- a/src/backends/native/meta-kms-device.c +++ b/src/backends/native/meta-kms-device.c @@ -47,6 +47,8 @@ struct _MetaKmsDevice GList *planes; MetaKmsDeviceCaps caps; + + GList *fallback_modes; }; G_DEFINE_TYPE (MetaKmsDevice, meta_kms_device, G_TYPE_OBJECT); @@ -157,6 +159,12 @@ meta_kms_device_get_cursor_plane_for (MetaKmsDevice *device, return get_plane_with_type_for (device, crtc, META_KMS_PLANE_TYPE_CURSOR); } +GList * +meta_kms_device_get_fallback_modes (MetaKmsDevice *device) +{ + return device->fallback_modes; +} + void meta_kms_device_update_states_in_impl (MetaKmsDevice *device) { @@ -214,6 +222,7 @@ typedef struct _CreateImplDeviceData GList *out_connectors; GList *out_planes; MetaKmsDeviceCaps out_caps; + GList *out_fallback_modes; char *out_driver_name; char *out_driver_description; } CreateImplDeviceData; @@ -235,6 +244,8 @@ create_impl_device_in_impl (MetaKmsImpl *impl, data->out_connectors = meta_kms_impl_device_copy_connectors (impl_device); data->out_planes = meta_kms_impl_device_copy_planes (impl_device); data->out_caps = *meta_kms_impl_device_get_caps (impl_device); + data->out_fallback_modes = + meta_kms_impl_device_copy_fallback_modes (impl_device); data->out_driver_name = g_strdup (meta_kms_impl_device_get_driver_name (impl_device)); data->out_driver_description = @@ -282,6 +293,7 @@ meta_kms_device_new (MetaKms *kms, device->connectors = data.out_connectors; device->planes = data.out_planes; device->caps = data.out_caps; + device->fallback_modes = data.out_fallback_modes; device->driver_name = data.out_driver_name; device->driver_description = data.out_driver_description; diff --git a/src/backends/native/meta-kms-device.h b/src/backends/native/meta-kms-device.h index a346c01e3..bd2e85667 100644 --- a/src/backends/native/meta-kms-device.h +++ b/src/backends/native/meta-kms-device.h @@ -53,6 +53,8 @@ MetaKmsPlane * meta_kms_device_get_primary_plane_for (MetaKmsDevice *device, MetaKmsPlane * meta_kms_device_get_cursor_plane_for (MetaKmsDevice *device, MetaKmsCrtc *crtc); +GList * meta_kms_device_get_fallback_modes (MetaKmsDevice *device); + MetaKmsDevice * meta_kms_device_new (MetaKms *kms, const char *path, MetaKmsDeviceFlag flags, diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c index 6beef4f52..4e3c011ce 100644 --- a/src/backends/native/meta-kms-impl-device.c +++ b/src/backends/native/meta-kms-impl-device.c @@ -29,12 +29,15 @@ #include "backends/native/meta-kms-crtc-private.h" #include "backends/native/meta-kms-crtc.h" #include "backends/native/meta-kms-impl.h" +#include "backends/native/meta-kms-mode-private.h" #include "backends/native/meta-kms-page-flip-private.h" #include "backends/native/meta-kms-plane-private.h" #include "backends/native/meta-kms-plane.h" #include "backends/native/meta-kms-private.h" #include "backends/native/meta-kms-update.h" +#include "meta-default-modes.h" + struct _MetaKmsImplDevice { GObject parent; @@ -53,6 +56,8 @@ struct _MetaKmsImplDevice GList *planes; MetaKmsDeviceCaps caps; + + GList *fallback_modes; }; G_DEFINE_TYPE (MetaKmsImplDevice, meta_kms_impl_device, G_TYPE_OBJECT) @@ -87,6 +92,12 @@ meta_kms_impl_device_get_caps (MetaKmsImplDevice *impl_device) return &impl_device->caps; } +GList * +meta_kms_impl_device_copy_fallback_modes (MetaKmsImplDevice *impl_device) +{ + return g_list_copy (impl_device->fallback_modes); +} + const char * meta_kms_impl_device_get_driver_name (MetaKmsImplDevice *impl_device) { @@ -372,6 +383,35 @@ init_planes (MetaKmsImplDevice *impl_device) impl_device->planes = g_list_reverse (impl_device->planes); } +static void +init_fallback_modes (MetaKmsImplDevice *impl_device) +{ + GList *modes = NULL; + int i; + + for (i = 0; i < G_N_ELEMENTS (meta_default_landscape_drm_mode_infos); i++) + { + MetaKmsMode *mode; + + mode = meta_kms_mode_new (impl_device, + &meta_default_landscape_drm_mode_infos[i], + META_KMS_MODE_FLAG_FALLBACK_LANDSCAPE); + modes = g_list_prepend (modes, mode); + } + + for (i = 0; i < G_N_ELEMENTS (meta_default_portrait_drm_mode_infos); i++) + { + MetaKmsMode *mode; + + mode = meta_kms_mode_new (impl_device, + &meta_default_portrait_drm_mode_infos[i], + META_KMS_MODE_FLAG_FALLBACK_PORTRAIT); + modes = g_list_prepend (modes, mode); + } + + impl_device->fallback_modes = g_list_reverse (modes); +} + static void init_info (MetaKmsImplDevice *impl_device) { @@ -468,6 +508,8 @@ meta_kms_impl_device_new (MetaKmsDevice *device, init_planes (impl_device); init_info (impl_device); + init_fallback_modes (impl_device); + update_connectors (impl_device, drm_resources); drmModeFreeResources (drm_resources); @@ -516,6 +558,8 @@ meta_kms_impl_device_finalize (GObject *object) g_list_free_full (impl_device->planes, g_object_unref); g_list_free_full (impl_device->crtcs, g_object_unref); g_list_free_full (impl_device->connectors, g_object_unref); + g_list_free_full (impl_device->fallback_modes, + (GDestroyNotify) meta_kms_mode_free); g_free (impl_device->driver_name); g_free (impl_device->driver_description); diff --git a/src/backends/native/meta-kms-impl-device.h b/src/backends/native/meta-kms-impl-device.h index e55a95b58..9678f6d36 100644 --- a/src/backends/native/meta-kms-impl-device.h +++ b/src/backends/native/meta-kms-impl-device.h @@ -50,6 +50,8 @@ GList * meta_kms_impl_device_copy_planes (MetaKmsImplDevice *impl_device); const MetaKmsDeviceCaps * meta_kms_impl_device_get_caps (MetaKmsImplDevice *impl_device); +GList * meta_kms_impl_device_copy_fallback_modes (MetaKmsImplDevice *impl_device); + const char * meta_kms_impl_device_get_driver_name (MetaKmsImplDevice *impl_device); const char * meta_kms_impl_device_get_driver_description (MetaKmsImplDevice *impl_device); diff --git a/src/backends/native/meta-kms-mode.h b/src/backends/native/meta-kms-mode.h index cbdf24651..007638a59 100644 --- a/src/backends/native/meta-kms-mode.h +++ b/src/backends/native/meta-kms-mode.h @@ -29,6 +29,8 @@ typedef enum _MetaKmsModeFlag { META_KMS_MODE_FLAG_NONE = 0, + META_KMS_MODE_FLAG_FALLBACK_LANDSCAPE = 1 << 0, + META_KMS_MODE_FLAG_FALLBACK_PORTRAIT = 1 << 1, } MetaKmsModeFlag; const char * meta_kms_mode_get_name (MetaKmsMode *mode); diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c index 2d5e444b1..d581b79fd 100644 --- a/src/backends/native/meta-output-kms.c +++ b/src/backends/native/meta-output-kms.c @@ -30,13 +30,12 @@ #include "backends/meta-crtc.h" #include "backends/native/meta-kms-connector.h" +#include "backends/native/meta-kms-device.h" #include "backends/native/meta-kms-mode.h" #include "backends/native/meta-kms-utils.h" #include "backends/native/meta-crtc-kms.h" #include "backends/native/meta-crtc-mode-kms.h" -#include "meta-default-modes.h" - #define SYNC_TOLERANCE 0.01 /* 1 percent */ typedef struct _MetaOutputKms @@ -152,6 +151,9 @@ add_common_modes (MetaOutputInfo *output_info, unsigned max_hdisplay = 0; unsigned max_vdisplay = 0; float max_refresh_rate = 0.0; + MetaKmsDevice *kms_device; + MetaKmsModeFlag flag_filter; + GList *l; for (i = 0; i < output_info->n_modes; i++) { @@ -168,38 +170,32 @@ add_common_modes (MetaOutputInfo *output_info, max_refresh_rate = MAX (max_refresh_rate, 60.0); max_refresh_rate *= (1 + SYNC_TOLERANCE); + kms_device = meta_gpu_kms_get_kms_device (gpu_kms); + array = g_ptr_array_new (); + if (max_hdisplay > max_vdisplay) - { - for (i = 0; i < G_N_ELEMENTS (meta_default_landscape_drm_mode_infos); i++) - { - drm_mode = &meta_default_landscape_drm_mode_infos[i]; - refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); - if (drm_mode->hdisplay > max_hdisplay || - drm_mode->vdisplay > max_vdisplay || - refresh_rate > max_refresh_rate) - continue; - - crtc_mode = meta_gpu_kms_get_mode_from_drm_mode (gpu_kms, - drm_mode); - g_ptr_array_add (array, crtc_mode); - } - } + flag_filter = META_KMS_MODE_FLAG_FALLBACK_LANDSCAPE; else - { - for (i = 0; i < G_N_ELEMENTS (meta_default_portrait_drm_mode_infos); i++) - { - drm_mode = &meta_default_portrait_drm_mode_infos[i]; - refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); - if (drm_mode->hdisplay > max_hdisplay || - drm_mode->vdisplay > max_vdisplay || - refresh_rate > max_refresh_rate) - continue; + flag_filter = META_KMS_MODE_FLAG_FALLBACK_PORTRAIT; - crtc_mode = meta_gpu_kms_get_mode_from_drm_mode (gpu_kms, - drm_mode); - g_ptr_array_add (array, crtc_mode); - } + for (l = meta_kms_device_get_fallback_modes (kms_device); l; l = l->next) + { + MetaKmsMode *fallback_mode = l->data; + const drmModeModeInfo *drm_mode; + + if (!(meta_kms_mode_get_flags (fallback_mode) & flag_filter)) + continue; + + drm_mode = meta_kms_mode_get_drm_mode (fallback_mode); + refresh_rate = meta_calculate_drm_mode_refresh_rate (drm_mode); + if (drm_mode->hdisplay > max_hdisplay || + drm_mode->vdisplay > max_vdisplay || + refresh_rate > max_refresh_rate) + continue; + + crtc_mode = meta_gpu_kms_get_mode_from_drm_mode (gpu_kms, drm_mode); + g_ptr_array_add (array, crtc_mode); } output_info->modes = g_renew (MetaCrtcMode *, output_info->modes,