summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backends/meta-backend-private.h3
-rw-r--r--src/backends/meta-backend.c12
-rw-r--r--src/backends/native/meta-backend-native.c31
-rw-r--r--src/backends/native/meta-backend-native.h3
-rw-r--r--src/backends/native/meta-cursor-renderer-native.c6
-rw-r--r--src/backends/native/meta-launcher.c310
-rw-r--r--src/backends/native/meta-launcher.h10
-rw-r--r--src/backends/native/meta-monitor-manager-kms.c272
-rw-r--r--src/backends/native/meta-monitor-manager-kms.h2
-rw-r--r--src/backends/native/meta-renderer-native.c190
-rw-r--r--src/backends/native/meta-renderer-native.h8
-rw-r--r--src/backends/x11/cm/meta-backend-x11-cm.c3
-rw-r--r--src/backends/x11/nested/meta-backend-x11-nested.c3
-rw-r--r--src/tests/meta-backend-test.c3
14 files changed, 468 insertions, 388 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,41 +1093,216 @@ meta_monitor_manager_kms_get_default_layout_mode (MetaMonitorManager *manager)
return META_LOGICAL_MONITOR_LAYOUT_MODE_PHYSICAL;
}
-static void
-meta_monitor_manager_kms_dispose (GObject *object)
+static guint
+count_devices_with_connectors (const char *seat_id,
+ GList *devices)
{
- MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (object);
+ g_autoptr (GHashTable) cards = NULL;
+ GList *l;
- g_clear_object (&manager_kms->udev);
+ 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;
- G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->dispose (object);
+ /* 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 void
-meta_monitor_manager_kms_finalize (GObject *object)
+static char *
+get_primary_gpu_path (MetaMonitorManagerKms *manager_kms)
{
- 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);
+ g_autoptr (GUdevEnumerator) enumerator = NULL;
+ const char *seat_id;
+ char *path = NULL;
+ GList *devices;
+ GList *l;
- free_resources (manager_kms);
- g_source_destroy ((GSource *) manager_kms->source);
+ enumerator = g_udev_enumerator_new (manager_kms->udev);
- G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->finalize (object);
+ 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 void
-meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
+static gboolean
+open_primary_gpu (MetaMonitorManagerKms *manager_kms,
+ int *fd_out,
+ char **kms_file_path_out,
+ GError **error)
{
MetaBackend *backend = meta_get_backend ();
- MetaRenderer *renderer = meta_backend_get_renderer (backend);
- MetaRendererNative *renderer_native = META_RENDERER_NATIVE (renderer);
- GSource *source;
+ 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;
+ }
- manager_kms->fd = meta_renderer_native_get_kms_fd (renderer_native);
+ fd = meta_launcher_open_restricted (launcher, path, error);
+ if (fd == -1)
+ return FALSE;
- drmSetClientCap (manager_kms->fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
+ *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));
@@ -1120,6 +1312,48 @@ meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
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)
+{
+ 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_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);
+
+ G_OBJECT_CLASS (meta_monitor_manager_kms_parent_class)->finalize (object);
+}
+
+static void
+meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
+{
+ 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 <xf86drmMode.h>
#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);
}