backends/native: React to GPU hotplug
If a GPU is added at runtime, we should connect to it and manage its outputs.
This commit is contained in:
parent
a6178990cd
commit
ad7d6e4a37
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user