[mutter/wip/gbsneto/kms-transactions-on-steroids: 7/30] backend: Move GPU ownership from the monitor manager to the backend



commit a56a6a43aa22c88fed5bcebe080afaf5721634dd
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Jan 11 15:35:42 2019 +0100

    backend: Move GPU ownership from the monitor manager to the backend
    
    Lets work towards making MetaMonitorManager about managing monitors, and
    not about managing GPUs. This changes other units to keep a pointer to
    the backend instead of a monitor manager, in case their ownership
    changed, or their main usage of the monitor manager was to look up GPUs.
    
    https://gitlab.gnome.org/GNOME/mutter/issues/548
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/525

 src/backends/meta-backend-private.h               |   7 +
 src/backends/meta-backend.c                       |  36 +++
 src/backends/meta-gpu.c                           |  29 +--
 src/backends/meta-gpu.h                           |   2 +-
 src/backends/meta-monitor-manager-dummy.c         |  62 +++---
 src/backends/meta-monitor-manager-private.h       |   9 +-
 src/backends/meta-monitor-manager.c               |  37 +---
 src/backends/meta-monitor.c                       |  20 +-
 src/backends/meta-monitor.h                       |   5 +-
 src/backends/meta-screen-cast-monitor-stream.c    |   4 +-
 src/backends/native/meta-backend-native.c         | 144 +++++++++++-
 src/backends/native/meta-cursor-renderer-native.c |  22 +-
 src/backends/native/meta-gpu-kms.c                |  29 ++-
 src/backends/native/meta-gpu-kms.h                |  10 +-
 src/backends/native/meta-monitor-manager-kms.c    | 253 +---------------------
 src/backends/native/meta-renderer-native.c        | 119 ++++------
 src/backends/native/meta-renderer-native.h        |   4 +-
 src/backends/native/meta-udev.c                   |   8 +-
 src/backends/native/meta-udev.h                   |   5 +-
 src/backends/x11/cm/meta-backend-x11-cm.c         |  11 +
 src/backends/x11/meta-crtc-xrandr.c               |   5 +-
 src/backends/x11/meta-gpu-xrandr.c                |  10 +-
 src/backends/x11/meta-gpu-xrandr.h                |   4 +-
 src/backends/x11/meta-monitor-manager-xrandr.c    |  42 ++--
 src/backends/x11/meta-output-xrandr.c             |   9 +-
 src/backends/x11/nested/meta-backend-x11-nested.c |  40 +++-
 src/backends/x11/nested/meta-backend-x11-nested.h |   2 +
 src/tests/headless-start-test.c                   |   2 +-
 src/tests/meson.build                             |   4 +
 src/tests/meta-backend-test.c                     |  24 ++
 src/tests/meta-backend-test.h                     |   2 +
 src/tests/meta-gpu-test.c                         |  55 +++++
 src/tests/meta-gpu-test.h                         |  26 +++
 src/tests/meta-monitor-manager-test.c             |  72 ++----
 src/tests/meta-monitor-manager-test.h             |   6 +-
 src/tests/monitor-unit-tests.c                    |  27 +--
 36 files changed, 587 insertions(+), 559 deletions(-)
---
diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h
index 7eba1806b..397c5f382 100644
--- a/src/backends/meta-backend-private.h
+++ b/src/backends/meta-backend-private.h
@@ -181,4 +181,11 @@ void meta_backend_notify_keymap_layout_group_changed (MetaBackend *backend,
 
 void meta_backend_notify_ui_scaling_factor_changed (MetaBackend *backend);
 
+META_EXPORT_TEST
+void meta_backend_add_gpu (MetaBackend *backend,
+                           MetaGpu     *gpu);
+
+META_EXPORT_TEST
+GList * meta_backend_get_gpus (MetaBackend *backend);
+
 #endif /* META_BACKEND_PRIVATE_H */
diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c
index 3864e34a4..a199f1af4 100644
--- a/src/backends/meta-backend.c
+++ b/src/backends/meta-backend.c
@@ -89,6 +89,7 @@ enum
   KEYMAP_LAYOUT_GROUP_CHANGED,
   LAST_DEVICE_CHANGED,
   LID_IS_CLOSED_CHANGED,
+  GPU_ADDED,
 
   N_SIGNALS
 };
@@ -138,6 +139,8 @@ struct _MetaBackendPrivate
   ClutterBackend *clutter_backend;
   ClutterActor *stage;
 
+  GList *gpus;
+
   gboolean is_pointer_position_initialized;
 
   guint device_update_idle_id;
@@ -175,6 +178,8 @@ meta_backend_finalize (GObject *object)
   MetaBackend *backend = META_BACKEND (object);
   MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
 
+  g_list_free_full (priv->gpus, g_object_unref);
+
   g_clear_object (&priv->monitor_manager);
   g_clear_object (&priv->orientation_manager);
   g_clear_object (&priv->input_settings);
@@ -752,6 +757,18 @@ meta_backend_class_init (MetaBackendClass *klass)
                   0,
                   NULL, NULL, NULL,
                   G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+  /**
+   * MetaBackend::gpu-added: (skip)
+   * @backend: the #MetaBackend
+   * @gpu: the #MetaGpu
+   */
+  signals[GPU_ADDED] =
+    g_signal_new ("gpu-added",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 1, META_TYPE_GPU);
 
   mutter_stage_views = g_getenv ("MUTTER_STAGE_VIEWS");
   stage_views_disabled = g_strcmp0 (mutter_stage_views, "0") == 0;
@@ -1399,3 +1416,22 @@ meta_backend_notify_keymap_layout_group_changed (MetaBackend *backend,
   g_signal_emit (backend, signals[KEYMAP_LAYOUT_GROUP_CHANGED], 0,
                  locked_group);
 }
+
+void
+meta_backend_add_gpu (MetaBackend *backend,
+                      MetaGpu     *gpu)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+  priv->gpus = g_list_append (priv->gpus, gpu);
+
+  g_signal_emit (backend, signals[GPU_ADDED], 0, gpu);
+}
+
+GList *
+meta_backend_get_gpus (MetaBackend *backend)
+{
+  MetaBackendPrivate *priv = meta_backend_get_instance_private (backend);
+
+  return priv->gpus;
+}
diff --git a/src/backends/meta-gpu.c b/src/backends/meta-gpu.c
index 3577391e5..cc67fa718 100644
--- a/src/backends/meta-gpu.c
+++ b/src/backends/meta-gpu.c
@@ -23,13 +23,14 @@
 
 #include "backends/meta-gpu.h"
 
+#include "backends/meta-backend-private.h"
 #include "backends/meta-output.h"
 
 enum
 {
   PROP_0,
 
-  PROP_MONITOR_MANAGER,
+  PROP_BACKEND,
 
   PROP_LAST
 };
