monitor-manager-kms: Don't listen on hotplugs when paused

When mutter is paused (i.e. not the DRM master), stop listening on
hotplug events. Instead read the current state and set modes when
resumed.

This avoids a race condition in the drm API which currently only
manages to properly deal with one application querying the EDID state
at the same time when there are multiple mutter instances running at
the same time (e.g. gnome-shell driving gdm at the same time as
gnome-shell as the session instance).

https://bugzilla.gnome.org/show_bug.cgi?id=779837
This commit is contained in:
Jonas Ådahl 2017-03-10 16:29:11 +08:00
parent 5aa02c0378
commit db14e6099e
3 changed files with 32 additions and 3 deletions

View File

@ -537,21 +537,31 @@ meta_activate_session (void)
void
meta_backend_native_pause (MetaBackendNative *native)
{
MetaBackend *backend = META_BACKEND (native);
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaMonitorManagerKms *monitor_manager_kms =
META_MONITOR_MANAGER_KMS (monitor_manager);
clutter_evdev_release_devices ();
clutter_egl_freeze_master_clock ();
meta_monitor_manager_kms_pause (monitor_manager_kms);
}
void meta_backend_native_resume (MetaBackendNative *native)
{
MetaBackend *backend = META_BACKEND (native);
MetaRenderer *renderer;
MetaMonitorManager *monitor_manager =
meta_backend_get_monitor_manager (backend);
MetaMonitorManagerKms *monitor_manager_kms =
META_MONITOR_MANAGER_KMS (monitor_manager);
MetaCursorRenderer *cursor_renderer;
MetaCursorRendererNative *cursor_renderer_native;
ClutterActor *stage;
MetaIdleMonitor *idle_monitor;
renderer = meta_backend_get_renderer (backend);
meta_renderer_native_queue_modes_reset (META_RENDERER_NATIVE (renderer));
meta_monitor_manager_kms_resume (monitor_manager_kms);
clutter_evdev_reclaim_devices ();
clutter_egl_thaw_master_clock ();

View File

@ -1783,6 +1783,21 @@ meta_monitor_manager_kms_disconnect_uevent_handler (MetaMonitorManagerKms *manag
manager_kms->uevent_handler_id = 0;
}
void
meta_monitor_manager_kms_pause (MetaMonitorManagerKms *manager_kms)
{
meta_monitor_manager_kms_disconnect_uevent_handler (manager_kms);
}
void
meta_monitor_manager_kms_resume (MetaMonitorManagerKms *manager_kms)
{
MetaMonitorManager *manager = META_MONITOR_MANAGER (manager_kms);
meta_monitor_manager_kms_connect_uevent_handler (manager_kms);
handle_hotplug_event (manager);
}
static void
meta_monitor_manager_kms_init (MetaMonitorManagerKms *manager_kms)
{

View File

@ -58,4 +58,8 @@ gboolean meta_monitor_manager_kms_flip_crtc (MetaMonitorManagerKms *manager_kms,
void meta_monitor_manager_kms_wait_for_flip (MetaMonitorManagerKms *manager_kms);
void meta_monitor_manager_kms_pause (MetaMonitorManagerKms *manager_kms);
void meta_monitor_manager_kms_resume (MetaMonitorManagerKms *manager_kms);
#endif /* META_MONITOR_MANAGER_KMS_H */