From 16a6aef5a7a79f1897010f6db73534777a75c43c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Thu, 6 Jul 2017 16:00:56 +0800 Subject: [PATCH] backends/native: Move KMS fd management to monitor manager Move finding, opening and managment of the KMS file descriptor to MetaMonitorManagerKms. This means that the monitor manager creation can now fail, both if more than one GPU with connectors is discovered, or if finding or opening the primary GPU fails. https://bugzilla.gnome.org/show_bug.cgi?id=785381 --- src/backends/meta-backend-private.h | 3 +- src/backends/meta-backend.c | 12 +- src/backends/native/meta-backend-native.c | 31 +- src/backends/native/meta-backend-native.h | 3 + .../native/meta-cursor-renderer-native.c | 6 +- src/backends/native/meta-launcher.c | 310 ++++-------------- src/backends/native/meta-launcher.h | 10 +- .../native/meta-monitor-manager-kms.c | 276 ++++++++++++++-- .../native/meta-monitor-manager-kms.h | 2 + src/backends/native/meta-renderer-native.c | 190 +++++------ src/backends/native/meta-renderer-native.h | 8 +- src/backends/x11/cm/meta-backend-x11-cm.c | 3 +- .../x11/nested/meta-backend-x11-nested.c | 3 +- src/tests/meta-backend-test.c | 3 +- 14 files changed, 470 insertions(+), 390 deletions(-) diff --git a/src/backends/meta-backend-private.h b/src/backends/meta-backend-private.h index fda36ed5c..0dc6bf77a 100644 --- a/src/backends/meta-backend-private.h +++ b/src/backends/meta-backend-private.h @@ -61,7 +61,8 @@ struct _MetaBackendClass MetaIdleMonitor * (* create_idle_monitor) (MetaBackend *backend, int device_id); - MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend); + MetaMonitorManager * (* create_monitor_manager) (MetaBackend *backend, + GError **error); MetaCursorRenderer * (* create_cursor_renderer) (MetaBackend *backend); MetaRenderer * (* create_renderer) (MetaBackend *backend, GError **error); diff --git a/src/backends/meta-backend.c b/src/backends/meta-backend.c index 42800b6fd..7571e6e1e 100644 --- a/src/backends/meta-backend.c +++ b/src/backends/meta-backend.c @@ -571,12 +571,14 @@ experimental_features_changed (MetaSettings *settings, } static MetaMonitorManager * -meta_backend_create_monitor_manager (MetaBackend *backend) +meta_backend_create_monitor_manager (MetaBackend *backend, + GError **error) { if (g_getenv ("META_DUMMY_MONITORS")) return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL); - return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend); + return META_BACKEND_GET_CLASS (backend)->create_monitor_manager (backend, + error); } static MetaRenderer * @@ -603,12 +605,14 @@ meta_backend_initable_init (GInitable *initable, priv->orientation_manager = g_object_new (META_TYPE_ORIENTATION_MANAGER, NULL); + priv->monitor_manager = meta_backend_create_monitor_manager (backend, error); + if (!priv->monitor_manager) + return FALSE; + priv->renderer = meta_backend_create_renderer (backend, error); if (!priv->renderer) return FALSE; - priv->monitor_manager = meta_backend_create_monitor_manager (backend); - priv->cursor_tracker = g_object_new (META_TYPE_CURSOR_TRACKER, NULL); priv->dnd = g_object_new (META_TYPE_DND, NULL); diff --git a/src/backends/native/meta-backend-native.c b/src/backends/native/meta-backend-native.c index fb3392d47..217f09b4e 100644 --- a/src/backends/native/meta-backend-native.c +++ b/src/backends/native/meta-backend-native.c @@ -400,9 +400,10 @@ meta_backend_native_create_idle_monitor (MetaBackend *backend, } static MetaMonitorManager * -meta_backend_native_create_monitor_manager (MetaBackend *backend) +meta_backend_native_create_monitor_manager (MetaBackend *backend, + GError **error) { - return g_object_new (META_TYPE_MONITOR_MANAGER_KMS, NULL); + return g_initable_new (META_TYPE_MONITOR_MANAGER_KMS, NULL, error, NULL); } static MetaCursorRenderer * @@ -415,16 +416,13 @@ static MetaRenderer * meta_backend_native_create_renderer (MetaBackend *backend, GError **error) { - MetaBackendNative *native = META_BACKEND_NATIVE (backend); - MetaBackendNativePrivate *priv = - meta_backend_native_get_instance_private (native); - int kms_fd; - const char *kms_file_path; + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerKms *monitor_manager_kms = + META_MONITOR_MANAGER_KMS (monitor_manager); MetaRendererNative *renderer_native; - kms_fd = meta_launcher_get_kms_fd (priv->launcher); - kms_file_path = meta_launcher_get_kms_file_path (priv->launcher); - renderer_native = meta_renderer_native_new (kms_fd, kms_file_path, error); + renderer_native = meta_renderer_native_new (monitor_manager_kms, error); if (!renderer_native) return NULL; @@ -621,14 +619,23 @@ meta_backend_native_init (MetaBackendNative *native) native); } +MetaLauncher * +meta_backend_native_get_launcher (MetaBackendNative *native) +{ + MetaBackendNativePrivate *priv = + meta_backend_native_get_instance_private (native); + + return priv->launcher; +} + gboolean meta_activate_vt (int vt, GError **error) { MetaBackend *backend = meta_get_backend (); MetaBackendNative *native = META_BACKEND_NATIVE (backend); - MetaBackendNativePrivate *priv = meta_backend_native_get_instance_private (native); + MetaLauncher *launcher = meta_backend_native_get_launcher (native); - return meta_launcher_activate_vt (priv->launcher, vt, error); + return meta_launcher_activate_vt (launcher, vt, error); } MetaBarrierManagerNative * diff --git a/src/backends/native/meta-backend-native.h b/src/backends/native/meta-backend-native.h index 3ba57a0cf..d69fbe057 100644 --- a/src/backends/native/meta-backend-native.h +++ b/src/backends/native/meta-backend-native.h @@ -27,6 +27,7 @@ #include "backends/meta-backend-private.h" #include "backends/native/meta-clutter-backend-native.h" +#include "backends/native/meta-launcher.h" #define META_TYPE_BACKEND_NATIVE (meta_backend_native_get_type ()) G_DECLARE_FINAL_TYPE (MetaBackendNative, meta_backend_native, @@ -38,4 +39,6 @@ void meta_backend_native_pause (MetaBackendNative *backend_native); void meta_backend_native_resume (MetaBackendNative *backend_native); +MetaLauncher * meta_backend_native_get_launcher (MetaBackendNative *native); + #endif /* META_BACKEND_NATIVE_H */ diff --git a/src/backends/native/meta-cursor-renderer-native.c b/src/backends/native/meta-cursor-renderer-native.c index cb5686e74..dc10e2ed9 100644 --- a/src/backends/native/meta-cursor-renderer-native.c +++ b/src/backends/native/meta-cursor-renderer-native.c @@ -862,8 +862,12 @@ meta_cursor_renderer_native_init (MetaCursorRendererNative *native) MetaBackend *backend = meta_get_backend (); MetaRenderer *renderer = meta_backend_get_renderer (backend); MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); + MetaMonitorManager *monitor_manager = + meta_backend_get_monitor_manager (backend); + MetaMonitorManagerKms *monitor_manager_kms = + META_MONITOR_MANAGER_KMS (monitor_manager); - priv->drm_fd = meta_renderer_native_get_kms_fd (renderer_native); + priv->drm_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); priv->gbm = meta_renderer_native_get_gbm (renderer_native); uint64_t width, height; diff --git a/src/backends/native/meta-launcher.c b/src/backends/native/meta-launcher.c index eb35f88be..f655f0e26 100644 --- a/src/backends/native/meta-launcher.c +++ b/src/backends/native/meta-launcher.c @@ -47,20 +47,22 @@ #include "meta-idle-monitor-native.h" #include "meta-renderer-native.h" -#define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor" - struct _MetaLauncher { Login1Session *session_proxy; Login1Seat *seat_proxy; + char *seat_id; GHashTable *sysfs_fds; gboolean session_active; - - int kms_fd; - char *kms_file_path; }; +const char * +meta_launcher_get_seat_id (MetaLauncher *launcher) +{ + return launcher->seat_id; +} + static Login1Session * get_session_proxy (GCancellable *cancellable, GError **error) @@ -171,6 +173,54 @@ get_device_info_from_fd (int fd, return TRUE; } +int +meta_launcher_open_restricted (MetaLauncher *launcher, + const char *path, + GError **error) +{ + int fd; + int major, minor; + + if (!get_device_info_from_path (path, &major, &minor)) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_NOT_FOUND, + "Could not get device info for path %s: %m", path); + return -1; + } + + if (!take_device (launcher->session_proxy, major, minor, &fd, NULL, error)) + return -1; + + return fd; +} + +void +meta_launcher_close_restricted (MetaLauncher *launcher, + int fd) +{ + int major, minor; + GError *error = NULL; + + if (!get_device_info_from_fd (fd, &major, &minor)) + { + g_warning ("Could not get device info for fd %d: %m", fd); + goto out; + } + + if (!login1_session_call_release_device_sync (launcher->session_proxy, + major, minor, + NULL, &error)) + { + g_warning ("Could not release device (%d,%d): %s", + major, minor, error->message); + } + +out: + close (fd); +} + static int on_evdev_device_open (const char *path, int flags, @@ -178,12 +228,12 @@ on_evdev_device_open (const char *path, GError **error) { MetaLauncher *self = user_data; - int fd; - int major, minor; /* Allow readonly access to sysfs */ if (g_str_has_prefix (path, "/sys/")) { + int fd; + do { fd = open (path, flags); @@ -203,19 +253,7 @@ on_evdev_device_open (const char *path, return fd; } - if (!get_device_info_from_path (path, &major, &minor)) - { - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_NOT_FOUND, - "Could not get device info for path %s: %m", path); - return -1; - } - - if (!take_device (self->session_proxy, major, minor, &fd, NULL, error)) - return -1; - - return fd; + return meta_launcher_open_restricted (self, path, error); } static void @@ -223,8 +261,6 @@ on_evdev_device_close (int fd, gpointer user_data) { MetaLauncher *self = user_data; - int major, minor; - GError *error = NULL; if (g_hash_table_lookup (self->sysfs_fds, GINT_TO_POINTER (fd))) { @@ -234,21 +270,7 @@ on_evdev_device_close (int fd, return; } - if (!get_device_info_from_fd (fd, &major, &minor)) - { - g_warning ("Could not get device info for fd %d: %m", fd); - goto out; - } - - if (!login1_session_call_release_device_sync (self->session_proxy, - major, minor, - NULL, &error)) - { - g_warning ("Could not release device %d,%d: %s", major, minor, error->message); - } - -out: - close (fd); + meta_launcher_close_restricted (self, fd); } static void @@ -278,194 +300,6 @@ on_active_changed (Login1Session *session, sync_active (self); } -static guint -count_devices_with_connectors (const gchar *seat_name, - GList *devices) -{ - g_autoptr (GHashTable) cards = NULL; - GList *tmp; - - cards = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); - for (tmp = devices; tmp != NULL; tmp = tmp->next) - { - GUdevDevice *device = tmp->data; - g_autoptr (GUdevDevice) parent_device = NULL; - const gchar *parent_device_type = NULL; - const gchar *parent_device_name = NULL; - const gchar *card_seat; - - /* filter out the real card devices, we only care about the connectors */ - if (g_udev_device_get_device_type (device) != G_UDEV_DEVICE_TYPE_NONE) - continue; - - /* only connectors have a modes attribute */ - if (!g_udev_device_has_sysfs_attr (device, "modes")) - continue; - - parent_device = g_udev_device_get_parent (device); - - if (g_udev_device_get_device_type (parent_device) == G_UDEV_DEVICE_TYPE_CHAR) - parent_device_type = g_udev_device_get_property (parent_device, "DEVTYPE"); - - if (g_strcmp0 (parent_device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0) - continue; - - card_seat = g_udev_device_get_property (parent_device, "ID_SEAT"); - - if (!card_seat) - card_seat = "seat0"; - - if (g_strcmp0 (seat_name, card_seat) != 0) - continue; - - parent_device_name = g_udev_device_get_name (parent_device); - g_hash_table_insert (cards, - (gpointer) parent_device_name , - g_steal_pointer (&parent_device)); - } - - return g_hash_table_size (cards); -} - -static gchar * -get_primary_gpu_path (const gchar *seat_name) -{ - const gchar *subsystems[] = {"drm", NULL}; - gchar *path = NULL; - GList *devices, *tmp; - - g_autoptr (GUdevClient) gudev_client = g_udev_client_new (subsystems); - g_autoptr (GUdevEnumerator) enumerator = g_udev_enumerator_new (gudev_client); - - 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) - goto out; - - /* For now, fail on systems where some of the connectors - * are connected to secondary gpus. - * - * https://bugzilla.gnome.org/show_bug.cgi?id=771442 - */ - if (g_getenv ("MUTTER_ALLOW_HYBRID_GPUS") == NULL) - { - guint num_devices; - - num_devices = count_devices_with_connectors (seat_name, devices); - if (num_devices != 1) - goto out; - } - - for (tmp = devices; tmp != NULL; tmp = tmp->next) - { - g_autoptr (GUdevDevice) platform_device = NULL; - g_autoptr (GUdevDevice) pci_device = NULL; - GUdevDevice *dev = tmp->data; - gint boot_vga; - const gchar *device_type; - const gchar *device_seat; - - /* 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_seat = g_udev_device_get_property (dev, "ID_SEAT"); - if (!device_seat) - { - /* when ID_SEAT is not set, it means seat0 */ - device_seat = "seat0"; - } - else if (g_strcmp0 (device_seat, "seat0") != 0) - { - /* if the device has been explicitly assigned other seat - * than seat0, it is probably the right device to use */ - path = g_strdup (g_udev_device_get_device_file (dev)); - break; - } - - /* skip devices that do not belong to our seat */ - if (g_strcmp0 (seat_name, device_seat)) - continue; - - platform_device = g_udev_device_get_parent_with_subsystem (dev, "platform", NULL); - if (platform_device != NULL) - { - path = g_strdup (g_udev_device_get_device_file (dev)); - break; - } - - pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL); - if (pci_device != NULL) - { - /* get value of boot_vga attribute or 0 if the device has no boot_vga */ - boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, "boot_vga"); - if (boot_vga == 1) - { - /* found the boot_vga device */ - path = g_strdup (g_udev_device_get_device_file (dev)); - break; - } - } - } - -out: - g_list_free_full (devices, g_object_unref); - - return path; -} - -static gboolean -get_kms_fd (Login1Session *session_proxy, - const gchar *seat_id, - int *fd_out, - char **kms_file_path_out, - GError **error) -{ - int major, minor; - int fd; - - g_autofree gchar *path = get_primary_gpu_path (seat_id); - if (!path) - { - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_NOT_FOUND, - "could not find drm kms device"); - return FALSE; - } - - if (!get_device_info_from_path (path, &major, &minor)) - { - g_set_error (error, - G_IO_ERROR, - G_IO_ERROR_NOT_FOUND, - "Could not get device info for path %s: %m", path); - return FALSE; - } - - if (!take_device (session_proxy, major, minor, &fd, NULL, error)) - { - g_prefix_error (error, "Could not open DRM device: "); - return FALSE; - } - - *fd_out = fd; - *kms_file_path_out = g_steal_pointer (&path); - - return TRUE; -} - static gchar * get_seat_id (GError **error) { @@ -504,8 +338,6 @@ meta_launcher_new (GError **error) g_autoptr (Login1Seat) seat_proxy = NULL; g_autofree char *seat_id = NULL; gboolean have_control = FALSE; - int kms_fd; - char *kms_file_path; session_proxy = get_session_proxy (NULL, error); if (!session_proxy) @@ -527,25 +359,21 @@ meta_launcher_new (GError **error) if (!seat_proxy) goto fail; - if (!get_kms_fd (session_proxy, seat_id, &kms_fd, &kms_file_path, error)) - goto fail; - self = g_slice_new0 (MetaLauncher); self->session_proxy = g_object_ref (session_proxy); self->seat_proxy = g_object_ref (seat_proxy); + self->seat_id = g_steal_pointer (&seat_id); self->sysfs_fds = g_hash_table_new (NULL, NULL); - self->session_active = TRUE; - self->kms_fd = kms_fd; - self->kms_file_path = kms_file_path; - clutter_evdev_set_seat_id (seat_id); + clutter_evdev_set_seat_id (self->seat_id); clutter_evdev_set_device_callbacks (on_evdev_device_open, on_evdev_device_close, self); g_signal_connect (self->session_proxy, "notify::active", G_CALLBACK (on_active_changed), self); + return self; fail: @@ -557,10 +385,10 @@ meta_launcher_new (GError **error) void meta_launcher_free (MetaLauncher *self) { + g_free (self->seat_id); g_object_unref (self->seat_proxy); g_object_unref (self->session_proxy); g_hash_table_destroy (self->sysfs_fds); - g_free (self->kms_file_path); g_slice_free (MetaLauncher, self); } @@ -582,15 +410,3 @@ meta_launcher_activate_vt (MetaLauncher *launcher, { return login1_seat_call_switch_to_sync (launcher->seat_proxy, vt, NULL, error); } - -int -meta_launcher_get_kms_fd (MetaLauncher *self) -{ - return self->kms_fd; -} - -const char * -meta_launcher_get_kms_file_path (MetaLauncher *self) -{ - return self->kms_file_path; -} diff --git a/src/backends/native/meta-launcher.h b/src/backends/native/meta-launcher.h index 4b16e351c..d83cf8139 100644 --- a/src/backends/native/meta-launcher.h +++ b/src/backends/native/meta-launcher.h @@ -34,8 +34,14 @@ gboolean meta_launcher_activate_vt (MetaLauncher *self, signed char vt, GError **error); -int meta_launcher_get_kms_fd (MetaLauncher *self); +const char * meta_launcher_get_seat_id (MetaLauncher *launcher); + +int meta_launcher_open_restricted (MetaLauncher *launcher, + const char *path, + GError **error); + +void meta_launcher_close_restricted (MetaLauncher *launcher, + int fd); -const char * meta_launcher_get_kms_file_path (MetaLauncher *self); #endif /* META_LAUNCHER_H */ diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index b58f5c3ef..8d4362b8f 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -25,7 +25,9 @@ #include "meta-monitor-manager-kms.h" #include "meta-monitor-config-manager.h" +#include "meta-backend-native.h" #include "meta-crtc.h" +#include "meta-launcher.h" #include "meta-output.h" #include "meta-backend-private.h" #include "meta-renderer-native.h" @@ -49,6 +51,8 @@ #include "meta-default-modes.h" +#define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor" + typedef struct { GSource source; @@ -62,6 +66,7 @@ struct _MetaMonitorManagerKms MetaMonitorManager parent_instance; int fd; + char *file_path; MetaKmsSource *source; drmModeConnector **connectors; @@ -81,7 +86,13 @@ struct _MetaMonitorManagerKmsClass MetaMonitorManagerClass parent_class; }; -G_DEFINE_TYPE (MetaMonitorManagerKms, meta_monitor_manager_kms, META_TYPE_MONITOR_MANAGER); +static void +initable_iface_init (GInitableIface *initable_iface); + +G_DEFINE_TYPE_WITH_CODE (MetaMonitorManagerKms, meta_monitor_manager_kms, + META_TYPE_MONITOR_MANAGER, + G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, + initable_iface_init)) int meta_monitor_manager_kms_get_fd (MetaMonitorManagerKms *manager_kms) @@ -89,6 +100,12 @@ meta_monitor_manager_kms_get_fd (MetaMonitorManagerKms *manager_kms) return manager_kms->fd; } +const char * +meta_monitor_manager_kms_get_file_path (MetaMonitorManagerKms *manager_kms) +{ + return manager_kms->file_path; +} + static void free_resources (MetaMonitorManagerKms *manager_kms) { @@ -1076,6 +1093,235 @@ meta_monitor_manager_kms_get_default_layout_mode (MetaMonitorManager *manager) return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL; } +static guint +count_devices_with_connectors (const char *seat_id, + GList *devices) +{ + g_autoptr (GHashTable) cards = NULL; + GList *l; + + cards = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_object_unref); + for (l = devices; l != NULL; l = l->next) + { + GUdevDevice *device = l->data; + g_autoptr (GUdevDevice) parent_device = NULL; + const gchar *parent_device_type = NULL; + const gchar *parent_device_name = NULL; + const gchar *card_seat; + + /* Filter out the real card devices, we only care about the connectors. */ + if (g_udev_device_get_device_type (device) != G_UDEV_DEVICE_TYPE_NONE) + continue; + + /* Only connectors have a modes attribute. */ + if (!g_udev_device_has_sysfs_attr (device, "modes")) + continue; + + parent_device = g_udev_device_get_parent (device); + + if (g_udev_device_get_device_type (parent_device) == + G_UDEV_DEVICE_TYPE_CHAR) + parent_device_type = g_udev_device_get_property (parent_device, + "DEVTYPE"); + + if (g_strcmp0 (parent_device_type, DRM_CARD_UDEV_DEVICE_TYPE) != 0) + continue; + + card_seat = g_udev_device_get_property (parent_device, "ID_SEAT"); + + if (!card_seat) + card_seat = "seat0"; + + if (g_strcmp0 (seat_id, card_seat) != 0) + continue; + + parent_device_name = g_udev_device_get_name (parent_device); + g_hash_table_insert (cards, + (gpointer) parent_device_name , + g_steal_pointer (&parent_device)); + } + + return g_hash_table_size (cards); +} + +static char * +get_primary_gpu_path (MetaMonitorManagerKms *manager_kms) +{ + MetaBackend *backend = meta_get_backend (); + 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; + char *path = NULL; + GList *devices; + GList *l; + + 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) + goto out; + + seat_id = meta_launcher_get_seat_id (launcher); + + /* + * For now, fail on systems where some of the connectors are connected to + * secondary gpus. + * + * https://bugzilla.gnome.org/show_bug.cgi?id=771442 + */ + if (g_getenv ("MUTTER_ALLOW_HYBRID_GPUS") == NULL) + { + unsigned int num_devices; + + num_devices = count_devices_with_connectors (seat_id, devices); + if (num_devices != 1) + goto out; + } + + for (l = devices; l; l = l->next) + { + GUdevDevice *dev = l->data; + g_autoptr (GUdevDevice) platform_device = NULL; + g_autoptr (GUdevDevice) pci_device = NULL; + const char *device_type; + const char *device_seat; + + /* 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_seat = g_udev_device_get_property (dev, "ID_SEAT"); + if (!device_seat) + { + /* When ID_SEAT is not set, it means seat0. */ + device_seat = "seat0"; + } + else if (g_strcmp0 (device_seat, "seat0") != 0) + { + /* + * If the device has been explicitly assigned other seat + * than seat0, it is probably the right device to use. + */ + path = g_strdup (g_udev_device_get_device_file (dev)); + break; + } + + /* 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) + { + path = g_strdup (g_udev_device_get_device_file (dev)); + break; + } + + pci_device = g_udev_device_get_parent_with_subsystem (dev, "pci", NULL); + if (pci_device != NULL) + { + int boot_vga; + + boot_vga = g_udev_device_get_sysfs_attr_as_int (pci_device, + "boot_vga"); + if (boot_vga == 1) + { + path = g_strdup (g_udev_device_get_device_file (dev)); + break; + } + } + } + +out: + g_list_free_full (devices, g_object_unref); + + return path; +} + +static gboolean +open_primary_gpu (MetaMonitorManagerKms *manager_kms, + int *fd_out, + char **kms_file_path_out, + GError **error) +{ + MetaBackend *backend = meta_get_backend (); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native); + g_autofree char *path = NULL; + int fd; + + path = get_primary_gpu_path (manager_kms); + if (!path) + { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND, + "Could not find drm kms device"); + return FALSE; + } + + fd = meta_launcher_open_restricted (launcher, path, error); + if (fd == -1) + return FALSE; + + *fd_out = fd; + *kms_file_path_out = g_steal_pointer (&path); + + return TRUE; +} + +static gboolean +meta_monitor_manager_kms_initable_init (GInitable *initable, + GCancellable *cancellable, + GError **error) +{ + MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (initable); + GSource *source; + const char *subsystems[2] = { "drm", NULL }; + + manager_kms->udev = g_udev_client_new (subsystems); + + if (!open_primary_gpu (manager_kms, + &manager_kms->fd, + &manager_kms->file_path, + error)) + return FALSE; + + drmSetClientCap (manager_kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); + + meta_monitor_manager_kms_connect_uevent_handler (manager_kms); + + source = g_source_new (&kms_event_funcs, sizeof (MetaKmsSource)); + manager_kms->source = (MetaKmsSource *) source; + manager_kms->source->fd_tag = g_source_add_unix_fd (source, + manager_kms->fd, + G_IO_IN | G_IO_ERR); + manager_kms->source->manager_kms = manager_kms; + g_source_attach (source, NULL); + + return TRUE; +} + +static void +initable_iface_init (GInitableIface *initable_iface) +{ + initable_iface->init = meta_monitor_manager_kms_initable_init; +} + static void meta_monitor_manager_kms_dispose (GObject *object) { @@ -1090,6 +1336,13 @@ static void meta_monitor_manager_kms_finalize (GObject *object) { MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object); + MetaBackend *backend = meta_get_backend (); + MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend); + MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native); + + if (manager_kms->fd != -1) + meta_launcher_close_restricted (launcher, manager_kms->fd); + g_clear_pointer (&manager_kms->file_path, g_free); free_resources (manager_kms); g_source_destroy ((GSource *) manager_kms->source); @@ -1100,26 +1353,7 @@ meta_monitor_manager_kms_finalize (GObject *object) static void meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms) { - MetaBackend *backend = meta_get_backend (); - MetaRenderer *renderer = meta_backend_get_renderer (backend); - MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); - GSource *source; - - manager_kms->fd = meta_renderer_native_get_kms_fd (renderer_native); - - drmSetClientCap (manager_kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); - - const char *subsystems[2] = { "drm", NULL }; - manager_kms->udev = g_udev_client_new (subsystems); - meta_monitor_manager_kms_connect_uevent_handler (manager_kms); - - source = g_source_new (&kms_event_funcs, sizeof (MetaKmsSource)); - manager_kms->source = (MetaKmsSource *) source; - manager_kms->source->fd_tag = g_source_add_unix_fd (source, - manager_kms->fd, - G_IO_IN | G_IO_ERR); - manager_kms->source->manager_kms = manager_kms; - g_source_attach (source, NULL); + manager_kms->fd = -1; } static void diff --git a/src/backends/native/meta-monitor-manager-kms.h b/src/backends/native/meta-monitor-manager-kms.h index 67ccbfef5..e4e71b157 100644 --- a/src/backends/native/meta-monitor-manager-kms.h +++ b/src/backends/native/meta-monitor-manager-kms.h @@ -44,6 +44,8 @@ typedef void (*MetaKmsFlipCallback) (void *user_data); int meta_monitor_manager_kms_get_fd (MetaMonitorManagerKms *manager_kms); +const char * meta_monitor_manager_kms_get_file_path (MetaMonitorManagerKms *manager_kms); + gboolean meta_drm_mode_equal (const drmModeModeInfo *one, const drmModeModeInfo *two); diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c index d2a6c030e..c85f3fe82 100644 --- a/src/backends/native/meta-renderer-native.c +++ b/src/backends/native/meta-renderer-native.c @@ -67,12 +67,13 @@ enum { PROP_0, - PROP_KMS_FD, - PROP_KMS_FILE_PATH, + PROP_MONITOR_MANAGER, PROP_LAST }; +static GParamSpec *obj_props[PROP_LAST]; + typedef struct _MetaOnscreenNative { struct { @@ -112,8 +113,7 @@ struct _MetaRendererNative { MetaRenderer parent; - int kms_fd; - char *kms_file_path; + MetaMonitorManagerKms *monitor_manager_kms; MetaRendererNativeMode mode; @@ -224,11 +224,15 @@ free_current_bo (CoglOnscreen *onscreen) CoglRenderer *cogl_renderer = cogl_context->display->renderer; CoglRendererEGL *egl_renderer = cogl_renderer->winsys; MetaRendererNative *renderer_native = egl_renderer->platform; + MetaMonitorManagerKms *monitor_manager_kms = + renderer_native->monitor_manager_kms; + int kms_fd; + + kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); if (onscreen_native->gbm.current_fb_id) { - drmModeRmFB (renderer_native->kms_fd, - onscreen_native->gbm.current_fb_id); + drmModeRmFB (kms_fd, onscreen_native->gbm.current_fb_id); onscreen_native->gbm.current_fb_id = 0; } if (onscreen_native->gbm.current_bo) @@ -499,7 +503,12 @@ flip_closure_destroyed (MetaRendererView *view) case META_RENDERER_NATIVE_MODE_GBM: if (onscreen_native->gbm.next_fb_id) { - drmModeRmFB (renderer_native->kms_fd, onscreen_native->gbm.next_fb_id); + MetaMonitorManagerKms *monitor_manager_kms = + renderer_native->monitor_manager_kms; + int kms_fd; + + kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); + drmModeRmFB (kms_fd, onscreen_native->gbm.next_fb_id); gbm_surface_release_buffer (onscreen_native->gbm.surface, onscreen_native->gbm.next_bo); onscreen_native->gbm.next_bo = NULL; @@ -581,10 +590,8 @@ meta_onscreen_native_flip_crtc (MetaOnscreenNative *onscreen_native, MetaBackend *backend = meta_get_backend (); MetaRenderer *renderer = meta_backend_get_renderer (backend); MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); MetaMonitorManagerKms *monitor_manager_kms = - META_MONITOR_MANAGER_KMS (monitor_manager); + renderer_native->monitor_manager_kms; if (!meta_monitor_manager_kms_is_crtc_active (monitor_manager_kms, crtc)) @@ -618,7 +625,7 @@ meta_onscreen_native_flip_crtc (MetaOnscreenNative *onscreen_native, typedef struct _SetCrtcFbData { - MetaMonitorManager *monitor_manager; + MetaMonitorManagerKms *monitor_manager_kms; MetaLogicalMonitor *logical_monitor; uint32_t fb_id; } SetCrtcFbData; @@ -629,8 +636,7 @@ set_crtc_fb (MetaLogicalMonitor *logical_monitor, gpointer user_data) { SetCrtcFbData *data = user_data; - MetaMonitorManagerKms *monitor_manager_kms = - META_MONITOR_MANAGER_KMS (data->monitor_manager); + MetaMonitorManagerKms *monitor_manager_kms = data->monitor_manager_kms; int x, y; x = crtc->rect.x - logical_monitor->rect.x; @@ -648,10 +654,8 @@ meta_onscreen_native_set_crtc_modes (MetaOnscreenNative *onscreen_native) MetaBackend *backend = meta_get_backend (); MetaRenderer *renderer = meta_backend_get_renderer (backend); MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); MetaMonitorManagerKms *monitor_manager_kms = - META_MONITOR_MANAGER_KMS (monitor_manager); + renderer_native->monitor_manager_kms; MetaRendererView *view = onscreen_native->view; uint32_t fb_id = 0; MetaLogicalMonitor *logical_monitor; @@ -674,8 +678,8 @@ meta_onscreen_native_set_crtc_modes (MetaOnscreenNative *onscreen_native) if (logical_monitor) { SetCrtcFbData data = { - .monitor_manager = monitor_manager, - .fb_id = fb_id + .monitor_manager_kms = monitor_manager_kms, + .fb_id = fb_id }; meta_logical_monitor_foreach_crtc (logical_monitor, @@ -684,6 +688,8 @@ meta_onscreen_native_set_crtc_modes (MetaOnscreenNative *onscreen_native) } else { + MetaMonitorManager *monitor_manager = + META_MONITOR_MANAGER (monitor_manager_kms); GList *crtcs; GList *l; @@ -730,10 +736,13 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen) { CoglOnscreenEGL *egl_onscreen = onscreen->winsys; MetaOnscreenNative *onscreen_native = egl_onscreen->platform; - MetaBackend *backend = meta_get_backend (); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); MetaRendererView *view = onscreen_native->view; + CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen); + CoglContext *cogl_context = framebuffer->context; + CoglDisplay *cogl_display = cogl_context->display; + CoglRenderer *cogl_renderer = cogl_display->renderer; + CoglRendererEGL *egl_renderer = cogl_renderer->winsys; + MetaRendererNative *renderer_native = egl_renderer->platform; GClosure *flip_closure; MetaLogicalMonitor *logical_monitor; gboolean fb_in_use = FALSE; @@ -771,6 +780,8 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen) } else { + MetaMonitorManager *monitor_manager = + META_MONITOR_MANAGER (renderer_native->monitor_manager_kms); GList *crtcs; GList *l; @@ -793,9 +804,6 @@ meta_onscreen_native_flip_crtcs (CoglOnscreen *onscreen) */ if (fb_in_use && onscreen_native->pending_flips == 0) { - MetaRenderer *renderer = meta_backend_get_renderer (backend); - MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); - switch (renderer_native->mode) { case META_RENDERER_NATIVE_MODE_GBM: @@ -824,9 +832,12 @@ gbm_get_next_fb_id (CoglOnscreen *onscreen, MetaRendererNative *renderer_native = egl_renderer->platform; CoglOnscreenEGL *egl_onscreen = onscreen->winsys; MetaOnscreenNative *onscreen_native = egl_onscreen->platform; + MetaMonitorManagerKms *monitor_manager_kms = + renderer_native->monitor_manager_kms; uint32_t handle, stride; struct gbm_bo *next_bo; uint32_t next_fb_id; + int kms_fd; /* Now we need to set the CRTC to whatever is the front buffer */ next_bo = gbm_surface_lock_front_buffer (onscreen_native->gbm.surface); @@ -834,7 +845,9 @@ gbm_get_next_fb_id (CoglOnscreen *onscreen, stride = gbm_bo_get_stride (next_bo); handle = gbm_bo_get_handle (next_bo).u32; - if (drmModeAddFB (renderer_native->kms_fd, + kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); + + if (drmModeAddFB (kms_fd, cogl_framebuffer_get_width (COGL_FRAMEBUFFER (onscreen)), cogl_framebuffer_get_height (COGL_FRAMEBUFFER (onscreen)), 24, /* depth */ @@ -864,11 +877,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen *onscreen, MetaRendererNative *renderer_native = egl_renderer->platform; CoglOnscreenEGL *egl_onscreen = onscreen->winsys; MetaOnscreenNative *onscreen_native = egl_onscreen->platform; - MetaBackend *backend = meta_get_backend (); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); MetaMonitorManagerKms *monitor_manager_kms = - META_MONITOR_MANAGER_KMS (monitor_manager); + renderer_native->monitor_manager_kms; CoglFrameInfo *frame_info; frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos); @@ -1106,19 +1116,23 @@ init_dumb_fb (MetaRendererNative *renderer_native, int height, GError **error) { + MetaMonitorManagerKms *monitor_manager_kms = + renderer_native->monitor_manager_kms; struct drm_mode_create_dumb create_arg; struct drm_mode_destroy_dumb destroy_arg; struct drm_mode_map_dumb map_arg; uint32_t fb_id = 0; void *map; + int kms_fd; + + kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); create_arg = (struct drm_mode_create_dumb) { .bpp = 32, /* RGBX8888 */ .width = width, .height = height }; - if (drmIoctl (renderer_native->kms_fd, DRM_IOCTL_MODE_CREATE_DUMB, - &create_arg) != 0) + if (drmIoctl (kms_fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg) != 0) { g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, @@ -1133,7 +1147,7 @@ init_dumb_fb (MetaRendererNative *renderer_native, uint32_t pitches[4] = { create_arg.pitch, }; uint32_t offsets[4] = { 0 }; - if (drmModeAddFB2 (renderer_native->kms_fd, width, height, + if (drmModeAddFB2 (kms_fd, width, height, GBM_FORMAT_XRGB8888, handles, pitches, offsets, &fb_id, 0) != 0) @@ -1146,7 +1160,7 @@ init_dumb_fb (MetaRendererNative *renderer_native, if (renderer_native->no_add_fb2) { - if (drmModeAddFB (renderer_native->kms_fd, width, height, + if (drmModeAddFB (kms_fd, width, height, 24 /* depth of RGBX8888 */, 32 /* bpp of RGBX8888 */, create_arg.pitch, @@ -1164,7 +1178,7 @@ init_dumb_fb (MetaRendererNative *renderer_native, map_arg = (struct drm_mode_map_dumb) { .handle = create_arg.handle }; - if (drmIoctl (renderer_native->kms_fd, DRM_IOCTL_MODE_MAP_DUMB, + if (drmIoctl (kms_fd, DRM_IOCTL_MODE_MAP_DUMB, &map_arg) != 0) { g_set_error (error, G_IO_ERROR, @@ -1175,8 +1189,7 @@ init_dumb_fb (MetaRendererNative *renderer_native, } map = mmap (NULL, create_arg.size, PROT_WRITE, MAP_SHARED, - renderer_native->kms_fd, - map_arg.offset); + kms_fd, map_arg.offset); if (map == MAP_FAILED) { g_set_error (error, G_IO_ERROR, @@ -1195,13 +1208,13 @@ init_dumb_fb (MetaRendererNative *renderer_native, err_mmap: err_map_dumb: - drmModeRmFB (renderer_native->kms_fd, fb_id); + drmModeRmFB (kms_fd, fb_id); err_add_fb: destroy_arg = (struct drm_mode_destroy_dumb) { .handle = create_arg.handle }; - drmIoctl (renderer_native->kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); + drmIoctl (kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); err_ioctl: return FALSE; @@ -1211,7 +1224,10 @@ static void release_dumb_fb (MetaRendererNative *renderer_native, MetaOnscreenNative *onscreen_native) { + MetaMonitorManagerKms *monitor_manager_kms = + renderer_native->monitor_manager_kms; struct drm_mode_destroy_dumb destroy_arg; + int kms_fd; if (!onscreen_native->egl.dumb_fb.map) return; @@ -1220,13 +1236,14 @@ release_dumb_fb (MetaRendererNative *renderer_native, onscreen_native->egl.dumb_fb.map_size); onscreen_native->egl.dumb_fb.map = NULL; - drmModeRmFB (renderer_native->kms_fd, - onscreen_native->egl.dumb_fb.fb_id); + kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); + + drmModeRmFB (kms_fd, onscreen_native->egl.dumb_fb.fb_id); destroy_arg = (struct drm_mode_destroy_dumb) { .handle = onscreen_native->egl.dumb_fb.handle }; - drmIoctl (renderer_native->kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); + drmIoctl (kms_fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); } #endif /* HAVE_EGL_DEVICE */ @@ -1417,12 +1434,6 @@ meta_renderer_native_get_gbm (MetaRendererNative *renderer_native) return renderer_native->gbm.device; } -int -meta_renderer_native_get_kms_fd (MetaRendererNative *renderer_native) -{ - return renderer_native->kms_fd; -} - void meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native) { @@ -1532,11 +1543,8 @@ meta_renderer_native_set_legacy_view_size (MetaRendererNative *renderer_native, if (width != view_layout.width || height != view_layout.height) { - MetaBackend *backend = meta_get_backend (); - MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); MetaMonitorManagerKms *monitor_manager_kms = - META_MONITOR_MANAGER_KMS (monitor_manager); + renderer_native->monitor_manager_kms; CoglFramebuffer *framebuffer = clutter_stage_view_get_onscreen (stage_view); CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer); @@ -1669,19 +1677,16 @@ meta_onscreen_native_set_view (CoglOnscreen *onscreen, MetaRendererView * meta_renderer_native_create_legacy_view (MetaRendererNative *renderer_native) { - MetaBackend *backend = meta_get_backend (); MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); + META_MONITOR_MANAGER (renderer_native->monitor_manager_kms); CoglOnscreen *onscreen = NULL; + MetaBackend *backend = meta_get_backend (); ClutterBackend *clutter_backend = meta_backend_get_clutter_backend (backend); CoglContext *cogl_context = clutter_backend_get_cogl_context (clutter_backend); cairo_rectangle_int_t view_layout = { 0 }; MetaRendererView *view; GError *error = NULL; - if (!monitor_manager) - return NULL; - meta_monitor_manager_get_screen_size (monitor_manager, &view_layout.width, &view_layout.height); @@ -1742,9 +1747,10 @@ static MetaRendererView * meta_renderer_native_create_view (MetaRenderer *renderer, MetaLogicalMonitor *logical_monitor) { - MetaBackend *backend = meta_get_backend (); + MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer); MetaMonitorManager *monitor_manager = - meta_backend_get_monitor_manager (backend); + META_MONITOR_MANAGER (renderer_native->monitor_manager_kms); + MetaBackend *backend = meta_get_backend (); 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); @@ -1867,11 +1873,8 @@ meta_renderer_native_get_property (GObject *object, switch (prop_id) { - case PROP_KMS_FD: - g_value_set_int (value, renderer_native->kms_fd); - break; - case PROP_KMS_FILE_PATH: - g_value_set_string (value, renderer_native->kms_file_path); + case PROP_MONITOR_MANAGER: + g_value_set_object (value, renderer_native->monitor_manager_kms); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1889,11 +1892,8 @@ meta_renderer_native_set_property (GObject *object, switch (prop_id) { - case PROP_KMS_FD: - renderer_native->kms_fd = g_value_get_int (value); - break; - case PROP_KMS_FILE_PATH: - renderer_native->kms_file_path = g_strdup (g_value_get_string (value)); + case PROP_MONITOR_MANAGER: + renderer_native->monitor_manager_kms = g_value_get_object (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -1908,8 +1908,6 @@ meta_renderer_native_finalize (GObject *object) g_clear_pointer (&renderer_native->gbm.device, gbm_device_destroy); - g_free (renderer_native->kms_file_path); - G_OBJECT_CLASS (meta_renderer_native_parent_class)->finalize (object); } @@ -1917,10 +1915,13 @@ static gboolean init_gbm (MetaRendererNative *renderer_native, GError **error) { + MetaMonitorManagerKms *monitor_manager_kms = + renderer_native->monitor_manager_kms; MetaBackend *backend = meta_get_backend (); MetaEgl *egl = meta_backend_get_egl (backend); struct gbm_device *gbm_device; EGLDisplay egl_display; + int kms_fd; if (!meta_egl_has_extensions (egl, EGL_NO_DISPLAY, NULL, "EGL_MESA_platform_gbm", @@ -1932,7 +1933,9 @@ init_gbm (MetaRendererNative *renderer_native, return FALSE; } - gbm_device = gbm_create_device (renderer_native->kms_fd); + kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); + + gbm_device = gbm_create_device (kms_fd); if (!gbm_device) { g_set_error (error, G_IO_ERROR, @@ -1983,11 +1986,14 @@ static EGLDeviceEXT find_egl_device (MetaRendererNative *renderer_native, GError **error) { + MetaMonitorManagerKms *monitor_manager_kms = + renderer_native->monitor_manager_kms; MetaBackend *backend = meta_get_backend (); MetaEgl *egl = meta_backend_get_egl (backend); char **missing_extensions; EGLint num_devices; EGLDeviceEXT *devices; + const char *kms_file_path; EGLDeviceEXT device; EGLint i; @@ -2020,6 +2026,8 @@ find_egl_device (MetaRendererNative *renderer_native, return EGL_NO_DEVICE_EXT; } + kms_file_path = meta_monitor_manager_kms_get_file_path (monitor_manager_kms); + device = EGL_NO_DEVICE_EXT; for (i = 0; i < num_devices; i++) { @@ -2031,7 +2039,7 @@ find_egl_device (MetaRendererNative *renderer_native, if (!egl_device_drm_path) continue; - if (g_str_equal (egl_device_drm_path, renderer_native->kms_file_path)) + if (g_str_equal (egl_device_drm_path, kms_file_path)) { device = devices[i]; break; @@ -2058,8 +2066,11 @@ get_egl_device_display (MetaRendererNative *renderer_native, { MetaBackend *backend = meta_get_backend (); MetaEgl *egl = meta_backend_get_egl (backend); + MetaMonitorManagerKms *monitor_manager_kms = + renderer_native->monitor_manager_kms; + int kms_fd = meta_monitor_manager_kms_get_fd (monitor_manager_kms); EGLint platform_attribs[] = { - EGL_DRM_MASTER_FD_EXT, renderer_native->kms_fd, + EGL_DRM_MASTER_FD_EXT, kms_fd, EGL_NONE }; @@ -2204,34 +2215,25 @@ 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; - g_object_class_install_property (object_class, - PROP_KMS_FD, - g_param_spec_int ("kms-fd", - "KMS fd", - "The KMS file descriptor", - 0, G_MAXINT, 0, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, - PROP_KMS_FILE_PATH, - g_param_spec_string ("kms-file-path", - "KMS file path", - "The KMS file path", - NULL, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); + obj_props[PROP_MONITOR_MANAGER] = + g_param_spec_object ("monitor-manager", + "monitor-manager", + "MetaMonitorManagerKms", + META_TYPE_MONITOR_MANAGER_KMS, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + g_object_class_install_properties (object_class, PROP_LAST, obj_props); } MetaRendererNative * -meta_renderer_native_new (int kms_fd, - const char *kms_file_path, - GError **error) +meta_renderer_native_new (MetaMonitorManagerKms *monitor_manager_kms, + GError **error) { MetaRendererNative *renderer_native; renderer_native = g_object_new (META_TYPE_RENDERER_NATIVE, - "kms-fd", kms_fd, - "kms-file-path", kms_file_path, + "monitor-manager", monitor_manager_kms, NULL); if (!g_initable_init (G_INITABLE (renderer_native), NULL, error)) { diff --git a/src/backends/native/meta-renderer-native.h b/src/backends/native/meta-renderer-native.h index 24cfdd35b..ef774cc28 100644 --- a/src/backends/native/meta-renderer-native.h +++ b/src/backends/native/meta-renderer-native.h @@ -29,6 +29,7 @@ #include #include "backends/meta-renderer.h" +#include "backends/native/meta-monitor-manager-kms.h" #define META_TYPE_RENDERER_NATIVE (meta_renderer_native_get_type ()) G_DECLARE_FINAL_TYPE (MetaRendererNative, meta_renderer_native, @@ -43,16 +44,13 @@ typedef enum _MetaRendererNativeMode #endif } MetaRendererNativeMode; -MetaRendererNative *meta_renderer_native_new (int kms_fd, - const char *kms_file_path, - GError **error); +MetaRendererNative * meta_renderer_native_new (MetaMonitorManagerKms *monitor_manager_kms, + GError **error); MetaRendererNativeMode meta_renderer_native_get_mode (MetaRendererNative *renderer_native); struct gbm_device * meta_renderer_native_get_gbm (MetaRendererNative *renderer_native); -int meta_renderer_native_get_kms_fd (MetaRendererNative *renderer_native); - void meta_renderer_native_queue_modes_reset (MetaRendererNative *renderer_native); gboolean meta_renderer_native_set_legacy_view_size (MetaRendererNative *renderer_native, diff --git a/src/backends/x11/cm/meta-backend-x11-cm.c b/src/backends/x11/cm/meta-backend-x11-cm.c index 06825f319..1cb914dd3 100644 --- a/src/backends/x11/cm/meta-backend-x11-cm.c +++ b/src/backends/x11/cm/meta-backend-x11-cm.c @@ -99,7 +99,8 @@ meta_backend_x11_cm_create_renderer (MetaBackend *backend, } static MetaMonitorManager * -meta_backend_x11_cm_create_monitor_manager (MetaBackend *backend) +meta_backend_x11_cm_create_monitor_manager (MetaBackend *backend, + GError **error) { return g_object_new (META_TYPE_MONITOR_MANAGER_XRANDR, NULL); } diff --git a/src/backends/x11/nested/meta-backend-x11-nested.c b/src/backends/x11/nested/meta-backend-x11-nested.c index 644c270e5..900c97fed 100644 --- a/src/backends/x11/nested/meta-backend-x11-nested.c +++ b/src/backends/x11/nested/meta-backend-x11-nested.c @@ -39,7 +39,8 @@ meta_backend_x11_nested_create_renderer (MetaBackend *backend, } static MetaMonitorManager * -meta_backend_x11_nested_create_monitor_manager (MetaBackend *backend) +meta_backend_x11_nested_create_monitor_manager (MetaBackend *backend, + GError **error) { return g_object_new (META_TYPE_MONITOR_MANAGER_DUMMY, NULL); } diff --git a/src/tests/meta-backend-test.c b/src/tests/meta-backend-test.c index 4abe0b739..ef597ad01 100644 --- a/src/tests/meta-backend-test.c +++ b/src/tests/meta-backend-test.c @@ -36,7 +36,8 @@ meta_backend_test_init (MetaBackendTest *backend_test) } static MetaMonitorManager * -meta_backend_test_create_monitor_manager (MetaBackend *backend) +meta_backend_test_create_monitor_manager (MetaBackend *backend, + GError **error) { return g_object_new (META_TYPE_MONITOR_MANAGER_TEST, NULL); }