[mutter] backends/native: Re-order primary GPU choosing logic



commit 1def09904763fa36d3b388924ee5c9cb6702ba8c
Author: Emilio Pozuelo Monfort <emilio pozuelo collabora co uk>
Date:   Fri Sep 21 14:37:03 2018 +0200

    backends/native: Re-order primary GPU choosing logic
    
    This is a step towards moving the primary GPU logic into the native
    renderer exclusively. In the future the renderer will have one more
    criterion on choosing the primary GPU than MetaMonitorManagerKms should
    know about: does a GPU offer hardware rendering.
    
    The choosing of primary GPU is separated from the discovery of GPUs.
    When GPUs are discovered and added to the list, the MetaGpuKmsFlag is
    now populated correctly and used in choosing.
    
    Choosing the primary GPU is done after all GPUs have been found and is
    slightly different from before:
    
    - Skipping devices that do not belong to our seat now works instead of
    becoming the primary GPU.
    
    - Fall back to any non-platform, non-boot_vga device if neither kind is
    found.
    
    The old preference of platform over boot_vga device is kept.
    
    The hotplug path will continue creating a gpu_kms without flags, because
    at that point the primary GPU has already been chosen and the flags are
    irrelevant.
    
    Co-authored by: Pekka Paalanen <pekka paalanen collabora com>
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/271

 src/backends/native/meta-monitor-manager-kms.c | 154 +++++++++++--------------
 1 file changed, 68 insertions(+), 86 deletions(-)
---
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)
-    {
-      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)
+  if (!init_gpus (manager_kms, error))
     {
-      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));
+      return FALSE;
     }
-  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)


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]