diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index e681cd253..9e2023c06 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -586,16 +586,9 @@ meta_monitor_manager_kms_get_primary_gpu (MetaMonitorManagerKms *manager_kms) return manager_kms->primary_gpu; } -typedef enum -{ - GPU_TYPE_PRIMARY, - GPU_TYPE_SECONDARY -} GpuType; - -static GList * -get_gpu_paths (MetaMonitorManagerKms *manager_kms, - GpuType gpu_type, - const char *filtered_gpu_path) +static gboolean +init_gpus (MetaMonitorManagerKms *manager_kms, + GError **error) { MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms); MetaBackend *backend = meta_monitor_manager_get_backend (manager); @@ -605,7 +598,7 @@ get_gpu_paths (MetaMonitorManagerKms *manager_kms, const char *seat_id; GList *devices; GList *l; - GList *gpu_paths = NULL; + MetaGpuKmsFlag flags = META_GPU_KMS_FLAG_NONE; enumerator = g_udev_enumerator_new (manager_kms->udev); @@ -620,18 +613,24 @@ get_gpu_paths (MetaMonitorManagerKms *manager_kms, devices = g_udev_enumerator_execute (enumerator); if (!devices) - return NULL; + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "No GPUs found with udev"); + return FALSE; + } seat_id = meta_launcher_get_seat_id (launcher); for (l = devices; l; l = l->next) { GUdevDevice *dev = l->data; + MetaGpuKms *gpu_kms; g_autoptr (GUdevDevice) platform_device = NULL; g_autoptr (GUdevDevice) pci_device = NULL; const char *device_path; const char *device_type; const char *device_seat; + GError *local_error = NULL; /* Filter out devices that are not character device, like card0-VGA-1. */ if (g_udev_device_get_device_type (dev) != G_UDEV_DEVICE_TYPE_CHAR) @@ -642,8 +641,6 @@ get_gpu_paths (MetaMonitorManagerKms *manager_kms, continue; device_path = g_udev_device_get_device_file (dev); - if (g_strcmp0 (device_path, filtered_gpu_path) == 0) - continue; device_seat = g_udev_device_get_property (dev, "ID_SEAT"); if (!device_seat) @@ -651,16 +648,6 @@ get_gpu_paths (MetaMonitorManagerKms *manager_kms, /* When ID_SEAT is not set, it means seat0. */ device_seat = "seat0"; } - else if (g_strcmp0 (device_seat, "seat0") != 0 && - gpu_type == GPU_TYPE_PRIMARY) - { - /* - * If the device has been explicitly assigned other seat - * than seat0, it is probably the right device to use. - */ - gpu_paths = g_list_append (gpu_paths, g_strdup (device_path)); - break; - } /* Skip devices that do not belong to our seat. */ if (g_strcmp0 (seat_id, device_seat)) @@ -669,38 +656,71 @@ get_gpu_paths (MetaMonitorManagerKms *manager_kms, platform_device = g_udev_device_get_parent_with_subsystem (dev, "platform", NULL); - if (platform_device != NULL && gpu_type == GPU_TYPE_PRIMARY) - { - gpu_paths = g_list_append (gpu_paths, g_strdup (device_path)); - break; - } + if (platform_device != NULL) + flags |= META_GPU_KMS_FLAG_PLATFORM_DEVICE; pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL); if (pci_device != NULL) { - if (gpu_type == GPU_TYPE_PRIMARY) - { - int boot_vga; - - boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, - "boot_vga"); - if (boot_vga == 1) - { - gpu_paths = g_list_append (gpu_paths, g_strdup (device_path)); - break; - } - } + if (g_udev_device_get_sysfs_attr_as_int (pci_device, + "boot_vga") == 1) + flags |= META_GPU_KMS_FLAG_BOOT_VGA; } - if (gpu_type == GPU_TYPE_SECONDARY) + gpu_kms = meta_gpu_kms_new (manager_kms, device_path, flags, + &local_error); + if (!gpu_kms) { - gpu_paths = g_list_append (gpu_paths, g_strdup (device_path)); + g_warning ("Failed to open gpu '%s': %s", + device_path, local_error->message); + g_clear_error (&local_error); + continue; } + + meta_monitor_manager_add_gpu (manager, META_GPU (gpu_kms)); } g_list_free_full (devices, g_object_unref); - return gpu_paths; + if (!meta_monitor_manager_get_gpus (manager)) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "No GPUs found"); + return FALSE; + } + + return TRUE; +} + +static MetaGpuKms * +choose_primary_gpu (MetaMonitorManagerKms *manager_kms) +{ + MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms); + GList *gpus = meta_monitor_manager_get_gpus (manager); + GList *l; + + g_return_val_if_fail (gpus, NULL); + + /* Prefer a platform device */ + for (l = gpus; l; l = l->next) + { + MetaGpuKms *gpu_kms = META_GPU_KMS (l->data); + + if (meta_gpu_kms_is_platform_device (gpu_kms)) + return gpu_kms; + } + + /* Otherwise a device we booted with */ + for (l = gpus; l; l = l->next) + { + MetaGpuKms *gpu_kms = META_GPU_KMS (l->data); + + if (meta_gpu_kms_is_boot_vga (gpu_kms)) + return gpu_kms; + } + + /* Lastly, just pick the first device */ + return META_GPU_KMS (gpus->data); } static gboolean @@ -711,57 +731,19 @@ meta_monitor_manager_kms_initable_init (GInitable *initable, MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (initable); MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms); const char *subsystems[2] = { "drm", NULL }; - GList *gpu_paths; - g_autofree char *primary_gpu_path = NULL; GList *l; gboolean can_have_outputs; manager_kms->udev = g_udev_client_new (subsystems); - gpu_paths = get_gpu_paths (manager_kms, GPU_TYPE_PRIMARY, NULL); - if (g_list_length (gpu_paths) != 1) + meta_monitor_manager_kms_connect_uevent_handler (manager_kms); + + if (!init_gpus (manager_kms, error)) { - g_list_free_full (gpu_paths, g_free); - g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, - "Could not find a primary drm kms device"); return FALSE; } - primary_gpu_path = g_strdup (gpu_paths->data); - manager_kms->primary_gpu = meta_gpu_kms_new (manager_kms, - primary_gpu_path, - META_GPU_KMS_FLAG_NONE, - error); - g_list_free_full (gpu_paths, g_free); - if (!manager_kms->primary_gpu) - return FALSE; - - meta_monitor_manager_kms_connect_uevent_handler (manager_kms); - - meta_monitor_manager_add_gpu (META_MONITOR_MANAGER (manager_kms), - META_GPU (manager_kms->primary_gpu)); - - gpu_paths = get_gpu_paths (manager_kms, GPU_TYPE_SECONDARY, primary_gpu_path); - for (l = gpu_paths; l; l = l->next) - { - g_autoptr (GError) secondary_error = NULL; - char *gpu_path = l->data; - MetaGpuKms *gpu_kms; - - gpu_kms = meta_gpu_kms_new (manager_kms, gpu_path, - META_GPU_KMS_FLAG_NONE, - &secondary_error); - if (!gpu_kms) - { - g_warning ("Failed to open secondary gpu '%s': %s", - gpu_path, secondary_error->message); - continue; - } - - meta_monitor_manager_add_gpu (META_MONITOR_MANAGER (manager_kms), - META_GPU (gpu_kms)); - } - g_list_free_full (gpu_paths, g_free); + manager_kms->primary_gpu = choose_primary_gpu (manager_kms); can_have_outputs = FALSE; for (l = meta_monitor_manager_get_gpus (manager); l; l = l->next)