@@ -38,7 +39,7 @@ static GParamSpec *obj_props[PROP_LAST];
 
 typedef struct _MetaGpuPrivate
 {
-  MetaMonitorManager *monitor_manager;
+  MetaBackend *backend;
 
   GList *outputs;
   GList *crtcs;
@@ -88,12 +89,12 @@ meta_gpu_read_current (MetaGpu  *gpu,
   return ret;
 }
 
-MetaMonitorManager *
-meta_gpu_get_monitor_manager (MetaGpu *gpu)
+MetaBackend *
+meta_gpu_get_backend (MetaGpu *gpu)
 {
   MetaGpuPrivate *priv = meta_gpu_get_instance_private (gpu);
 
-  return priv->monitor_manager;
+  return priv->backend;
 }
 
 GList *
@@ -158,8 +159,8 @@ meta_gpu_set_property (GObject      *object,
 
   switch (prop_id)
     {
-    case PROP_MONITOR_MANAGER:
-      priv->monitor_manager = g_value_get_object (value);
+    case PROP_BACKEND:
+      priv->backend = g_value_get_object (value);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -177,8 +178,8 @@ meta_gpu_get_property (GObject    *object,
 
   switch (prop_id)
     {
-    case PROP_MONITOR_MANAGER:
-      g_value_set_object (value, priv->monitor_manager);
+    case PROP_BACKEND:
+      g_value_set_object (value, priv->backend);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -212,11 +213,11 @@ meta_gpu_class_init (MetaGpuClass *klass)
   object_class->get_property = meta_gpu_get_property;
   object_class->finalize = meta_gpu_finalize;
 
-  obj_props[PROP_MONITOR_MANAGER] =
-    g_param_spec_object ("monitor-manager",
-                         "monitor-manager",
-                         "MetaMonitorManager",
-                         META_TYPE_MONITOR_MANAGER,
+  obj_props[PROP_BACKEND] =
+    g_param_spec_object ("backend",
+                         "backend",
+                         "MetaBackend",
+                         META_TYPE_BACKEND,
                          G_PARAM_READWRITE |
                          G_PARAM_CONSTRUCT_ONLY |
                          G_PARAM_STATIC_STRINGS);
diff --git a/src/backends/meta-gpu.h b/src/backends/meta-gpu.h
index 701acdc97..9d12f95a7 100644
--- a/src/backends/meta-gpu.h
+++ b/src/backends/meta-gpu.h
@@ -46,7 +46,7 @@ META_EXPORT_TEST
 gboolean meta_gpu_has_hotplug_mode_update (MetaGpu *gpu);
 
 META_EXPORT_TEST
-MetaMonitorManager * meta_gpu_get_monitor_manager (MetaGpu *gpu);
+MetaBackend * meta_gpu_get_backend (MetaGpu *gpu);
 
 META_EXPORT_TEST
 GList * meta_gpu_get_outputs (MetaGpu *gpu);
diff --git a/src/backends/meta-monitor-manager-dummy.c b/src/backends/meta-monitor-manager-dummy.c
index 46c3b8c17..5dc7cd3e5 100644
--- a/src/backends/meta-monitor-manager-dummy.c
+++ b/src/backends/meta-monitor-manager-dummy.c
@@ -47,8 +47,6 @@ struct _MetaMonitorManagerDummy
 {
   MetaMonitorManager parent_instance;
 
-  MetaGpu *gpu;
-
   gboolean is_transform_handled;
 };
 
@@ -98,6 +96,14 @@ create_mode (CrtcModeSpec *spec,
   return mode;
 }
 
+static MetaGpu *
+get_gpu (MetaMonitorManager *manager)
+{
+  MetaBackend *backend = meta_monitor_manager_get_backend (manager);
+
+  return META_GPU (meta_backend_get_gpus (backend)->data);
+}
+
 static void
 append_monitor (MetaMonitorManager *manager,
                 GList             **modes,
@@ -105,8 +111,7 @@ append_monitor (MetaMonitorManager *manager,
                 GList             **outputs,
                 float               scale)
 {
-  MetaMonitorManagerDummy *manager_dummy = META_MONITOR_MANAGER_DUMMY (manager);
-  MetaGpu *gpu = manager_dummy->gpu;
+  MetaGpu *gpu = get_gpu (manager);
   CrtcModeSpec default_specs[] = {
     {
       .width = 800,
@@ -246,8 +251,7 @@ append_tiled_monitor (MetaMonitorManager *manager,
                       GList             **outputs,
                       int                 scale)
 {
-  MetaMonitorManagerDummy *manager_dummy = META_MONITOR_MANAGER_DUMMY (manager);
-  MetaGpu *gpu = manager_dummy->gpu;
+  MetaGpu *gpu = get_gpu (manager);
   CrtcModeSpec mode_specs[] = {
     {
       .width = 800,
@@ -371,8 +375,7 @@ meta_output_dummy_notify_destroy (MetaOutput *output)
 static void
 meta_monitor_manager_dummy_read_current (MetaMonitorManager *manager)
 {
-  MetaMonitorManagerDummy *manager_dummy = META_MONITOR_MANAGER_DUMMY (manager);
-  MetaGpu *gpu = manager_dummy->gpu;
+  MetaGpu *gpu = get_gpu (manager);
   unsigned int num_monitors = 1;
   float *monitor_scales = NULL;
   const char *num_monitors_str;
@@ -495,7 +498,6 @@ apply_crtc_assignments (MetaMonitorManager *manager,
                         MetaOutputInfo    **outputs,
                         unsigned int        n_outputs)
 {
-  MetaMonitorManagerDummy *manager_dummy = META_MONITOR_MANAGER_DUMMY (manager);
   GList *l;
   unsigned i;
 
@@ -560,7 +562,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
     }
 
   /* Disable CRTCs not mentioned in the list */
-  for (l = meta_gpu_get_crtcs (manager_dummy->gpu); l; l = l->next)
+  for (l = meta_gpu_get_crtcs (get_gpu (manager)); l; l = l->next)
     {
       MetaCrtc *crtc = l->data;
 
@@ -580,7 +582,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
     }
 
   /* Disable outputs not mentioned in the list */
-  for (l = meta_gpu_get_outputs (manager_dummy->gpu); l; l = l->next)
+  for (l = meta_gpu_get_outputs (get_gpu (manager)); l; l = l->next)
     {
       MetaOutput *output = l->data;
 
@@ -772,11 +774,32 @@ meta_monitor_manager_dummy_get_default_layout_mode (MetaMonitorManager *manager)
     return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
 }
 
+static void
+meta_monitor_manager_dummy_constructed (GObject *object)
+{
+  MetaMonitorManagerDummy *manager_dummy = META_MONITOR_MANAGER_DUMMY (object);
+  const char *nested_offscreen_transform;
+  GObjectClass *parent_object_class =
+    G_OBJECT_CLASS (meta_monitor_manager_dummy_parent_class);
+
+  parent_object_class->constructed (object);
+
+  nested_offscreen_transform =
+    g_getenv ("MUTTER_DEBUG_NESTED_OFFSCREEN_TRANSFORM");
+  if (g_strcmp0 (nested_offscreen_transform, "1") == 0)
+    manager_dummy->is_transform_handled = FALSE;
+  else
+    manager_dummy->is_transform_handled = TRUE;
+}
+
 static void
 meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
   MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass);
 
+  object_class->constructed = meta_monitor_manager_dummy_constructed;
+
   manager_class->ensure_initial_config = meta_monitor_manager_dummy_ensure_initial_config;
   manager_class->apply_monitors_config = meta_monitor_manager_dummy_apply_monitors_config;
   manager_class->is_transform_handled = meta_monitor_manager_dummy_is_transform_handled;
@@ -790,27 +813,14 @@ meta_monitor_manager_dummy_class_init (MetaMonitorManagerDummyClass *klass)
 static void
 meta_monitor_manager_dummy_init (MetaMonitorManagerDummy *manager_dummy)
 {
-  MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_dummy);
-  const char *nested_offscreen_transform;
-
-  nested_offscreen_transform =
-    g_getenv ("MUTTER_DEBUG_NESTED_OFFSCREEN_TRANSFORM");
-  if (g_strcmp0 (nested_offscreen_transform, "1") == 0)
-    manager_dummy->is_transform_handled = FALSE;
-  else
-    manager_dummy->is_transform_handled = TRUE;
-
-  manager_dummy->gpu = g_object_new (META_TYPE_GPU_DUMMY,
-                                     "monitor-manager", manager,
-                                     NULL);
-  meta_monitor_manager_add_gpu (manager, manager_dummy->gpu);
 }
 
 static gboolean
 meta_gpu_dummy_read_current (MetaGpu  *gpu,
                              GError  **error)
 {
-  MetaMonitorManager *manager = meta_gpu_get_monitor_manager (gpu);
+  MetaBackend *backend = meta_gpu_get_backend (gpu);
+  MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend);
 
   meta_monitor_manager_dummy_read_current (manager);
 
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index cdb8f4209..f34c01ae1 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -121,8 +121,6 @@ struct _MetaMonitorManager
   int screen_width;
   int screen_height;
 
-  GList *gpus;
-
   GList *monitors;
 
   GList *logical_monitors;
@@ -248,6 +246,7 @@ struct _MetaMonitorManagerClass
   MetaLogicalMonitorLayoutMode (*get_default_layout_mode) (MetaMonitorManager *);
 };
 
+META_EXPORT_TEST
 MetaBackend *       meta_monitor_manager_get_backend (MetaMonitorManager *manager);
 
 void                meta_monitor_manager_setup (MetaMonitorManager *manager);
@@ -295,12 +294,6 @@ MetaMonitor *       meta_monitor_manager_get_monitor_from_connector (MetaMonitor
 META_EXPORT_TEST
 GList *             meta_monitor_manager_get_monitors      (MetaMonitorManager *manager);
 
-META_EXPORT_TEST
-void                meta_monitor_manager_add_gpu (MetaMonitorManager *manager,
-                                                  MetaGpu            *gpu);
-META_EXPORT_TEST
-GList *             meta_monitor_manager_get_gpus (MetaMonitorManager *manager);
-
 void                meta_monitor_manager_get_screen_size   (MetaMonitorManager *manager,
                                                             int                *width,
                                                             int                *height);
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 2d898c757..35ae2c736 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -511,9 +511,11 @@ meta_monitor_manager_apply_monitors_config (MetaMonitorManager      *manager,
 gboolean
 meta_monitor_manager_has_hotplug_mode_update (MetaMonitorManager *manager)
 {
+  GList *gpus;
   GList *l;
 
-  for (l = manager->gpus; l; l = l->next)
+  gpus = meta_backend_get_gpus (manager->backend);
+  for (l = gpus; l; l = l->next)
     {
       MetaGpu *gpu = l->data;
 
@@ -794,7 +796,6 @@ meta_monitor_manager_finalize (GObject *object)
 {
   MetaMonitorManager *manager = META_MONITOR_MANAGER (object);
 
-  g_list_free_full (manager->gpus, g_object_unref);
   g_list_free_full (manager->logical_monitors, g_object_unref);
 
   g_signal_handler_disconnect (manager->backend,
@@ -1063,10 +1064,12 @@ static GList *
 combine_gpu_lists (MetaMonitorManager    *manager,
                    GList              * (*list_getter) (MetaGpu *gpu))
 {
+  GList *gpus;
   GList *list = NULL;
   GList *l;
 
-  for (l = manager->gpus; l; l = l->next)
+  gpus = meta_backend_get_gpus (manager->backend);
+  for (l = gpus; l; l = l->next)
     {
       MetaGpu *gpu = l->data;
 
@@ -2676,26 +2679,6 @@ meta_monitor_manager_get_monitors (MetaMonitorManager *manager)
   return manager->monitors;
 }
 
-/**
- * meta_monitor_manager_add_gpu:
- * @manager: A #MetaMonitorManager object
- *
- * Should only be called by subclasses. Adds a #MetaGpu to the internal list of
- * GPU's.
- */
-void
-meta_monitor_manager_add_gpu (MetaMonitorManager *manager,
-                              MetaGpu            *gpu)
-{
-  manager->gpus = g_list_append (manager->gpus, gpu);
-}
-
-GList *
-meta_monitor_manager_get_gpus (MetaMonitorManager *manager)
-{
-  return manager->gpus;
-}
-
 void
 meta_monitor_manager_get_screen_size (MetaMonitorManager *manager,
                                       int                *width,
@@ -2717,6 +2700,7 @@ meta_monitor_manager_get_power_save_mode (MetaMonitorManager *manager)
 static void
 rebuild_monitors (MetaMonitorManager *manager)
 {
+  GList *gpus;
   GList *l;
 
   if (manager->monitors)
@@ -2725,7 +2709,8 @@ rebuild_monitors (MetaMonitorManager *manager)
       manager->monitors = NULL;
     }
 
-  for (l = manager->gpus; l; l = l->next)
+  gpus = meta_backend_get_gpus (manager->backend);
+  for (l = gpus; l; l = l->next)
     {
       MetaGpu *gpu = l->data;
       GList *k;
@@ -2740,7 +2725,7 @@ rebuild_monitors (MetaMonitorManager *manager)
                 {
                   MetaMonitorTiled *monitor_tiled;
 
-                  monitor_tiled = meta_monitor_tiled_new (gpu, output);
+                  monitor_tiled = meta_monitor_tiled_new (gpu, manager, output);
                   manager->monitors = g_list_append (manager->monitors,
                                                      monitor_tiled);
                 }
@@ -2797,7 +2782,7 @@ meta_monitor_manager_real_read_current_state (MetaMonitorManager *manager)
 
   manager->serial++;
 
-  for (l = manager->gpus; l; l = l->next)
+  for (l = meta_backend_get_gpus (manager->backend); l; l = l->next)
     {
       MetaGpu *gpu = l->data;
       GError *error = NULL;
diff --git a/src/backends/meta-monitor.c b/src/backends/meta-monitor.c
index 5f6c45543..dae40e277 100644
--- a/src/backends/meta-monitor.c
+++ b/src/backends/meta-monitor.c
@@ -90,6 +90,8 @@ struct _MetaMonitorTiled
 {
   MetaMonitor parent;
 
+  MetaMonitorManager *monitor_manager;
+
   uint32_t tile_group_id;
 
   /* The tile (0, 0) output. */
@@ -1176,10 +1178,10 @@ meta_monitor_tiled_generate_modes (MetaMonitorTiled *monitor_tiled)
 }
 
 MetaMonitorTiled *
-meta_monitor_tiled_new (MetaGpu    *gpu,
-                        MetaOutput *output)
+meta_monitor_tiled_new (MetaGpu            *gpu,
+                        MetaMonitorManager *monitor_manager,
+                        MetaOutput         *output)
 {
-  MetaMonitorManager *monitor_manager;
   MetaMonitorTiled *monitor_tiled;
   MetaMonitor *monitor;
   MetaMonitorPrivate *monitor_priv;
@@ -1200,7 +1202,7 @@ meta_monitor_tiled_new (MetaGpu    *gpu,
 
   meta_monitor_generate_spec (monitor);
 
-  monitor_manager = meta_gpu_get_monitor_manager (gpu);
+  monitor_tiled->monitor_manager = monitor_manager;
   meta_monitor_manager_tiled_monitor_added (monitor_manager,
                                             META_MONITOR (monitor_tiled));
 
@@ -1286,14 +1288,10 @@ meta_monitor_tiled_calculate_crtc_pos (MetaMonitor          *monitor,
 static void
 meta_monitor_tiled_finalize (GObject *object)
 {
-  MetaMonitor *monitor = META_MONITOR (object);
-  MetaMonitorPrivate *monitor_priv =
-    meta_monitor_get_instance_private (monitor);
-  MetaMonitorManager *monitor_manager;
+  MetaMonitorTiled *monitor_tiled = META_MONITOR_TILED (object);
 
-  monitor_manager = meta_gpu_get_monitor_manager (monitor_priv->gpu);
-  meta_monitor_manager_tiled_monitor_removed (monitor_manager,
-                                              monitor);
+  meta_monitor_manager_tiled_monitor_removed (monitor_tiled->monitor_manager,
+                                              META_MONITOR (monitor_tiled));
 
   G_OBJECT_CLASS (meta_monitor_tiled_parent_class)->finalize (object);
 }
diff --git a/src/backends/meta-monitor.h b/src/backends/meta-monitor.h
index 413a4e23a..0ea93c056 100644
--- a/src/backends/meta-monitor.h
+++ b/src/backends/meta-monitor.h
@@ -96,8 +96,9 @@ G_DECLARE_FINAL_TYPE (MetaMonitorTiled, meta_monitor_tiled,
                       MetaMonitor)
 
 META_EXPORT_TEST
-MetaMonitorTiled * meta_monitor_tiled_new (MetaGpu    *gpu,
-                                           MetaOutput *output);
+MetaMonitorTiled * meta_monitor_tiled_new (MetaGpu            *gpu,
+                                           MetaMonitorManager *monitor_manager,
+                                           MetaOutput         *output);
 
 META_EXPORT_TEST
 MetaMonitorNormal * meta_monitor_normal_new (MetaGpu    *gpu,
diff --git a/src/backends/meta-screen-cast-monitor-stream.c b/src/backends/meta-screen-cast-monitor-stream.c
index 33b9f026a..4de430a25 100644
--- a/src/backends/meta-screen-cast-monitor-stream.c
+++ b/src/backends/meta-screen-cast-monitor-stream.c
@@ -113,7 +113,9 @@ meta_screen_cast_monitor_stream_new (MetaScreenCastSession     *session,
                                      GError                   **error)
 {
   MetaGpu *gpu = meta_monitor_get_gpu (monitor);
-  MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu);
+  MetaBackend *backend = meta_gpu_get_backend (gpu);
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
   MetaScreenCastMonitorStream *monitor_stream;
 
   if (!meta_monitor_is_active (monitor))
diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c
index 7bf8d6243..262ab9a0a 100644
--- a/src/backends/native/meta-backend-native.c
+++ b/src/backends/native/meta-backend-native.c
@@ -66,6 +66,8 @@ struct _MetaBackendNative
   MetaLauncher *launcher;
   MetaUdev *udev;
   MetaBarrierManagerNative *barrier_manager;
+
+  guint udev_device_added_handler_id;
 };
 
 static GInitableIface *initable_parent_iface;
@@ -77,11 +79,17 @@ G_DEFINE_TYPE_WITH_CODE (MetaBackendNative, meta_backend_native, META_TYPE_BACKE
                          G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
                                                 initable_iface_init))
 
+static void
+disconnect_udev_device_added_handler (MetaBackendNative *native);
+
 static void
 meta_backend_native_finalize (GObject *object)
 {
   MetaBackendNative *native = META_BACKEND_NATIVE (object);
 
+  if (native->udev_device_added_handler_id)
+    disconnect_udev_device_added_handler (native);
+
   g_clear_object (&native->udev);
   meta_launcher_free (native->launcher);
 
@@ -370,13 +378,10 @@ static MetaRenderer *
 meta_backend_native_create_renderer (MetaBackend *backend,
                                      GError     **error)
 {
-  MetaMonitorManager *monitor_manager =
-    meta_backend_get_monitor_manager (backend);
-  MetaMonitorManagerKms *monitor_manager_kms =
-    META_MONITOR_MANAGER_KMS (monitor_manager);
+  MetaBackendNative *native = META_BACKEND_NATIVE (backend);
   MetaRendererNative *renderer_native;
 
-  renderer_native = meta_renderer_native_new (monitor_manager_kms, error);
+  renderer_native = meta_renderer_native_new (native, error);
   if (!renderer_native)
     return NULL;
 
@@ -513,6 +518,128 @@ meta_backend_native_update_screen_size (MetaBackend *backend,
   clutter_actor_set_size (stage, width, height);
 }
 
+static MetaGpuKms *
+create_gpu_from_udev_device (MetaBackendNative  *native,
+                             GUdevDevice        *device,
+                             GError            **error)
+{
+  MetaGpuKmsFlag flags = META_GPU_KMS_FLAG_NONE;
+  const char *device_path;
+
+  if (meta_is_udev_device_platform_device (device))
+    flags |= META_GPU_KMS_FLAG_PLATFORM_DEVICE;
+
+  if (meta_is_udev_device_boot_vga (device))
+    flags |= META_GPU_KMS_FLAG_BOOT_VGA;
+
+  device_path = g_udev_device_get_device_file (device);
+  return meta_gpu_kms_new (native, device_path, flags, error);
+}
+
+static void
+on_udev_device_added (MetaUdev          *udev,
+                      GUdevDevice       *device,
+                      MetaBackendNative *native)
+{
+  MetaBackend *backend = META_BACKEND (native);
+  g_autoptr (GError) error = NULL;
+  const char *device_path;
+  MetaGpuKms *new_gpu_kms;
+  GList *gpus, *l;
+
+  if (!meta_udev_is_drm_device (udev, device))
+    return;
+
+  device_path = g_udev_device_get_device_file (device);
+
+  gpus = meta_backend_get_gpus (backend);;
+  for (l = gpus; l; l = l->next)
+    {
+      MetaGpuKms *gpu_kms = l->data;
+
+      if (!g_strcmp0 (device_path, meta_gpu_kms_get_file_path (gpu_kms)))
+        {
+          g_warning ("Failed to hotplug secondary gpu '%s': %s",
+                     device_path, "device already present");
+          return;
+        }
+    }
+
+  new_gpu_kms = create_gpu_from_udev_device (native, device, &error);
+  if (!new_gpu_kms)
+    {
+      g_warning ("Failed to hotplug secondary gpu '%s': %s",
+                 device_path, error->message);
+      g_error_free (error);
+      return;
+    }
+
+  meta_backend_add_gpu (backend, META_GPU (new_gpu_kms));
+}
+
+static void
+connect_udev_device_added_handler (MetaBackendNative *native)
+{
+  native->udev_device_added_handler_id =
+    g_signal_connect (native->udev, "device-added",
+                      G_CALLBACK (on_udev_device_added), native);
+}
+
+static void
+disconnect_udev_device_added_handler (MetaBackendNative *native)
+{
+  g_signal_handler_disconnect (native->udev,
+                               native->udev_device_added_handler_id);
+  native->udev_device_added_handler_id = 0;
+}
+
+static gboolean
+init_gpus (MetaBackendNative  *native,
+           GError            **error)
+{
+  MetaBackend *backend = META_BACKEND (native);
+  MetaUdev *udev = meta_backend_native_get_udev (native);
+  GList *devices;
+  GList *l;
+
+  devices = meta_udev_list_drm_devices (udev, error);
+  if (!devices)
+    return FALSE;
+
+  for (l = devices; l; l = l->next)
+    {
+      GUdevDevice *device = l->data;
+      MetaGpuKms *gpu_kms;
+      GError *local_error = NULL;
+
+      gpu_kms = create_gpu_from_udev_device (native, device, &local_error);
+
+      if (!gpu_kms)
+        {
+          g_warning ("Failed to open gpu '%s': %s",
+                     g_udev_device_get_device_file (device),
+                     local_error->message);
+          g_clear_error (&local_error);
+          continue;
+        }
+
+      meta_backend_add_gpu (backend, META_GPU (gpu_kms));
+    }
+
+  g_list_free_full (devices, g_object_unref);
+
+  if (g_list_length (meta_backend_get_gpus (backend)) == 0)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+                   "No GPUs found");
+      return FALSE;
+    }
+
+  connect_udev_device_added_handler (native);
+
+  return TRUE;
+}
+
 static gboolean
 meta_backend_native_initable_init (GInitable     *initable,
                                    GCancellable  *cancellable,
@@ -534,6 +661,9 @@ meta_backend_native_initable_init (GInitable     *initable,
   native->udev = meta_udev_new (native);
   native->barrier_manager = meta_barrier_manager_native_new ();
 
+  if (!init_gpus (native, error))
+    return FALSE;
+
   return initable_parent_iface->init (initable, cancellable, error);
 }
 
@@ -650,6 +780,8 @@ meta_backend_native_pause (MetaBackendNative *native)
   clutter_evdev_release_devices ();
   clutter_stage_freeze_updates (stage);
 
+  disconnect_udev_device_added_handler (native);
+
   meta_monitor_manager_kms_pause (monitor_manager_kms);
 }
 
@@ -665,6 +797,8 @@ void meta_backend_native_resume (MetaBackendNative *native)
 
   meta_monitor_manager_kms_resume (monitor_manager_kms);
 
+  connect_udev_device_added_handler (native);
+
   clutter_evdev_reclaim_devices ();
   clutter_stage_thaw_updates (stage);
 
diff --git a/src/backends/native/meta-cursor-renderer-native.c 
b/src/backends/native/meta-cursor-renderer-native.c
index 3df804140..2cac69b8f 100644
--- a/src/backends/native/meta-cursor-renderer-native.c
+++ b/src/backends/native/meta-cursor-renderer-native.c
@@ -77,7 +77,7 @@ struct _MetaCursorRendererNative
 
 struct _MetaCursorRendererNativePrivate
 {
-  MetaMonitorManager *monitor_manager;
+  MetaBackend *backend;
 
   gboolean hw_state_invalidated;
   gboolean has_hw_cursor;
@@ -387,7 +387,9 @@ update_hw_cursor (MetaCursorRendererNative *native,
   MetaCursorRendererNativePrivate *priv =
     meta_cursor_renderer_native_get_instance_private (native);
   MetaCursorRenderer *renderer = META_CURSOR_RENDERER (native);
-  MetaMonitorManager *monitor_manager = priv->monitor_manager;
+  MetaBackend *backend = priv->backend;
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
   GList *logical_monitors;
   GList *l;
   ClutterRect rect;
@@ -480,7 +482,9 @@ cursor_over_transformed_logical_monitor (MetaCursorRenderer *renderer,
     META_CURSOR_RENDERER_NATIVE (renderer);
   MetaCursorRendererNativePrivate *priv =
     meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
-  MetaMonitorManager *monitor_manager = priv->monitor_manager;
+  MetaBackend *backend = priv->backend;
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
   GList *logical_monitors;
   GList *l;
   ClutterRect cursor_rect;
@@ -538,7 +542,9 @@ can_draw_cursor_unscaled (MetaCursorRenderer *renderer,
     META_CURSOR_RENDERER_NATIVE (renderer);
   MetaCursorRendererNativePrivate *priv =
     meta_cursor_renderer_native_get_instance_private (cursor_renderer_native);
-  MetaMonitorManager *monitor_manager = priv->monitor_manager;
+  MetaBackend *backend = priv->backend;
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
   ClutterRect cursor_rect;
   GList *logical_monitors;
   GList *l;
@@ -680,7 +686,9 @@ calculate_cursor_sprite_gpus (MetaCursorRenderer *renderer,
   MetaCursorRendererNative *native = META_CURSOR_RENDERER_NATIVE (renderer);
   MetaCursorRendererNativePrivate *priv =
     meta_cursor_renderer_native_get_instance_private (native);
-  MetaMonitorManager *monitor_manager = priv->monitor_manager;
+  MetaBackend *backend = priv->backend;
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
   GList *gpus = NULL;
   GList *logical_monitors;
   GList *l;
@@ -1175,7 +1183,7 @@ init_hw_cursor_support (MetaCursorRendererNative *cursor_renderer_native)
   GList *gpus;
   GList *l;
 
-  gpus = meta_monitor_manager_get_gpus (priv->monitor_manager);
+  gpus = meta_backend_get_gpus (priv->backend);
   for (l = gpus; l; l = l->next)
     {
       MetaGpuKms *gpu_kms = l->data;
@@ -1223,7 +1231,7 @@ meta_cursor_renderer_native_new (MetaBackend *backend)
                            G_CALLBACK (on_monitors_changed),
                            cursor_renderer_native, 0);
 
-  priv->monitor_manager = monitor_manager;
+  priv->backend = backend;
   priv->hw_state_invalidated = TRUE;
 
   init_hw_cursor_support (cursor_renderer_native);
diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c
index c569b948e..bf9843f02 100644
--- a/src/backends/native/meta-gpu-kms.c
+++ b/src/backends/native/meta-gpu-kms.c
@@ -204,7 +204,9 @@ meta_gpu_kms_is_crtc_active (MetaGpuKms *gpu_kms,
                              MetaCrtc   *crtc)
 {
   MetaGpu *gpu = META_GPU (gpu_kms);
-  MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu);
+  MetaBackend *backend = meta_gpu_get_backend (gpu);
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
   GList *l;
   gboolean connected_crtc_found;
 
@@ -265,7 +267,9 @@ meta_gpu_kms_flip_crtc (MetaGpuKms  *gpu_kms,
                         GError     **error)
 {
   MetaGpu *gpu = META_GPU (gpu_kms);
-  MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu);
+  MetaBackend *backend = meta_gpu_get_backend (gpu);
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
   MetaGpuKmsFlipClosureContainer *closure_container;
   int kms_fd = meta_gpu_kms_get_fd (gpu_kms);
   uint32_t *connectors;
@@ -273,6 +277,7 @@ meta_gpu_kms_flip_crtc (MetaGpuKms  *gpu_kms,
   int ret = -1;
 
   g_assert (meta_crtc_get_gpu (crtc) == gpu);
+  g_assert (monitor_manager);
   g_assert (meta_monitor_manager_get_power_save_mode (monitor_manager) ==
             META_POWER_SAVE_ON);
 
@@ -878,16 +883,12 @@ meta_gpu_kms_can_have_outputs (MetaGpuKms *gpu_kms)
 }
 
 MetaGpuKms *
-meta_gpu_kms_new (MetaMonitorManagerKms  *monitor_manager_kms,
-                  const char             *kms_file_path,
-                  MetaGpuKmsFlag          flags,
-                  GError                **error)
+meta_gpu_kms_new (MetaBackendNative  *backend_native,
+                  const char         *kms_file_path,
+                  MetaGpuKmsFlag      flags,
+                  GError            **error)
 {
-  MetaMonitorManager *monitor_manager =
-    META_MONITOR_MANAGER (monitor_manager_kms);
-  MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
-  MetaLauncher *launcher =
-    meta_backend_native_get_launcher (META_BACKEND_NATIVE (backend));
+  MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
   GSource *source;
   MetaKmsSource *kms_source;
   MetaGpuKms *gpu_kms;
@@ -898,7 +899,7 @@ meta_gpu_kms_new (MetaMonitorManagerKms  *monitor_manager_kms,
     return NULL;
 
   gpu_kms = g_object_new (META_TYPE_GPU_KMS,
-                          "monitor-manager", monitor_manager_kms,
+                          "backend", backend_native,
                           NULL);
 
   gpu_kms->flags = flags;
@@ -926,9 +927,7 @@ static void
 meta_gpu_kms_finalize (GObject *object)
 {
   MetaGpuKms *gpu_kms = META_GPU_KMS (object);
-  MetaMonitorManager *monitor_manager =
-    meta_gpu_get_monitor_manager (META_GPU (gpu_kms));
-  MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
+  MetaBackend *backend = meta_gpu_get_backend (META_GPU (gpu_kms));
   MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
   MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
 
diff --git a/src/backends/native/meta-gpu-kms.h b/src/backends/native/meta-gpu-kms.h
index 1f7a939e2..4df13c075 100644
--- a/src/backends/native/meta-gpu-kms.h
+++ b/src/backends/native/meta-gpu-kms.h
@@ -28,7 +28,7 @@
 #include <xf86drmMode.h>
 
 #include "backends/meta-gpu.h"
-#include "backends/native/meta-monitor-manager-kms.h"
+#include "backends/native/meta-backend-native.h"
 
 #define META_TYPE_GPU_KMS (meta_gpu_kms_get_type ())
 G_DECLARE_FINAL_TYPE (MetaGpuKms, meta_gpu_kms, META, GPU_KMS, MetaGpu)
@@ -51,10 +51,10 @@ typedef enum _MetaGpuKmsFlag
   META_GPU_KMS_FLAG_PLATFORM_DEVICE = (1 << 1),
 } MetaGpuKmsFlag;
 
-MetaGpuKms * meta_gpu_kms_new (MetaMonitorManagerKms  *monitor_manager_kms,
-                               const char             *kms_file_path,
-                               MetaGpuKmsFlag          flags,
-                               GError                **error);
+MetaGpuKms * meta_gpu_kms_new (MetaBackendNative  *backend_native,
+                               const char         *kms_file_path,
+                               MetaGpuKmsFlag      flags,
+                               GError            **error);
 
 gboolean meta_gpu_kms_apply_crtc_mode (MetaGpuKms *gpu_kms,
                                        MetaCrtc   *crtc,
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index d207c7a04..3c118e736 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -61,17 +61,6 @@
 #include "meta/main.h"
 #include "meta/meta-x11-errors.h"
 
-#define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor"
-
-enum
-{
-  GPU_ADDED,
-
-  LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = { 0 };
-
 typedef struct
 {
   GSource source;
@@ -84,8 +73,6 @@ struct _MetaMonitorManagerKms
 {
   MetaMonitorManager parent_instance;
 
-  GUdevClient *udev;
-  guint uevent_handler_id;
   guint hotplug_handler_id;
 };
 
@@ -148,7 +135,7 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
     return;
   }
 
-  for (l = manager->gpus; l; l = l->next)
+  for (l = meta_backend_get_gpus (manager->backend); l; l = l->next)
     {
       MetaGpuKms *gpu_kms = l->data;
 
@@ -173,7 +160,9 @@ apply_crtc_assignments (MetaMonitorManager *manager,
                         MetaOutputInfo     **outputs,
                         unsigned int         n_outputs)
 {
+  MetaBackend *backend = meta_monitor_manager_get_backend (manager);
   unsigned i;
+  GList *gpus;
   GList *l;
 
   for (i = 0; i < n_crtcs; i++)
@@ -230,7 +219,8 @@ apply_crtc_assignments (MetaMonitorManager *manager,
     }
   /* Disable CRTCs not mentioned in the list (they have is_dirty == FALSE,
      because they weren't seen in the first loop) */
-  for (l = manager->gpus; l; l = l->next)
+  gpus = meta_backend_get_gpus (backend);
+  for (l = gpus; l; l = l->next)
     {
       MetaGpu *gpu = l->data;
       GList *k;
@@ -268,7 +258,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
     }
 
   /* Disable outputs not mentioned in the list */
-  for (l = manager->gpus; l; l = l->next)
+  for (l = gpus; l; l = l->next)
     {
       MetaGpu *gpu = l->data;
       GList *k;
@@ -407,44 +397,6 @@ handle_hotplug_event (MetaMonitorManager *manager)
   meta_monitor_manager_on_hotplug (manager);
 }
 
-static void
-handle_gpu_hotplug (MetaMonitorManagerKms *manager_kms,
-                    GUdevDevice           *device)
-{
-  MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
-  g_autoptr (GError) error = NULL;
-  const char *gpu_path;
-  MetaGpuKms *gpu_kms;
-  GList *gpus, *l;
-
-  gpu_path = g_udev_device_get_device_file (device);
-
-  gpus = meta_monitor_manager_get_gpus (manager);
-  for (l = gpus; l; l = l->next)
-    {
-      MetaGpuKms *gpu_kms = l->data;
-
-      if (!g_strcmp0 (gpu_path, meta_gpu_kms_get_file_path (gpu_kms)))
-        {
-          g_warning ("Failed to hotplug secondary gpu '%s': %s",
-                     gpu_path, "device already present");
-          return;
-        }
-    }
-
-  gpu_kms = meta_gpu_kms_new (manager_kms, gpu_path,
-                              META_GPU_KMS_FLAG_NONE, &error);
-  if (!gpu_kms)
-    {
-      g_warning ("Failed to hotplug secondary gpu '%s': %s",
-                 gpu_path, error->message);
-      return;
-    }
-  meta_monitor_manager_add_gpu (manager, META_GPU (gpu_kms));
-
-  g_signal_emit (manager_kms, signals[GPU_ADDED], 0, gpu_kms);
-}
-
 static void
 on_udev_hotplug (MetaUdev           *udev,
                  MetaMonitorManager *manager)
@@ -474,67 +426,17 @@ meta_monitor_manager_kms_disconnect_hotplug_handler (MetaMonitorManagerKms *mana
   manager_kms->hotplug_handler_id = 0;
 }
 
-static void
-on_uevent (GUdevClient *client,
-           const char  *action,
-           GUdevDevice *device,
-           gpointer     user_data)
-{
-  MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (user_data);
-  MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
-
-  if (g_str_equal (action, "add") &&
-      g_udev_device_get_device_file (device) != NULL)
-    {
-      MetaBackend *backend = meta_monitor_manager_get_backend (manager);
-      MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
-      MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
-      const char *device_seat;
-      const char *seat_id;
-
-      device_seat = g_udev_device_get_property (device, "ID_SEAT");
-      seat_id = meta_launcher_get_seat_id (launcher);
-
-      if (!device_seat)
-        device_seat = "seat0";
-
-      if (!g_strcmp0 (seat_id, device_seat))
-        handle_gpu_hotplug (manager_kms, device);
-    }
-}
-
-static void
-meta_monitor_manager_kms_connect_uevent_handler (MetaMonitorManagerKms *manager_kms)
-{
-  manager_kms->uevent_handler_id = g_signal_connect (manager_kms->udev,
-                                                     "uevent",
-                                                     G_CALLBACK (on_uevent),
-                                                     manager_kms);
-}
-
-static void
-meta_monitor_manager_kms_disconnect_uevent_handler (MetaMonitorManagerKms *manager_kms)
-{
-  g_signal_handler_disconnect (manager_kms->udev,
-                               manager_kms->uevent_handler_id);
-  manager_kms->uevent_handler_id = 0;
-}
-
 void
 meta_monitor_manager_kms_pause (MetaMonitorManagerKms *manager_kms)
 {
-  meta_monitor_manager_kms_disconnect_uevent_handler (manager_kms);
   meta_monitor_manager_kms_disconnect_hotplug_handler (manager_kms);
 }
 
 void
 meta_monitor_manager_kms_resume (MetaMonitorManagerKms *manager_kms)
 {
-  MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
-
-  meta_monitor_manager_kms_connect_uevent_handler (manager_kms);
   meta_monitor_manager_kms_connect_hotplug_handler (manager_kms);
-  handle_hotplug_event (manager);
+  handle_hotplug_event (META_MONITOR_MANAGER (manager_kms));
 }
 
 static gboolean
@@ -620,112 +522,6 @@ meta_monitor_manager_kms_get_default_layout_mode (MetaMonitorManager *manager)
     return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
 }
 
-static gboolean
-init_gpus (MetaMonitorManagerKms  *manager_kms,
-           GError                **error)
-{
-  MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
-  MetaBackend *backend = meta_monitor_manager_get_backend (manager);
-  MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
-  MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
-  g_autoptr (GUdevEnumerator) enumerator = NULL;
-  const char *seat_id;
-  GList *devices;
-  GList *l;
-  MetaGpuKmsFlag flags = META_GPU_KMS_FLAG_NONE;
-
-  enumerator = g_udev_enumerator_new (manager_kms->udev);
-
-  g_udev_enumerator_add_match_name (enumerator, "card*");
-  g_udev_enumerator_add_match_tag (enumerator, "seat");
-
-  /*
-   * We need to explicitly match the subsystem for now.
-   * https://bugzilla.gnome.org/show_bug.cgi?id=773224
-   */
-  g_udev_enumerator_add_match_subsystem (enumerator, "drm");
-
-  devices = g_udev_enumerator_execute (enumerator);
-  if (!devices)
-    {
-      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)
-        continue;
-
-      device_type = g_udev_device_get_property (dev, "DEVTYPE");
-      if (g_strcmp0 (device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0)
-        continue;
-
-      device_path = g_udev_device_get_device_file (dev);
-
-      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";
-        }
-
-      /* Skip devices that do not belong to our seat. */
-      if (g_strcmp0 (seat_id, device_seat))
-        continue;
-
-      platform_device = g_udev_device_get_parent_with_subsystem (dev,
-                                                                 "platform",
-                                                                 NULL);
-      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 (g_udev_device_get_sysfs_attr_as_int (pci_device,
-                                                   "boot_vga") == 1)
-            flags |= META_GPU_KMS_FLAG_BOOT_VGA;
-        }
-
-      gpu_kms = meta_gpu_kms_new (manager_kms, device_path, flags,
-                                  &local_error);
-      if (!gpu_kms)
-        {
-          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);
-
-  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 gboolean
 meta_monitor_manager_kms_initable_init (GInitable    *initable,
                                         GCancellable *cancellable,
@@ -733,22 +529,14 @@ 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 *l;
+  MetaBackend *backend = meta_monitor_manager_get_backend (manager);
   gboolean can_have_outputs;
+  GList *l;
 
-  manager_kms->udev = g_udev_client_new (subsystems);
-
-  meta_monitor_manager_kms_connect_uevent_handler (manager_kms);
   meta_monitor_manager_kms_connect_hotplug_handler (manager_kms);
 
-  if (!init_gpus (manager_kms, error))
-    {
-      return FALSE;
-    }
-
   can_have_outputs = FALSE;
-  for (l = meta_monitor_manager_get_gpus (manager); l; l = l->next)
+  for (l = meta_backend_get_gpus (backend); l; l = l->next)
     {
       MetaGpuKms *gpu_kms = l->data;
 
@@ -774,16 +562,6 @@ initable_iface_init (GInitableIface *initable_iface)
   initable_iface->init = meta_monitor_manager_kms_initable_init;
 }
 
-static void
-meta_monitor_manager_kms_dispose (GObject *object)
-{
-  MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
-
-  g_clear_object (&manager_kms->udev);
-
-  G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->dispose (object);
-}
-
 static void
 meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
 {
@@ -793,9 +571,6 @@ static void
 meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
 {
   MetaMonitorManagerClass *manager_class = META_MONITOR_MANAGER_CLASS (klass);
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-  object_class->dispose = meta_monitor_manager_kms_dispose;
 
   manager_class->read_edid = meta_monitor_manager_kms_read_edid;
   manager_class->read_current_state = meta_monitor_manager_kms_read_current_state;
@@ -810,12 +585,4 @@ meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
   manager_class->get_capabilities = meta_monitor_manager_kms_get_capabilities;
   manager_class->get_max_screen_size = meta_monitor_manager_kms_get_max_screen_size;
   manager_class->get_default_layout_mode = meta_monitor_manager_kms_get_default_layout_mode;
-
-  signals[GPU_ADDED] =
-    g_signal_new ("gpu-added",
-                  G_TYPE_FROM_CLASS (object_class),
-                  G_SIGNAL_RUN_LAST,
-                  0,
-                  NULL, NULL, NULL,
-                  G_TYPE_NONE, 1, META_TYPE_GPU_KMS);
 }
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 4fee4756c..f994685e4 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -82,7 +82,7 @@ enum
 {
   PROP_0,
 
-  PROP_MONITOR_MANAGER,
+  PROP_BACKEND,
 
   PROP_LAST
 };
@@ -200,8 +200,9 @@ struct _MetaRendererNative
 {
   MetaRenderer parent;
 
-  MetaMonitorManagerKms *monitor_manager_kms;
   MetaGpuKms *primary_gpu_kms;
+
+  MetaBackend *backend;
   MetaGles3 *gles3;
 
   gboolean use_modifiers;
@@ -257,15 +258,6 @@ cogl_pixel_format_from_drm_format (uint32_t               drm_format,
                                    CoglPixelFormat       *out_format,
                                    CoglTextureComponents *out_components);
 
-static MetaBackend *
-backend_from_renderer_native (MetaRendererNative *renderer_native)
-{
-  MetaMonitorManager *monitor_manager =
-    META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
-
-  return meta_monitor_manager_get_backend (monitor_manager);
-}
-
 static void
 meta_renderer_native_gpu_data_free (MetaRendererNativeGpuData *renderer_gpu_data)
 {
@@ -289,9 +281,7 @@ meta_renderer_native_get_gpu_data (MetaRendererNative *renderer_native,
 static MetaRendererNative *
 meta_renderer_native_from_gpu (MetaGpuKms *gpu_kms)
 {
-  MetaMonitorManager *monitor_manager =
-    meta_gpu_get_monitor_manager (META_GPU (gpu_kms));
-  MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
+  MetaBackend *backend = meta_gpu_get_backend (META_GPU (gpu_kms));
 
   return META_RENDERER_NATIVE (meta_backend_get_renderer (backend));
 }
@@ -335,11 +325,7 @@ get_secondary_gpu_state (CoglOnscreen *onscreen,
 static MetaEgl *
 meta_renderer_native_get_egl (MetaRendererNative *renderer_native)
 {
-  MetaMonitorManager *monitor_manager =
-    META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
-  MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
-
-  return meta_backend_get_egl (backend);
+  return meta_backend_get_egl (renderer_native->backend);
 }
 
 static MetaEgl *
@@ -1558,7 +1544,7 @@ retry_page_flips (gpointer user_data)
   MetaOnscreenNative *onscreen_native = user_data;
   MetaRendererNative *renderer_native = onscreen_native->renderer_native;
   MetaMonitorManager *monitor_manager =
-    META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
+    meta_backend_get_monitor_manager (renderer_native->backend);
   uint64_t now_us;
   MetaPowerSave power_save_mode;
   GList *l;
@@ -1650,9 +1636,7 @@ retry_page_flips (gpointer user_data)
     }
   else
     {
-      MetaBackend *backend = backend_from_renderer_native (renderer_native);
-
-      meta_backend_thaw_updates (backend);
+      meta_backend_thaw_updates (renderer_native->backend);
       g_clear_pointer (&onscreen_native->retry_page_flips_source,
                        g_source_unref);
       return G_SOURCE_REMOVE;
@@ -1677,6 +1661,7 @@ schedule_retry_page_flip (MetaOnscreenNative *onscreen_native,
                           uint32_t            fb_id,
                           GClosure           *flip_closure)
 {
+  MetaRendererNative *renderer_native = onscreen_native->renderer_native;
   RetryPageFlipData *retry_page_flip_data;
   uint64_t now_us;
   uint64_t retry_time_us;
@@ -1693,8 +1678,6 @@ schedule_retry_page_flip (MetaOnscreenNative *onscreen_native,
 
   if (!onscreen_native->retry_page_flips_source)
     {
-      MetaBackend *backend =
-        backend_from_renderer_native (onscreen_native->renderer_native);
       GSource *source;
 
       source = g_source_new (&retry_page_flips_source_funcs, sizeof (GSource));
@@ -1703,7 +1686,7 @@ schedule_retry_page_flip (MetaOnscreenNative *onscreen_native,
       g_source_attach (source, NULL);
 
       onscreen_native->retry_page_flips_source = source;
-      meta_backend_freeze_updates (backend);
+      meta_backend_freeze_updates (renderer_native->backend);
     }
   else
     {
@@ -1989,7 +1972,7 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen)
   MetaRendererView *view = onscreen_native->view;
   MetaRendererNative *renderer_native = onscreen_native->renderer_native;
   MetaMonitorManager *monitor_manager =
-    META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
+    meta_backend_get_monitor_manager (renderer_native->backend);
   GClosure *flip_closure;
   MetaPowerSave power_save_mode;
   MetaLogicalMonitor *logical_monitor;
@@ -2319,7 +2302,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen,
   MetaRendererNativeGpuData *renderer_gpu_data = cogl_renderer_egl->platform;
   MetaRendererNative *renderer_native = renderer_gpu_data->renderer_native;
   MetaMonitorManager *monitor_manager =
-    META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
+    meta_backend_get_monitor_manager (renderer_native->backend);
   CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
   MetaOnscreenNative *onscreen_native = onscreen_egl->platform;
   MetaGpuKms *render_gpu = onscreen_native->render_gpu;
@@ -2938,6 +2921,7 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
   CoglRendererEGL *cogl_renderer_egl = cogl_renderer->winsys;
   CoglOnscreenEGL *onscreen_egl = onscreen->winsys;
   MetaOnscreenNative *onscreen_native;
+  MetaRendererNative *renderer_native;
   MetaRendererNativeGpuData *renderer_gpu_data;
 
   /* If we never successfully allocated then there's nothing to do */
@@ -2945,6 +2929,7 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
     return;
 
   onscreen_native = onscreen_egl->platform;
+  renderer_native = onscreen_native->renderer_native;
 
   if (onscreen_egl->egl_surface != EGL_NO_SURFACE &&
       (cogl_display_egl->current_draw_surface == onscreen_egl->egl_surface ||
@@ -2961,16 +2946,13 @@ meta_renderer_native_release_onscreen (CoglOnscreen *onscreen)
                     (GDestroyNotify) retry_page_flip_data_free);
   if (onscreen_native->retry_page_flips_source)
     {
-      MetaBackend *backend =
-        backend_from_renderer_native (onscreen_native->renderer_native);
-
-      meta_backend_thaw_updates (backend);
+      meta_backend_thaw_updates (renderer_native->backend);
       g_clear_pointer (&onscreen_native->retry_page_flips_source,
                        g_source_destroy);
     }
 
   renderer_gpu_data =
-    meta_renderer_native_get_gpu_data (onscreen_native->renderer_native,
+    meta_renderer_native_get_gpu_data (renderer_native,
                                        onscreen_native->render_gpu);
   switch (renderer_gpu_data->mode)
     {
@@ -3031,11 +3013,9 @@ _cogl_winsys_egl_vtable = {
 gboolean
 meta_renderer_native_supports_mirroring (MetaRendererNative *renderer_native)
 {
-  MetaMonitorManager *monitor_manager =
-    META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
   GList *l;
 
-  for (l = monitor_manager->gpus; l; l = l->next)
+  for (l = meta_backend_get_gpus (renderer_native->backend); l; l = l->next)
     {
       MetaGpuKms *gpu_kms = META_GPU_KMS (l->data);
       MetaRendererNativeGpuData *renderer_gpu_data;
@@ -3284,7 +3264,7 @@ calculate_view_transform (MetaMonitorManager *monitor_manager,
 static CoglContext *
 cogl_context_from_renderer_native (MetaRendererNative *renderer_native)
 {
-  MetaBackend *backend = backend_from_renderer_native (renderer_native);
+  MetaBackend *backend = renderer_native->backend;
   ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
 
   return clutter_backend_get_cogl_context (clutter_backend);
@@ -3338,8 +3318,9 @@ meta_renderer_native_create_view (MetaRenderer       *renderer,
                                   MetaLogicalMonitor *logical_monitor)
 {
   MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
+  MetaBackend *backend = renderer_native->backend;
   MetaMonitorManager *monitor_manager =
-    META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
+    meta_backend_get_monitor_manager (backend);
   CoglContext *cogl_context =
     cogl_context_from_renderer_native (renderer_native);
   CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
@@ -3429,11 +3410,9 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native)
 
   if (renderer_native->pending_unset_disabled_crtcs)
     {
-      MetaMonitorManager *monitor_manager =
-        META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
       GList *l;
 
-      for (l = meta_monitor_manager_get_gpus (monitor_manager); l; l = l->next)
+      for (l = meta_backend_get_gpus (renderer_native->backend); l; l = l->next)
         {
           MetaGpu *gpu = l->data;
           MetaGpuKms *gpu_kms = META_GPU_KMS (gpu);
@@ -3470,8 +3449,8 @@ meta_renderer_native_get_property (GObject    *object,
 
   switch (prop_id)
     {
-    case PROP_MONITOR_MANAGER:
-      g_value_set_object (value, renderer_native->monitor_manager_kms);
+    case PROP_BACKEND:
+      g_value_set_object (value, renderer_native->backend);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -3480,7 +3459,7 @@ meta_renderer_native_get_property (GObject    *object,
 }
 
 static void
-on_gpu_added (MetaMonitorManager *monitor_manager,
+on_gpu_added (MetaBackendNative  *backend_native,
               MetaGpuKms         *gpu_kms,
               MetaRendererNative *renderer_native);
 
@@ -3494,8 +3473,8 @@ meta_renderer_native_set_property (GObject      *object,
 
   switch (prop_id)
     {
-    case PROP_MONITOR_MANAGER:
-      renderer_native->monitor_manager_kms = g_value_get_object (value);
+    case PROP_BACKEND:
+      renderer_native->backend = g_value_get_object (value);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -3881,10 +3860,7 @@ get_egl_device_display (MetaRendererNative  *renderer_native,
 static int
 count_drm_devices (MetaRendererNative *renderer_native)
 {
-  MetaMonitorManager *monitor_manager =
-    META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
-
-  return g_list_length (meta_monitor_manager_get_gpus (monitor_manager));
+  return g_list_length (meta_backend_get_gpus (renderer_native->backend));
 }
 
 static MetaRendererNativeGpuData *
@@ -4031,11 +4007,11 @@ create_renderer_gpu_data (MetaRendererNative  *renderer_native,
 }
 
 static void
-on_gpu_added (MetaMonitorManager *monitor_manager,
+on_gpu_added (MetaBackendNative  *backend_native,
               MetaGpuKms         *gpu_kms,
               MetaRendererNative *renderer_native)
 {
-  MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
+  MetaBackend *backend = META_BACKEND (backend_native);
   ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend);
   CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend);
   CoglDisplay *cogl_display = cogl_context_get_display (cogl_context);
@@ -4052,10 +4028,10 @@ on_gpu_added (MetaMonitorManager *monitor_manager,
 }
 
 static MetaGpuKms *
-choose_primary_gpu_unchecked (MetaMonitorManager *manager,
+choose_primary_gpu_unchecked (MetaBackend        *backend,
                               MetaRendererNative *renderer_native)
 {
-  GList *gpus = meta_monitor_manager_get_gpus (manager);
+  GList *gpus = meta_backend_get_gpus (backend);
   GList *l;
   int allow_sw;
 
@@ -4103,14 +4079,14 @@ choose_primary_gpu_unchecked (MetaMonitorManager *manager,
 }
 
 static MetaGpuKms *
-choose_primary_gpu (MetaMonitorManager  *manager,
+choose_primary_gpu (MetaBackend         *backend,
                     MetaRendererNative  *renderer_native,
                     GError             **error)
 {
   MetaGpuKms *gpu_kms;
   MetaRendererNativeGpuData *renderer_gpu_data;
 
-  gpu_kms = choose_primary_gpu_unchecked (manager, renderer_native);
+  gpu_kms = choose_primary_gpu_unchecked (backend, renderer_native);
   renderer_gpu_data = meta_renderer_native_get_gpu_data (renderer_native,
                                                          gpu_kms);
   if (renderer_gpu_data->egl_display == EGL_NO_DISPLAY)
@@ -4130,14 +4106,11 @@ meta_renderer_native_initable_init (GInitable     *initable,
                                     GError       **error)
 {
   MetaRendererNative *renderer_native = META_RENDERER_NATIVE (initable);
-  MetaMonitorManagerKms *monitor_manager_kms =
-    renderer_native->monitor_manager_kms;
-  MetaMonitorManager *monitor_manager =
-    META_MONITOR_MANAGER (monitor_manager_kms);
+  MetaBackend *backend = renderer_native->backend;
   GList *gpus;
   GList *l;
 
-  gpus = meta_monitor_manager_get_gpus (monitor_manager);
+  gpus = meta_backend_get_gpus (backend);
   for (l = gpus; l; l = l->next)
     {
       MetaGpuKms *gpu_kms = META_GPU_KMS (l->data);
@@ -4146,7 +4119,7 @@ meta_renderer_native_initable_init (GInitable     *initable,
         return FALSE;
     }
 
-  renderer_native->primary_gpu_kms = choose_primary_gpu (monitor_manager,
+  renderer_native->primary_gpu_kms = choose_primary_gpu (backend,
                                                          renderer_native,
                                                          error);
   if (!renderer_native->primary_gpu_kms)
@@ -4183,16 +4156,14 @@ static void
 meta_renderer_native_constructed (GObject *object)
 {
   MetaRendererNative *renderer_native = META_RENDERER_NATIVE (object);
-  MetaMonitorManager *monitor_manager =
-    META_MONITOR_MANAGER (renderer_native->monitor_manager_kms);
-  MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
+  MetaBackend *backend = renderer_native->backend;
   MetaSettings *settings = meta_backend_get_settings (backend);
 
   if (meta_settings_is_experimental_feature_enabled (
         settings, META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS))
     renderer_native->use_modifiers = TRUE;
 
-  g_signal_connect (renderer_native->monitor_manager_kms, "gpu-added",
+  g_signal_connect (backend, "gpu-added",
                     G_CALLBACK (on_gpu_added), renderer_native);
 
   G_OBJECT_CLASS (meta_renderer_native_parent_class)->constructed (object);
@@ -4221,11 +4192,11 @@ meta_renderer_native_class_init (MetaRendererNativeClass *klass)
   renderer_class->create_cogl_renderer = meta_renderer_native_create_cogl_renderer;
   renderer_class->create_view = meta_renderer_native_create_view;
 
-  obj_props[PROP_MONITOR_MANAGER] =
-    g_param_spec_object ("monitor-manager",
-                         "monitor-manager",
-                         "MetaMonitorManagerKms",
-                         META_TYPE_MONITOR_MANAGER_KMS,
+  obj_props[PROP_BACKEND] =
+    g_param_spec_object ("backend",
+                         "backend",
+                         "MetaBackendNative",
+                         META_TYPE_BACKEND_NATIVE,
                          G_PARAM_READWRITE |
                          G_PARAM_CONSTRUCT_ONLY |
                          G_PARAM_STATIC_STRINGS);
@@ -4233,12 +4204,12 @@ meta_renderer_native_class_init (MetaRendererNativeClass *klass)
 }
 
 MetaRendererNative *
-meta_renderer_native_new (MetaMonitorManagerKms *monitor_manager_kms,
-                          GError               **error)
+meta_renderer_native_new (MetaBackendNative  *backend_native,
+                          GError            **error)
 {
   return g_initable_new (META_TYPE_RENDERER_NATIVE,
                          NULL,
                          error,
-                         "monitor-manager", monitor_manager_kms,
+                         "backend", backend_native,
                          NULL);
 }
diff --git a/src/backends/native/meta-renderer-native.h b/src/backends/native/meta-renderer-native.h
index a006dcbe7..900a8cb5a 100644
--- a/src/backends/native/meta-renderer-native.h
+++ b/src/backends/native/meta-renderer-native.h
@@ -46,8 +46,8 @@ typedef enum _MetaRendererNativeMode
 #endif
 } MetaRendererNativeMode;
 
-MetaRendererNative * meta_renderer_native_new (MetaMonitorManagerKms *monitor_manager_kms,
-                                               GError               **error);
+MetaRendererNative * meta_renderer_native_new (MetaBackendNative  *backend_native,
+                                               GError            **error);
 
 struct gbm_device * meta_gbm_device_from_gpu (MetaGpuKms *gpu_kms);
 
diff --git a/src/backends/native/meta-udev.c b/src/backends/native/meta-udev.c
index 489ca0948..ee7cc3ad4 100644
--- a/src/backends/native/meta-udev.c
+++ b/src/backends/native/meta-udev.c
@@ -73,7 +73,7 @@ meta_is_udev_device_boot_vga (GUdevDevice *device)
   return g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga") == 1;
 }
 
-static gboolean
+gboolean
 meta_udev_is_drm_device (MetaUdev    *udev,
                          GUdevDevice *device)
 {
@@ -168,12 +168,6 @@ on_uevent (GUdevClient *client,
     g_signal_emit (udev, signals[HOTPLUG], 0);
 }
 
-GUdevClient *
-meta_udev_get_gudev_client (MetaUdev *udev)
-{
-  return udev->gudev_client;
-}
-
 MetaUdev *
 meta_udev_new (MetaBackendNative *backend_native)
 {
diff --git a/src/backends/native/meta-udev.h b/src/backends/native/meta-udev.h
index 4618114f4..cf72acd1b 100644
--- a/src/backends/native/meta-udev.h
+++ b/src/backends/native/meta-udev.h
@@ -28,12 +28,13 @@
 #define META_TYPE_UDEV (meta_udev_get_type ())
 G_DECLARE_FINAL_TYPE (MetaUdev, meta_udev, META, UDEV, GObject)
 
-GUdevClient * meta_udev_get_gudev_client (MetaUdev *udev);
-
 gboolean meta_is_udev_device_platform_device (GUdevDevice *device);
 
 gboolean meta_is_udev_device_boot_vga (GUdevDevice *device);
 
+gboolean meta_udev_is_drm_device (MetaUdev    *udev,
+                                  GUdevDevice *device);
+
 GList * meta_udev_list_drm_devices (MetaUdev  *udev,
                                     GError   **error);
 
diff --git a/src/backends/x11/cm/meta-backend-x11-cm.c b/src/backends/x11/cm/meta-backend-x11-cm.c
index 1e377220b..d7e69ff23 100644
--- a/src/backends/x11/cm/meta-backend-x11-cm.c
+++ b/src/backends/x11/cm/meta-backend-x11-cm.c
@@ -28,6 +28,7 @@
 
 #include "backends/meta-backend-private.h"
 #include "backends/x11/meta-cursor-renderer-x11.h"
+#include "backends/x11/meta-gpu-xrandr.h"
 #include "backends/x11/meta-input-settings-x11.h"
 #include "backends/x11/meta-monitor-manager-xrandr.h"
 #include "backends/x11/cm/meta-renderer-x11-cm.h"
@@ -389,6 +390,16 @@ meta_backend_x11_cm_translate_crossing_event (MetaBackendX11 *x11,
 static void
 meta_backend_x11_cm_init (MetaBackendX11Cm *backend_x11_cm)
 {
+  MetaGpuXrandr *gpu_xrandr;
+
+  /*
+   * The X server deals with multiple GPUs for us, soe just see what the X
+   * server gives us as one single GPU, even though it may actually be backed
+   * by multiple.
+   */
+  gpu_xrandr = meta_gpu_xrandr_new (META_BACKEND_X11 (backend_x11_cm));
+  meta_backend_add_gpu (META_BACKEND (backend_x11_cm),
+                        META_GPU (gpu_xrandr));
 }
 
 static void
diff --git a/src/backends/x11/meta-crtc-xrandr.c b/src/backends/x11/meta-crtc-xrandr.c
index d201b8581..e917f9c7d 100644
--- a/src/backends/x11/meta-crtc-xrandr.c
+++ b/src/backends/x11/meta-crtc-xrandr.c
@@ -39,6 +39,7 @@
 #include <stdlib.h>
 #include <xcb/randr.h>
 
+#include "backends/meta-backend-private.h"
 #include "backends/meta-crtc.h"
 #include "backends/x11/meta-crtc-xrandr.h"
 #include "backends/x11/meta-gpu-xrandr.h"
@@ -60,7 +61,9 @@ meta_crtc_xrandr_set_config (MetaCrtc            *crtc,
 {
   MetaGpu *gpu = meta_crtc_get_gpu (crtc);
   MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (gpu);
-  MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu);
+  MetaBackend *backend = meta_gpu_get_backend (gpu);
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
   MetaMonitorManagerXrandr *monitor_manager_xrandr =
     META_MONITOR_MANAGER_XRANDR (monitor_manager);
   Display *xdisplay;
diff --git a/src/backends/x11/meta-gpu-xrandr.c b/src/backends/x11/meta-gpu-xrandr.c
index 3e8a7318d..e90189dc0 100644
--- a/src/backends/x11/meta-gpu-xrandr.c
+++ b/src/backends/x11/meta-gpu-xrandr.c
@@ -31,7 +31,9 @@
 #include <X11/extensions/dpms.h>
 #include <X11/Xlibint.h>
 
+#include "backends/meta-backend-private.h"
 #include "backends/meta-output.h"
+#include "backends/x11/meta-backend-x11.h"
 #include "backends/x11/meta-crtc-xrandr.h"
 #include "backends/x11/meta-monitor-manager-xrandr.h"
 #include "backends/x11/meta-output-xrandr.h"
@@ -86,7 +88,9 @@ meta_gpu_xrandr_read_current (MetaGpu  *gpu,
                               GError  **error)
 {
   MetaGpuXrandr *gpu_xrandr = META_GPU_XRANDR (gpu);
-  MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu);
+  MetaBackend *backend = meta_gpu_get_backend (gpu);
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
   MetaMonitorManagerXrandr *monitor_manager_xrandr =
     META_MONITOR_MANAGER_XRANDR (monitor_manager);
   Display *xdisplay =
@@ -229,10 +233,10 @@ meta_gpu_xrandr_read_current (MetaGpu  *gpu,
 }
 
 MetaGpuXrandr *
-meta_gpu_xrandr_new (MetaMonitorManagerXrandr *monitor_manager_xrandr)
+meta_gpu_xrandr_new (MetaBackendX11 *backend_x11)
 {
   return g_object_new (META_TYPE_GPU_XRANDR,
-                       "monitor-manager", monitor_manager_xrandr,
+                       "backend", backend_x11,
                        NULL);
 }
 
diff --git a/src/backends/x11/meta-gpu-xrandr.h b/src/backends/x11/meta-gpu-xrandr.h
index aad49d09b..2086f8632 100644
--- a/src/backends/x11/meta-gpu-xrandr.h
+++ b/src/backends/x11/meta-gpu-xrandr.h
@@ -26,7 +26,7 @@
 #include <X11/extensions/Xrandr.h>
 
 #include "backends/meta-gpu.h"
-#include "backends/x11/meta-monitor-manager-xrandr.h"
+#include "backends/x11/meta-backend-x11.h"
 
 #define META_TYPE_GPU_XRANDR (meta_gpu_xrandr_get_type ())
 G_DECLARE_FINAL_TYPE (MetaGpuXrandr, meta_gpu_xrandr, META, GPU_XRANDR, MetaGpu)
@@ -37,6 +37,6 @@ void meta_gpu_xrandr_get_max_screen_size (MetaGpuXrandr *gpu_xrandr,
                                           int           *max_width,
                                           int           *max_height);
 
-MetaGpuXrandr * meta_gpu_xrandr_new (MetaMonitorManagerXrandr *monitor_manager_xrandr);
+MetaGpuXrandr * meta_gpu_xrandr_new (MetaBackendX11 *backend_x11);
 
 #endif /* META_GPU_XRANDR_H */
diff --git a/src/backends/x11/meta-monitor-manager-xrandr.c b/src/backends/x11/meta-monitor-manager-xrandr.c
index 45c81f4eb..8fae335f0 100644
--- a/src/backends/x11/meta-monitor-manager-xrandr.c
+++ b/src/backends/x11/meta-monitor-manager-xrandr.c
@@ -73,13 +73,6 @@ struct _MetaMonitorManagerXrandr
   int rr_error_base;
   gboolean has_randr15;
 
-  /*
-   * The X server deals with multiple GPUs for us, soe just see what the X
-   * server gives us as one single GPU, even though it may actually be backed
-   * by multiple.
-   */
-  MetaGpu *gpu;
-
   xcb_timestamp_t last_xrandr_set_timestamp;
 
   GHashTable *tiled_monitor_atoms;
@@ -344,6 +337,15 @@ is_output_assignment_changed (MetaOutput      *output,
   return TRUE;
 }
 
+static MetaGpu *
+meta_monitor_manager_xrandr_get_gpu (MetaMonitorManagerXrandr *manager_xrandr)
+{
+  MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
+  MetaBackend *backend = meta_monitor_manager_get_backend (manager);
+
+  return META_GPU (meta_backend_get_gpus (backend)->data);
+}
+
 static gboolean
 is_assignments_changed (MetaMonitorManager *manager,
                         MetaCrtcInfo      **crtc_infos,
@@ -353,9 +355,10 @@ is_assignments_changed (MetaMonitorManager *manager,
 {
   MetaMonitorManagerXrandr *manager_xrandr =
     META_MONITOR_MANAGER_XRANDR (manager);
+  MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr);
   GList *l;
 
-  for (l = meta_gpu_get_crtcs (manager_xrandr->gpu); l; l = l->next)
+  for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
     {
       MetaCrtc *crtc = l->data;
 
@@ -363,7 +366,7 @@ is_assignments_changed (MetaMonitorManager *manager,
         return TRUE;
     }
 
-  for (l = meta_gpu_get_outputs (manager_xrandr->gpu); l; l = l->next)
+  for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
     {
       MetaOutput *output = l->data;
 
@@ -387,6 +390,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
                         unsigned int        n_outputs)
 {
   MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (manager);
+  MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr);
   unsigned i;
   GList *l;
   int width, height, width_mm, height_mm;
@@ -448,7 +452,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
     }
 
   /* Disable CRTCs not mentioned in the list */
-  for (l = meta_gpu_get_crtcs (manager_xrandr->gpu); l; l = l->next)
+  for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
     {
       MetaCrtc *crtc = l->data;
 
@@ -568,7 +572,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
     }
 
   /* Disable outputs not mentioned in the list */
-  for (l = meta_gpu_get_outputs (manager_xrandr->gpu); l; l = l->next)
+  for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
     {
       MetaOutput *output = l->data;
 
@@ -1003,8 +1007,9 @@ meta_monitor_manager_xrandr_get_max_screen_size (MetaMonitorManager *manager,
 {
   MetaMonitorManagerXrandr *manager_xrandr =
     META_MONITOR_MANAGER_XRANDR (manager);
+  MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr);
 
-  meta_gpu_xrandr_get_max_screen_size (META_GPU_XRANDR (manager_xrandr->gpu),
+  meta_gpu_xrandr_get_max_screen_size (META_GPU_XRANDR (gpu),
                                        max_width, max_height);
 
   return TRUE;
@@ -1022,13 +1027,10 @@ meta_monitor_manager_xrandr_constructed (GObject *object)
   MetaMonitorManagerXrandr *manager_xrandr =
     META_MONITOR_MANAGER_XRANDR (object);
   MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
-  MetaBackendX11 *backend =
-    META_BACKEND_X11 (meta_monitor_manager_get_backend (manager));
-
-  manager_xrandr->xdisplay = meta_backend_x11_get_xdisplay (backend);
+  MetaBackend *backend = meta_monitor_manager_get_backend (manager);
+  MetaBackendX11 *backend_x11 = META_BACKEND_X11 (backend);
 
-  manager_xrandr->gpu = META_GPU (meta_gpu_xrandr_new (manager_xrandr));
-  meta_monitor_manager_add_gpu (manager, manager_xrandr->gpu);
+  manager_xrandr->xdisplay = meta_backend_x11_get_xdisplay (backend_x11);
 
   if (!XRRQueryExtension (manager_xrandr->xdisplay,
                          &manager_xrandr->rr_event_base,
@@ -1068,7 +1070,6 @@ meta_monitor_manager_xrandr_finalize (GObject *object)
 {
   MetaMonitorManagerXrandr *manager_xrandr = META_MONITOR_MANAGER_XRANDR (object);
 
-  g_clear_object (&manager_xrandr->gpu);
   g_hash_table_destroy (manager_xrandr->tiled_monitor_atoms);
   g_free (manager_xrandr->supported_scales);
 
@@ -1115,6 +1116,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
                                           XEvent                   *event)
 {
   MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_xrandr);
+  MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr);
   MetaGpuXrandr *gpu_xrandr;
   XRRScreenResources *resources;
   gboolean is_hotplug;
@@ -1127,7 +1129,7 @@ meta_monitor_manager_xrandr_handle_xevent (MetaMonitorManagerXrandr *manager_xra
 
   meta_monitor_manager_read_current_state (manager);
 
-  gpu_xrandr = META_GPU_XRANDR (manager_xrandr->gpu);
+  gpu_xrandr = META_GPU_XRANDR (gpu);
   resources = meta_gpu_xrandr_get_resources (gpu_xrandr);
 
   is_hotplug = resources->timestamp < resources->configTimestamp;
diff --git a/src/backends/x11/meta-output-xrandr.c b/src/backends/x11/meta-output-xrandr.c
index 515389dae..42f22d1ae 100644
--- a/src/backends/x11/meta-output-xrandr.c
+++ b/src/backends/x11/meta-output-xrandr.c
@@ -41,6 +41,7 @@
 #include <X11/Xlib-xcb.h>
 #include <xcb/randr.h>
 
+#include "backends/meta-backend-private.h"
 #include "backends/meta-crtc.h"
 #include "backends/x11/meta-monitor-manager-xrandr.h"
 #include "meta/util.h"
@@ -49,7 +50,9 @@ static Display *
 xdisplay_from_output (MetaOutput *output)
 {
   MetaGpu *gpu = meta_output_get_gpu (output);
-  MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu);
+  MetaBackend *backend = meta_gpu_get_backend (gpu);
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
   MetaMonitorManagerXrandr *monitor_manager_xrandr =
     META_MONITOR_MANAGER_XRANDR (monitor_manager);
 
@@ -643,7 +646,9 @@ static void
 output_get_tile_info (MetaOutput *output)
 {
   MetaGpu *gpu = meta_output_get_gpu (output);
-  MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu);
+  MetaBackend *backend = meta_gpu_get_backend (gpu);
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
   MetaMonitorManagerXrandr *monitor_manager_xrandr =
     META_MONITOR_MANAGER_XRANDR (monitor_manager);
   Display *xdisplay = xdisplay_from_output (output);
diff --git a/src/backends/x11/nested/meta-backend-x11-nested.c 
b/src/backends/x11/nested/meta-backend-x11-nested.c
index 172c4d9ac..0f022aa76 100644
--- a/src/backends/x11/nested/meta-backend-x11-nested.c
+++ b/src/backends/x11/nested/meta-backend-x11-nested.c
@@ -28,8 +28,13 @@
 
 #include "wayland/meta-wayland.h"
 
-G_DEFINE_TYPE (MetaBackendX11Nested, meta_backend_x11_nested,
-               META_TYPE_BACKEND_X11)
+typedef struct _MetaBackendX11NestedPrivate
+{
+  MetaGpu *gpu;
+} MetaBackendX11NestedPrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (MetaBackendX11Nested, meta_backend_x11_nested,
+                            META_TYPE_BACKEND_X11)
 
 static MetaRenderer *
 meta_backend_x11_nested_create_renderer (MetaBackend *backend,
@@ -182,6 +187,32 @@ meta_backend_x11_nested_translate_device_event (MetaBackendX11 *x11,
   g_assert (device_event->event == meta_backend_x11_get_xwindow (x11));
 }
 
+static void
+meta_backend_x11_nested_real_init_gpus (MetaBackendX11Nested *backend_x11_nested)
+{
+  MetaBackendX11NestedPrivate *priv =
+    meta_backend_x11_nested_get_instance_private (backend_x11_nested);
+
+  priv->gpu = g_object_new (META_TYPE_GPU_DUMMY,
+                            "backend", backend_x11_nested,
+                            NULL);
+  meta_backend_add_gpu (META_BACKEND (backend_x11_nested), priv->gpu);
+}
+
+static void
+meta_backend_x11_nested_constructed (GObject *object)
+{
+  MetaBackendX11Nested *backend_x11_nested = META_BACKEND_X11_NESTED (object);
+  MetaBackendX11NestedClass *backend_x11_nested_class =
+    META_BACKEND_X11_NESTED_GET_CLASS (backend_x11_nested);
+  GObjectClass *parent_class =
+    G_OBJECT_CLASS (meta_backend_x11_nested_parent_class);
+
+  parent_class->constructed (object);
+
+  backend_x11_nested_class->init_gpus (backend_x11_nested);
+}
+
 static void
 meta_backend_x11_nested_init (MetaBackendX11Nested *backend_x11_nested)
 {
@@ -190,9 +221,12 @@ meta_backend_x11_nested_init (MetaBackendX11Nested *backend_x11_nested)
 static void
 meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
   MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
   MetaBackendX11Class *backend_x11_class = META_BACKEND_X11_CLASS (klass);
 
+  object_class->constructed = meta_backend_x11_nested_constructed;
+
   backend_class->create_renderer = meta_backend_x11_nested_create_renderer;
   backend_class->create_monitor_manager = meta_backend_x11_nested_create_monitor_manager;
   backend_class->create_cursor_renderer = meta_backend_x11_nested_create_cursor_renderer;
@@ -205,4 +239,6 @@ meta_backend_x11_nested_class_init (MetaBackendX11NestedClass *klass)
 
   backend_x11_class->handle_host_xevent = meta_backend_x11_nested_handle_host_xevent;
   backend_x11_class->translate_device_event = meta_backend_x11_nested_translate_device_event;
+
+  klass->init_gpus = meta_backend_x11_nested_real_init_gpus;
 }
diff --git a/src/backends/x11/nested/meta-backend-x11-nested.h 
b/src/backends/x11/nested/meta-backend-x11-nested.h
index 572ce1cc5..4f19ff54a 100644
--- a/src/backends/x11/nested/meta-backend-x11-nested.h
+++ b/src/backends/x11/nested/meta-backend-x11-nested.h
@@ -33,6 +33,8 @@ G_DECLARE_DERIVABLE_TYPE (MetaBackendX11Nested, meta_backend_x11_nested,
 struct _MetaBackendX11NestedClass
 {
   MetaBackendX11Class parent_class;
+
+  void (* init_gpus) (MetaBackendX11Nested *backend_x11_nested);
 };
 
 #endif /* META_BACKEND_X11_NESTED_H */
diff --git a/src/tests/headless-start-test.c b/src/tests/headless-start-test.c
index 172a16544..95ba3fa53 100644
--- a/src/tests/headless-start-test.c
+++ b/src/tests/headless-start-test.c
@@ -79,7 +79,7 @@ meta_test_headless_start (void)
   GList *gpus;
   MetaGpu *gpu;
 
-  gpus = meta_monitor_manager_get_gpus (monitor_manager);
+  gpus = meta_backend_get_gpus (backend);
   g_assert_cmpint ((int) g_list_length (gpus), ==, 1);
 
   gpu = gpus->data;
diff --git a/src/tests/meson.build b/src/tests/meson.build
index 050f5d3a9..dd1f3929f 100644
--- a/src/tests/meson.build
+++ b/src/tests/meson.build
@@ -66,6 +66,8 @@ unit_tests = executable('mutter-test-unit-tests',
     'boxes-tests.h',
     'meta-backend-test.c',
     'meta-backend-test.h',
+    'meta-gpu-test.c',
+    'meta-gpu-test.h',
     'meta-monitor-manager-test.c',
     'meta-monitor-manager-test.h',
     'monitor-config-migration-unit-tests.c',
@@ -89,6 +91,8 @@ headless_start_test = executable('mutter-headless-start-test',
     'headless-start-test.c',
     'meta-backend-test.c',
     'meta-backend-test.h',
+    'meta-gpu-test.c',
+    'meta-gpu-test.h',
     'meta-monitor-manager-test.c',
     'meta-monitor-manager-test.h',
     'test-utils.c',
diff --git a/src/tests/meta-backend-test.c b/src/tests/meta-backend-test.c
index 5da9da07f..0bc30d04d 100644
--- a/src/tests/meta-backend-test.c
+++ b/src/tests/meta-backend-test.c
@@ -21,12 +21,15 @@
 
 #include "tests/meta-backend-test.h"
 
+#include "tests/meta-gpu-test.h"
 #include "tests/meta-monitor-manager-test.h"
 
 struct _MetaBackendTest
 {
   MetaBackendX11Nested parent;
 
+  MetaGpu *gpu;
+
   gboolean is_lid_closed;
 };
 
@@ -39,6 +42,12 @@ meta_backend_test_set_is_lid_closed (MetaBackendTest *backend_test,
   backend_test->is_lid_closed = is_lid_closed;
 }
 
+MetaGpu *
+meta_backend_test_get_gpu (MetaBackendTest *backend_test)
+{
+  return backend_test->gpu;
+}
+
 static gboolean
 meta_backend_test_is_lid_closed (MetaBackend *backend)
 {
@@ -47,6 +56,17 @@ meta_backend_test_is_lid_closed (MetaBackend *backend)
   return backend_test->is_lid_closed;
 }
 
+static void
+meta_backend_test_init_gpus (MetaBackendX11Nested *backend_x11_nested)
+{
+  MetaBackendTest *backend_test = META_BACKEND_TEST (backend_x11_nested);
+
+  backend_test->gpu = g_object_new (META_TYPE_GPU_TEST,
+                                    "backend", backend_test,
+                                    NULL);
+  meta_backend_add_gpu (META_BACKEND (backend_test), backend_test->gpu);
+}
+
 static void
 meta_backend_test_init (MetaBackendTest *backend_test)
 {
@@ -65,7 +85,11 @@ static void
 meta_backend_test_class_init (MetaBackendTestClass *klass)
 {
   MetaBackendClass *backend_class = META_BACKEND_CLASS (klass);
+  MetaBackendX11NestedClass *backend_x11_nested_class =
+    META_BACKEND_X11_NESTED_CLASS (klass);
 
   backend_class->create_monitor_manager = meta_backend_test_create_monitor_manager;
   backend_class->is_lid_closed = meta_backend_test_is_lid_closed;
+
+  backend_x11_nested_class->init_gpus = meta_backend_test_init_gpus;
 }
diff --git a/src/tests/meta-backend-test.h b/src/tests/meta-backend-test.h
index 25cb8e6ee..d1cf81f1c 100644
--- a/src/tests/meta-backend-test.h
+++ b/src/tests/meta-backend-test.h
@@ -29,4 +29,6 @@ G_DECLARE_FINAL_TYPE (MetaBackendTest, meta_backend_test,
 void meta_backend_test_set_is_lid_closed (MetaBackendTest *backend_test,
                                           gboolean         is_lid_closed);
 
+MetaGpu * meta_backend_test_get_gpu (MetaBackendTest *backend_test);
+
 #endif /* META_BACKEND_TEST_H */
diff --git a/src/tests/meta-gpu-test.c b/src/tests/meta-gpu-test.c
new file mode 100644
index 000000000..d483fd211
--- /dev/null
+++ b/src/tests/meta-gpu-test.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016-2018 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include "tests/meta-gpu-test.h"
+
+#include "backends/meta-backend-private.h"
+#include "tests/meta-monitor-manager-test.h"
+
+struct _MetaGpuTest
+{
+  MetaGpu parent;
+};
+
+G_DEFINE_TYPE (MetaGpuTest, meta_gpu_test, META_TYPE_GPU)
+
+static gboolean
+meta_gpu_test_read_current (MetaGpu  *gpu,
+                            GError  **error)
+{
+  MetaBackend *backend = meta_gpu_get_backend (gpu);
+  MetaMonitorManager *manager = meta_backend_get_monitor_manager (backend);
+
+  meta_monitor_manager_test_read_current (manager);
+
+  return TRUE;
+}
+
+static void
+meta_gpu_test_init (MetaGpuTest *gpu_test)
+{
+}
+
+static void
+meta_gpu_test_class_init (MetaGpuTestClass *klass)
+{
+  MetaGpuClass *gpu_class = META_GPU_CLASS (klass);
+
+  gpu_class->read_current = meta_gpu_test_read_current;
+}
diff --git a/src/tests/meta-gpu-test.h b/src/tests/meta-gpu-test.h
new file mode 100644
index 000000000..46bbc80e2
--- /dev/null
+++ b/src/tests/meta-gpu-test.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2016-2018 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef META_GPU_TEST_H
+#define META_GPU_TEST_H
+
+#include "backends/meta-gpu.h"
+
+#define META_TYPE_GPU_TEST (meta_gpu_test_get_type ())
+G_DECLARE_FINAL_TYPE (MetaGpuTest, meta_gpu_test, META, GPU_TEST, MetaGpu)
+
+#endif /* META_GPU_TEST_H */
diff --git a/src/tests/meta-monitor-manager-test.c b/src/tests/meta-monitor-manager-test.c
index 45680ed5b..8232aaa2a 100644
--- a/src/tests/meta-monitor-manager-test.c
+++ b/src/tests/meta-monitor-manager-test.c
@@ -26,13 +26,12 @@
 #include "backends/meta-gpu.h"
 #include "backends/meta-monitor-config-manager.h"
 #include "backends/meta-output.h"
+#include "tests/meta-backend-test.h"
 
 struct _MetaMonitorManagerTest
 {
   MetaMonitorManager parent;
 
-  MetaGpu *gpu;
-
   gboolean handles_transforms;
 
   int tiled_monitor_count;
@@ -43,13 +42,6 @@ struct _MetaMonitorManagerTest
 G_DEFINE_TYPE (MetaMonitorManagerTest, meta_monitor_manager_test,
                META_TYPE_MONITOR_MANAGER)
 
-struct _MetaGpuTest
-{
-  MetaGpu parent;
-};
-
-G_DEFINE_TYPE (MetaGpuTest, meta_gpu_test, META_TYPE_GPU)
-
 static MetaMonitorTestSetup *_initial_test_setup = NULL;
 
 void
@@ -58,12 +50,6 @@ meta_monitor_manager_test_init_test_setup (MetaMonitorTestSetup *test_setup)
   _initial_test_setup = test_setup;
 }
 
-MetaGpu *
-meta_monitor_manager_test_get_gpu (MetaMonitorManagerTest *manager_test)
-{
-  return manager_test->gpu;
-}
-
 void
 meta_monitor_manager_test_emulate_hotplug (MetaMonitorManagerTest *manager_test,
                                            MetaMonitorTestSetup   *test_setup)
@@ -95,11 +81,13 @@ meta_monitor_manager_test_get_tiled_monitor_count (MetaMonitorManagerTest *manag
   return manager_test->tiled_monitor_count;
 }
 
-static void
+void
 meta_monitor_manager_test_read_current (MetaMonitorManager *manager)
 {
   MetaMonitorManagerTest *manager_test = META_MONITOR_MANAGER_TEST (manager);
-  MetaGpu *gpu = manager_test->gpu;
+  MetaBackend *backend = meta_monitor_manager_get_backend (manager);
+  MetaBackendTest *backend_test = META_BACKEND_TEST (backend);
+  MetaGpu *gpu = meta_backend_test_get_gpu (backend_test);
   GList *l;
 
   g_assert (manager_test->test_setup);
@@ -109,14 +97,9 @@ meta_monitor_manager_test_read_current (MetaMonitorManager *manager)
   for (l = manager_test->test_setup->crtcs; l; l = l->next)
     META_CRTC (l->data)->gpu = gpu;
 
-  meta_gpu_take_modes (manager_test->gpu,
-                       manager_test->test_setup->modes);
-
-  meta_gpu_take_crtcs (manager_test->gpu,
-                       manager_test->test_setup->crtcs);
-
-  meta_gpu_take_outputs (manager_test->gpu,
-                         manager_test->test_setup->outputs);
+  meta_gpu_take_modes (gpu, manager_test->test_setup->modes);
+  meta_gpu_take_crtcs (gpu, manager_test->test_setup->crtcs);
+  meta_gpu_take_outputs (gpu, manager_test->test_setup->outputs);
 }
 
 static void
@@ -143,7 +126,9 @@ apply_crtc_assignments (MetaMonitorManager *manager,
                         MetaOutputInfo    **outputs,
                         unsigned int        n_outputs)
 {
-  MetaMonitorManagerTest *manager_test = META_MONITOR_MANAGER_TEST (manager);
+  MetaBackend *backend = meta_monitor_manager_get_backend (manager);
+  MetaBackendTest *backend_test = META_BACKEND_TEST (backend);
+  MetaGpu *gpu = meta_backend_test_get_gpu (backend_test);
   GList *l;
   unsigned int i;
 
@@ -209,7 +194,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
     }
 
   /* Disable CRTCs not mentioned in the list */
-  for (l = meta_gpu_get_crtcs (manager_test->gpu); l; l = l->next)
+  for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
     {
       MetaCrtc *crtc = l->data;
 
@@ -229,7 +214,7 @@ apply_crtc_assignments (MetaMonitorManager *manager,
     }
 
   /* Disable outputs not mentioned in the list */
-  for (l = meta_gpu_get_outputs (manager_test->gpu); l; l = l->next)
+  for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
     {
       MetaOutput *output = l->data;
 
@@ -458,18 +443,11 @@ meta_monitor_manager_test_dispose (GObject *object)
 static void
 meta_monitor_manager_test_init (MetaMonitorManagerTest *manager_test)
 {
-  MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_test);
-
   g_assert (_initial_test_setup);
 
   manager_test->handles_transforms = TRUE;
 
   manager_test->test_setup = _initial_test_setup;
-
-  manager_test->gpu = g_object_new (META_TYPE_GPU_TEST,
-                                    "monitor-manager", manager,
-                                    NULL);
-  meta_monitor_manager_add_gpu (manager, manager_test->gpu);
 }
 
 static void
@@ -491,27 +469,3 @@ meta_monitor_manager_test_class_init (MetaMonitorManagerTestClass *klass)
   manager_class->get_max_screen_size = meta_monitor_manager_test_get_max_screen_size;
   manager_class->get_default_layout_mode = meta_monitor_manager_test_get_default_layout_mode;
 }
-
-static gboolean
-meta_gpu_test_read_current (MetaGpu  *gpu,
-                            GError  **error)
-{
-  MetaMonitorManager *manager = meta_gpu_get_monitor_manager (gpu);
-
-  meta_monitor_manager_test_read_current (manager);
-
-  return TRUE;
-}
-
-static void
-meta_gpu_test_init (MetaGpuTest *gpu_test)
-{
-}
-
-static void
-meta_gpu_test_class_init (MetaGpuTestClass *klass)
-{
-  MetaGpuClass *gpu_class = META_GPU_CLASS (klass);
-
-  gpu_class->read_current = meta_gpu_test_read_current;
-}
diff --git a/src/tests/meta-monitor-manager-test.h b/src/tests/meta-monitor-manager-test.h
index a38c7f198..0512a7fcb 100644
--- a/src/tests/meta-monitor-manager-test.h
+++ b/src/tests/meta-monitor-manager-test.h
@@ -20,7 +20,6 @@
 #ifndef META_MONITOR_MANAGER_TEST_H
 #define META_MONITOR_MANAGER_TEST_H
 
-#include "backends/meta-gpu.h"
 #include "backends/meta-monitor-manager-private.h"
 
 typedef struct _MetaMonitorTestSetup
@@ -39,12 +38,9 @@ typedef struct _MetaOutputTest
 G_DECLARE_FINAL_TYPE (MetaMonitorManagerTest, meta_monitor_manager_test,
                       META, MONITOR_MANAGER_TEST, MetaMonitorManager)
 
-#define META_TYPE_GPU_TEST (meta_gpu_test_get_type ())
-G_DECLARE_FINAL_TYPE (MetaGpuTest, meta_gpu_test, META, GPU_TEST, MetaGpu)
-
 void meta_monitor_manager_test_init_test_setup (MetaMonitorTestSetup *test_setup);
 
-MetaGpu * meta_monitor_manager_test_get_gpu (MetaMonitorManagerTest *manager_test);
+void meta_monitor_manager_test_read_current (MetaMonitorManager *manager);
 
 void meta_monitor_manager_test_emulate_hotplug (MetaMonitorManagerTest *manager_test,
                                                 MetaMonitorTestSetup   *test_setup);
diff --git a/src/tests/monitor-unit-tests.c b/src/tests/monitor-unit-tests.c
index f47544b03..83102c3a5 100644
--- a/src/tests/monitor-unit-tests.c
+++ b/src/tests/monitor-unit-tests.c
@@ -408,12 +408,10 @@ destroy_monitor_test_clients (void)
 }
 
 static MetaOutput *
-output_from_winsys_id (MetaMonitorManager *monitor_manager,
-                       uint64_t            winsys_id)
+output_from_winsys_id (MetaBackend *backend,
+                       uint64_t     winsys_id)
 {
-  MetaMonitorManagerTest *monitor_manager_test =
-    META_MONITOR_MANAGER_TEST (monitor_manager);
-  MetaGpu *gpu = meta_monitor_manager_test_get_gpu (monitor_manager_test);
+  MetaGpu *gpu = meta_backend_test_get_gpu (META_BACKEND_TEST (backend));
   GList *l;
 
   for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
@@ -429,7 +427,7 @@ output_from_winsys_id (MetaMonitorManager *monitor_manager,
 
 typedef struct _CheckMonitorModeData
 {
-  MetaMonitorManager *monitor_manager;
+  MetaBackend *backend;
   MetaTestCaseMonitorCrtcMode *expect_crtc_mode_iter;
 } CheckMonitorModeData;
 
@@ -441,12 +439,12 @@ check_monitor_mode (MetaMonitor         *monitor,
                     GError             **error)
 {
   CheckMonitorModeData *data = user_data;
-  MetaMonitorManager *monitor_manager = data->monitor_manager;
+  MetaBackend *backend = data->backend;
   MetaOutput *output;
   MetaCrtcMode *crtc_mode;
   int expect_crtc_mode_index;
 
-  output = output_from_winsys_id (monitor_manager,
+  output = output_from_winsys_id (backend,
                                   data->expect_crtc_mode_iter->output);
   g_assert (monitor_crtc_mode->output == output);
 
@@ -489,11 +487,11 @@ check_current_monitor_mode (MetaMonitor         *monitor,
                             GError             **error)
 {
   CheckMonitorModeData *data = user_data;
-  MetaMonitorManager *monitor_manager = data->monitor_manager;
+  MetaBackend *backend = data->backend;
   MetaOutput *output;
   MetaCrtc *crtc;
 
-  output = output_from_winsys_id (monitor_manager,
+  output = output_from_winsys_id (backend,
                                   data->expect_crtc_mode_iter->output);
   crtc = meta_output_get_assigned_crtc (output);
 
@@ -661,7 +659,7 @@ check_monitor_configuration (MonitorTestCase *test_case)
     meta_backend_get_monitor_manager (backend);
   MetaMonitorManagerTest *monitor_manager_test =
     META_MONITOR_MANAGER_TEST (monitor_manager);
-  MetaGpu *gpu = meta_monitor_manager_test_get_gpu (monitor_manager_test);
+  MetaGpu *gpu = meta_backend_test_get_gpu (META_BACKEND_TEST (backend));
   int tiled_monitor_count;
   GList *monitors;
   GList *crtcs;
@@ -716,8 +714,7 @@ check_monitor_configuration (MonitorTestCase *test_case)
           MetaOutput *output = l_output->data;
           uint64_t winsys_id = test_case->expect.monitors[i].outputs[j];
 
-          g_assert (output == output_from_winsys_id (monitor_manager,
-                                                     winsys_id));
+          g_assert (output == output_from_winsys_id (backend, winsys_id));
           g_assert_cmpint (test_case->expect.monitors[i].is_underscanning,
                            ==,
                            output->is_underscanning);
@@ -763,7 +760,7 @@ check_monitor_configuration (MonitorTestCase *test_case)
                            test_case->expect.monitors[i].modes[j].flags);
 
           data = (CheckMonitorModeData) {
-            .monitor_manager = monitor_manager,
+            .backend = backend,
             .expect_crtc_mode_iter =
               test_case->expect.monitors[i].modes[j].crtc_modes
           };
@@ -792,7 +789,7 @@ check_monitor_configuration (MonitorTestCase *test_case)
           CheckMonitorModeData data;
 
           data = (CheckMonitorModeData) {
-            .monitor_manager = monitor_manager,
+            .backend = backend,
             .expect_crtc_mode_iter =
               test_case->expect.monitors[i].modes[expected_current_mode_index].crtc_modes
           };



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