[mutter] backends/native: React to GPU hotplug
- From: Jonas Ådahl <jadahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [mutter] backends/native: React to GPU hotplug
- Date: Wed, 21 Nov 2018 13:38:57 +0000 (UTC)
commit ad7d6e4a37a6258a5de876a85859f7f57415dffa
Author: Emilio Pozuelo Monfort <emilio pozuelo collabora co uk>
Date: Mon Sep 17 13:03:18 2018 +0200
backends/native: React to GPU hotplug
If a GPU is added at runtime, we should connect to it and manage
its outputs.
src/backends/native/meta-monitor-manager-kms.c | 74 ++++++++++++++++++++++++++
src/backends/native/meta-renderer-native.c | 61 +++++++++++++++++----
2 files changed, 125 insertions(+), 10 deletions(-)
---
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 3209bff94..48b2d374d 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -2,6 +2,7 @@
/*
* Copyright (C) 2013 Red Hat Inc.
+ * Copyright (C) 2018 DisplayLink (UK) Ltd.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -50,6 +51,15 @@
#define DRM_CARD_UDEV_DEVICE_TYPE "drm_minor"
+enum
+{
+ GPU_ADDED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
typedef struct
{
GSource source;
@@ -371,6 +381,43 @@ handle_hotplug_event (MetaMonitorManager *manager)
meta_monitor_manager_on_hotplug (manager);
}
+static void
+handle_gpu_hotplug (MetaMonitorManagerKms *manager_kms,
+ GUdevDevice *device)
+{
+ MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
+ g_autoptr (GError) error = NULL;
+ const char *gpu_path;
+ MetaGpuKms *gpu_kms;
+ GList *gpus, *l;
+
+ gpu_path = g_udev_device_get_device_file (device);
+
+ gpus = meta_monitor_manager_get_gpus (manager);
+ for (l = gpus; l; l = l->next)
+ {
+ MetaGpuKms *gpu_kms = l->data;
+
+ if (!g_strcmp0 (gpu_path, meta_gpu_kms_get_file_path (gpu_kms)))
+ {
+ g_warning ("Failed to hotplug secondary gpu '%s': %s",
+ gpu_path, "device already present");
+ return;
+ }
+ }
+
+ gpu_kms = meta_gpu_kms_new (manager_kms, gpu_path, &error);
+ if (!gpu_kms)
+ {
+ g_warning ("Failed to hotplug secondary gpu '%s': %s",
+ gpu_path, error->message);
+ return;
+ }
+ meta_monitor_manager_add_gpu (manager, META_GPU (gpu_kms));
+
+ g_signal_emit (manager_kms, signals[GPU_ADDED], 0, gpu_kms);
+}
+
static void
on_uevent (GUdevClient *client,
const char *action,
@@ -380,6 +427,25 @@ on_uevent (GUdevClient *client,
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (user_data);
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
+ if (g_str_equal (action, "add") &&
+ g_udev_device_get_device_file (device) != NULL)
+ {
+ MetaBackend *backend = meta_monitor_manager_get_backend (manager);
+ MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
+ MetaLauncher *launcher = meta_backend_native_get_launcher (backend_native);
+ const char *device_seat;
+ const char *seat_id;
+
+ device_seat = g_udev_device_get_property (device, "ID_SEAT");
+ seat_id = meta_launcher_get_seat_id (launcher);
+
+ if (!device_seat)
+ device_seat = "seat0";
+
+ if (!g_strcmp0 (seat_id, device_seat))
+ handle_gpu_hotplug (manager_kms, device);
+ }
+
if (!g_udev_device_get_property_as_boolean (device, "HOTPLUG"))
return;
@@ -754,4 +820,12 @@ meta_monitor_manager_kms_class_init (MetaMonitorManagerKmsClass *klass)
manager_class->get_capabilities = meta_monitor_manager_kms_get_capabilities;
manager_class->get_max_screen_size = meta_monitor_manager_kms_get_max_screen_size;
manager_class->get_default_layout_mode = meta_monitor_manager_kms_get_default_layout_mode;
+
+ signals[GPU_ADDED] =
+ g_signal_new ("gpu-added",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 1, META_TYPE_GPU_KMS);
}
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index ab7a2ee40..6277dda20 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -3015,6 +3015,11 @@ meta_renderer_native_get_property (GObject *object,
}
}
+static void
+on_gpu_added (MetaMonitorManager *monitor_manager,
+ MetaGpuKms *gpu_kms,
+ MetaRendererNative *renderer_native);
+
static void
meta_renderer_native_set_property (GObject *object,
guint prop_id,
@@ -3491,6 +3496,48 @@ meta_renderer_native_create_renderer_gpu_data (MetaRendererNative *renderer_nat
return NULL;
}
+static gboolean
+create_renderer_gpu_data (MetaRendererNative *renderer_native,
+ MetaGpuKms *gpu_kms,
+ GError **error)
+{
+ MetaRendererNativeGpuData *renderer_gpu_data;
+
+ renderer_gpu_data =
+ meta_renderer_native_create_renderer_gpu_data (renderer_native,
+ gpu_kms,
+ error);
+ if (!renderer_gpu_data)
+ return FALSE;
+
+ g_hash_table_insert (renderer_native->gpu_datas,
+ gpu_kms,
+ renderer_gpu_data);
+
+ return TRUE;
+}
+
+static void
+on_gpu_added (MetaMonitorManager *monitor_manager,
+ MetaGpuKms *gpu_kms,
+ MetaRendererNative *renderer_native)
+{
+ MetaBackend *backend = meta_monitor_manager_get_backend (monitor_manager);
+ 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);
+ GError *error = NULL;
+
+ if (!create_renderer_gpu_data (renderer_native, gpu_kms, &error))
+ {
+ g_warning ("on_gpu_added: could not create gpu_data for gpu %s: %s",
+ meta_gpu_kms_get_file_path (gpu_kms), error->message);
+ g_clear_error (&error);
+ }
+
+ _cogl_winsys_egl_ensure_current (cogl_display);
+}
+
static gboolean
meta_renderer_native_initable_init (GInitable *initable,
GCancellable *cancellable,
@@ -3508,18 +3555,9 @@ meta_renderer_native_initable_init (GInitable *initable,
for (l = gpus; l; l = l->next)
{
MetaGpuKms *gpu_kms = META_GPU_KMS (l->data);
- MetaRendererNativeGpuData *renderer_gpu_data;
- renderer_gpu_data =
- meta_renderer_native_create_renderer_gpu_data (renderer_native,
- gpu_kms,
- error);
- if (!renderer_gpu_data)
+ if (!create_renderer_gpu_data (renderer_native, gpu_kms, error))
return FALSE;
-
- g_hash_table_insert (renderer_native->gpu_datas,
- gpu_kms,
- renderer_gpu_data);
}
return TRUE;
@@ -3555,6 +3593,9 @@ meta_renderer_native_constructed (GObject *object)
settings, META_EXPERIMENTAL_FEATURE_KMS_MODIFIERS))
renderer_native->use_modifiers = TRUE;
+ g_signal_connect (renderer_native->monitor_manager_kms, "gpu-added",
+ G_CALLBACK (on_gpu_added), renderer_native);
+
G_OBJECT_CLASS (meta_renderer_native_parent_class)->constructed (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]