[mutter] monitor-manager-kms: Add all GPUs with connectors
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] monitor-manager-kms: Add all GPUs with connectors
- Date: Fri, 6 Oct 2017 18:25:36 +0000 (UTC)
commit cbcf6a4f2311b1cd06c9f31d77c7899aeae9157b
Author: Jonas Ådahl <jadahl gmail com>
Date: Mon Jul 24 17:07:09 2017 +0800
monitor-manager-kms: Add all GPUs with connectors
First find the primary GPU and open it. Then go through all other
discovered GPUs with connectors and add those too. MetaRendererNative
still fails to initialize when multiple added GPUs and
MetaCursorRendererNative still always falls back on OpenGL based cursor
rendering when there are multiple GPUs.
https://bugzilla.gnome.org/show_bug.cgi?id=785381
src/backends/native/meta-monitor-manager-kms.c | 151 ++++++++++--------------
1 files changed, 65 insertions(+), 86 deletions(-)
---
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 1f20106..2a14308 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -520,59 +520,16 @@ meta_monitor_manager_kms_get_primary_gpu (MetaMonitorManagerKms *manager_kms)
return manager_kms->primary_gpu;
}
-static guint
-count_devices_with_connectors (const char *seat_id,
- GList *devices)
+typedef enum
{
- g_autoptr (GHashTable) cards = NULL;
- GList *l;
-
- cards = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref);
- for (l = devices; l != NULL; l = l->next)
- {
- GUdevDevice *device = l->data;
- g_autoptr (GUdevDevice) parent_device = NULL;
- const gchar *parent_device_type = NULL;
- const gchar *parent_device_name = NULL;
- const gchar *card_seat;
-
- /* Filter out the real card devices, we only care about the connectors. */
- if (g_udev_device_get_device_type (device) != G_UDEV_DEVICE_TYPE_NONE)
- continue;
-
- /* Only connectors have a modes attribute. */
- if (!g_udev_device_has_sysfs_attr (device, "modes"))
- continue;
-
- parent_device = g_udev_device_get_parent (device);
-
- if (g_udev_device_get_device_type (parent_device) ==
- G_UDEV_DEVICE_TYPE_CHAR)
- parent_device_type = g_udev_device_get_property (parent_device,
- "DEVTYPE");
-
- if (g_strcmp0 (parent_device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
- continue;
-
- card_seat = g_udev_device_get_property (parent_device, "ID_SEAT");
-
- if (!card_seat)
- card_seat = "seat0";
-
- if (g_strcmp0 (seat_id, card_seat) != 0)
- continue;
-
- parent_device_name = g_udev_device_get_name (parent_device);
- g_hash_table_insert (cards,
- (gpointer) parent_device_name ,
- g_steal_pointer (&parent_device));
- }
-
- return g_hash_table_size (cards);
-}
-
-static char *
-get_primary_gpu_path (MetaMonitorManagerKms *manager_kms)
+ GPU_TYPE_PRIMARY,
+ GPU_TYPE_SECONDARY
+} GpuType;
+
+static GList *
+get_gpu_paths (MetaMonitorManagerKms *manager_kms,
+ GpuType gpu_type,
+ const char *filtered_gpu_path)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
MetaBackend *backend = meta_monitor_manager_get_backend (manager);
@@ -580,9 +537,9 @@ get_primary_gpu_path (MetaMonitorManagerKms *manager_kms)
MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
g_autoptr (GUdevEnumerator) enumerator = NULL;
const char *seat_id;
- char *path = NULL;
GList *devices;
GList *l;
+ GList *gpu_paths = NULL;
enumerator = g_udev_enumerator_new (manager_kms->udev);
@@ -597,30 +554,16 @@ get_primary_gpu_path (MetaMonitorManagerKms *manager_kms)
devices = g_udev_enumerator_execute (enumerator);
if (!devices)
- goto out;
+ return NULL;
seat_id = meta_launcher_get_seat_id (launcher);
- /*
- * For now, fail on systems where some of the connectors are connected to
- * secondary gpus.
- *
- * https://bugzilla.gnome.org/show_bug.cgi?id=771442
- */
- if (g_getenv ("MUTTER_ALLOW_HYBRID_GPUS") == NULL)
- {
- unsigned int num_devices;
-
- num_devices = count_devices_with_connectors (seat_id, devices);
- if (num_devices != 1)
- goto out;
- }
-
for (l = devices; l; l = l->next)
{
GUdevDevice *dev = l->data;
g_autoptr (GUdevDevice) platform_device = NULL;
g_autoptr (GUdevDevice) pci_device = NULL;
+ const char *device_path;
const char *device_type;
const char *device_seat;
@@ -632,19 +575,24 @@ get_primary_gpu_path (MetaMonitorManagerKms *manager_kms)
if (g_strcmp0 (device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
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)
{
/* When ID_SEAT is not set, it means seat0. */
device_seat = "seat0";
}
- else if (g_strcmp0 (device_seat, "seat0") != 0)
+ 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.
*/
- path = g_strdup (g_udev_device_get_device_file (dev));
+ gpu_paths = g_list_append (gpu_paths, g_strdup (device_path));
break;
}
@@ -655,31 +603,37 @@ get_primary_gpu_path (MetaMonitorManagerKms *manager_kms)
platform_device = g_udev_device_get_parent_with_subsystem (dev,
"platform",
NULL);
- if (platform_device != NULL)
+ if (platform_device != NULL && gpu_type == GPU_TYPE_PRIMARY)
{
- path = g_strdup (g_udev_device_get_device_file (dev));
+ gpu_paths = g_list_append (gpu_paths, g_strdup (device_path));
break;
}
pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL);
if (pci_device != NULL)
{
- int boot_vga;
-
- boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device,
- "boot_vga");
- if (boot_vga == 1)
+ if (gpu_type == GPU_TYPE_PRIMARY)
{
- path = g_strdup (g_udev_device_get_device_file (dev));
- break;
+ 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;
+ }
+ }
+ else
+ {
+ gpu_paths = g_list_append (gpu_paths, g_strdup (device_path));
}
}
}
-out:
g_list_free_full (devices, g_object_unref);
- return path;
+ return gpu_paths;
}
static gboolean
@@ -689,21 +643,26 @@ meta_monitor_manager_kms_initable_init (GInitable *initable,
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (initable);
const char *subsystems[2] = { "drm", NULL };
- g_autofree char *primary_gpu_path;
+ GList *gpu_paths;
+ g_autofree char *primary_gpu_path = NULL;
+ GList *l;
manager_kms->udev = g_udev_client_new (subsystems);
- primary_gpu_path = get_primary_gpu_path (manager_kms);
- if (!primary_gpu_path)
+ gpu_paths = get_gpu_paths (manager_kms, GPU_TYPE_PRIMARY, NULL);
+ if (g_list_length (gpu_paths) != 1)
{
+ g_list_free_full (gpu_paths, g_free);
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
- "Could not find drm kms device");
+ "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,
error);
+ g_list_free_full (gpu_paths, g_free);
if (!manager_kms->primary_gpu)
return FALSE;
@@ -712,6 +671,26 @@ meta_monitor_manager_kms_initable_init (GInitable *initable,
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)
+ {
+ GError *secondary_error = NULL;
+ char *gpu_path = l->data;
+ MetaGpuKms *gpu_kms;
+
+ gpu_kms = meta_gpu_kms_new (manager_kms, gpu_path, &secondary_error);
+ if (!gpu_kms)
+ {
+ g_warning ("Failed to open secondary gpu '%s': %s",
+ gpu_path, secondary_error->message);
+ g_error_free (secondary_error);
+ }
+
+ meta_monitor_manager_add_gpu (META_MONITOR_MANAGER (manager_kms),
+ META_GPU (gpu_kms));
+ }
+ g_list_free_full (gpu_paths, g_free);
+
return TRUE;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]