diff options
author | Hans de Goede <hdegoede@redhat.com> | 2019-08-05 14:08:08 +0200 |
---|---|---|
committer | Jonas Ã…dahl <jadahl@gmail.com> | 2019-08-15 20:38:28 +0000 |
commit | f3660dc60e76b13e35f361a1ea6816f8b0af66d8 (patch) | |
tree | d161a71ec68741d94f15a6fa72e981e5e430aebc /src | |
parent | 0eb355e29d0a0644dcf30732f07c56b83ac9fd1c (diff) | |
download | mutter-f3660dc60e76b13e35f361a1ea6816f8b0af66d8.tar.gz |
kms: Deal with GPUs being unplugged
Add meta-kms and meta-monitor-manager-kms listener for the udev
device-removed signal and on this signal update the device state /
re-enumerate the monitors, so that the monitors properly get updated
to disconnected state on GPU removal.
We really should also have meta-backend-native remove the GPU itself
from our list of GPU objects. But that is more involved, see:
https://gitlab.gnome.org/GNOME/mutter/issues/710
This commit at least gets us to a point where we properly update the
list of monitors when a GPU gets unplugged; and where we no longer
crash the first time the user changes the monitor configuration after
a GPU was unplugged.
Specifically before this commit we would hit the first g_error () in
meta_renderer_native_create_view () as soon as some monitor
(re)configuration is done after a GPU was unplugged.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/713
Diffstat (limited to 'src')
-rw-r--r-- | src/backends/native/meta-kms.c | 25 | ||||
-rw-r--r-- | src/backends/native/meta-monitor-manager-kms.c | 14 |
2 files changed, 37 insertions, 2 deletions
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c index 641aaa198..13dc396d3 100644 --- a/src/backends/native/meta-kms.c +++ b/src/backends/native/meta-kms.c @@ -149,6 +149,7 @@ struct _MetaKms MetaBackend *backend; guint hotplug_handler_id; + guint removed_handler_id; MetaKmsImpl *impl; gboolean in_impl_task; @@ -474,8 +475,7 @@ meta_kms_update_states_sync (MetaKms *kms, } static void -on_udev_hotplug (MetaUdev *udev, - MetaKms *kms) +handle_hotplug_event (MetaKms *kms) { g_autoptr (GError) error = NULL; @@ -483,6 +483,21 @@ on_udev_hotplug (MetaUdev *udev, g_warning ("Updating KMS state failed: %s", error->message); } +static void +on_udev_hotplug (MetaUdev *udev, + MetaKms *kms) +{ + handle_hotplug_event (kms); +} + +static void +on_udev_device_removed (MetaUdev *udev, + GUdevDevice *device, + MetaKms *kms) +{ + handle_hotplug_event (kms); +} + MetaBackend * meta_kms_get_backend (MetaKms *kms) { @@ -525,6 +540,9 @@ meta_kms_new (MetaBackend *backend, kms->hotplug_handler_id = g_signal_connect (udev, "hotplug", G_CALLBACK (on_udev_hotplug), kms); + kms->removed_handler_id = + g_signal_connect (udev, "device-removed", + G_CALLBACK (on_udev_device_removed), kms); return kms; } @@ -548,6 +566,9 @@ meta_kms_finalize (GObject *object) if (kms->hotplug_handler_id) g_signal_handler_disconnect (udev, kms->hotplug_handler_id); + if (kms->removed_handler_id) + g_signal_handler_disconnect (udev, kms->removed_handler_id); + G_OBJECT_CLASS (meta_kms_parent_class)->finalize (object); } diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c index 9bac13576..26c2ddb61 100644 --- a/src/backends/native/meta-monitor-manager-kms.c +++ b/src/backends/native/meta-monitor-manager-kms.c @@ -76,6 +76,7 @@ struct _MetaMonitorManagerKms MetaMonitorManager parent_instance; guint hotplug_handler_id; + guint removed_handler_id; }; struct _MetaMonitorManagerKmsClass @@ -485,6 +486,14 @@ on_udev_hotplug (MetaUdev *udev, } static void +on_udev_device_removed (MetaUdev *udev, + GUdevDevice *device, + MetaMonitorManager *manager) +{ + handle_hotplug_event (manager); +} + +static void meta_monitor_manager_kms_connect_hotplug_handler (MetaMonitorManagerKms *manager_kms) { MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms); @@ -494,6 +503,9 @@ meta_monitor_manager_kms_connect_hotplug_handler (MetaMonitorManagerKms *manager manager_kms->hotplug_handler_id = g_signal_connect_after (udev, "hotplug", G_CALLBACK (on_udev_hotplug), manager); + manager_kms->removed_handler_id = + g_signal_connect_after (udev, "device-removed", + G_CALLBACK (on_udev_device_removed), manager); } static void @@ -505,6 +517,8 @@ meta_monitor_manager_kms_disconnect_hotplug_handler (MetaMonitorManagerKms *mana g_signal_handler_disconnect (udev, manager_kms->hotplug_handler_id); manager_kms->hotplug_handler_id = 0; + g_signal_handler_disconnect (udev, manager_kms->removed_handler_id); + manager_kms->removed_handler_id = 0; } void |