mirror of
https://gitlab.freedesktop.org/plymouth/plymouth.git
synced 2026-05-08 08:58:05 +02:00
ply-device-manager: Handle change events for monitor hotplugging
Not only handle add but also change events for drm-subsys devices, change events are generated when the hardware detect a new monitor has been plugged in. This is esp. important with modern DisplayPort MST docking stations where discovery / enumeration can take so long that the connected displays are not enumerated by the kernel yet when the drm plugin first calls drmModeGetResources(). Causing the monitors on these docks to sometimes not show plymouth during boot (based on various timing parameters). Note that if during the add event drm-renderer could not be bound, this commit tries to re-bind the DRM renderer on change events in case a monitor got plugged into a GPU which did not have anything connected before. This often happens with the second GPU in a laptop with a hybrid GPU setup. BugLink: https://bugzilla.redhat.com/show_bug.cgi?id=1652279 Signed-off-by: Hans de Goede <hdegoede@redhat.com>
This commit is contained in:
parent
f9e376797a
commit
e54f6a4731
1 changed files with 38 additions and 2 deletions
|
|
@ -51,6 +51,9 @@ static bool create_devices_for_terminal_and_renderer_type (ply_device_manager_t
|
|||
const char *device_path,
|
||||
ply_terminal_t *terminal,
|
||||
ply_renderer_type_t renderer_type);
|
||||
static void create_pixel_displays_for_renderer (ply_device_manager_t *manager,
|
||||
ply_renderer_t *renderer);
|
||||
|
||||
struct _ply_device_manager
|
||||
{
|
||||
ply_device_manager_flags_t flags;
|
||||
|
|
@ -371,6 +374,39 @@ create_devices_for_subsystem (ply_device_manager_t *manager,
|
|||
return found_device;
|
||||
}
|
||||
|
||||
static void
|
||||
on_drm_udev_add_or_change (ply_device_manager_t *manager,
|
||||
const char *action,
|
||||
struct udev_device *device)
|
||||
{
|
||||
const char *device_path = udev_device_get_devnode (device);
|
||||
ply_renderer_t *renderer;
|
||||
bool changed;
|
||||
|
||||
if (device_path == NULL)
|
||||
return;
|
||||
|
||||
renderer = ply_hashtable_lookup (manager->renderers, (void *) device_path);
|
||||
if (renderer == NULL) {
|
||||
/* We also try to create the renderer again on change events,
|
||||
* renderer creation fails when no outputs are connected and
|
||||
* this may have changed.
|
||||
*/
|
||||
create_devices_for_udev_device (manager, device);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Renderer exists, bail if this is not a change event */
|
||||
if (strcmp (action, "change"))
|
||||
return;
|
||||
|
||||
changed = ply_renderer_handle_change_event (renderer);
|
||||
if (changed) {
|
||||
free_displays_for_renderer (manager, renderer);
|
||||
create_pixel_displays_for_renderer (manager, renderer);
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
on_udev_event (ply_device_manager_t *manager)
|
||||
{
|
||||
|
|
@ -388,7 +424,7 @@ on_udev_event (ply_device_manager_t *manager)
|
|||
if (action == NULL)
|
||||
return false;
|
||||
|
||||
if (strcmp (action, "add") == 0) {
|
||||
if (strcmp (action, "add") == 0 || strcmp (action, "change") == 0) {
|
||||
const char *subsystem;
|
||||
|
||||
subsystem = udev_device_get_subsystem (device);
|
||||
|
|
@ -397,7 +433,7 @@ on_udev_event (ply_device_manager_t *manager)
|
|||
if (manager->local_console_managed && manager->local_console_is_text)
|
||||
ply_trace ("ignoring since we're already using text splash for local console");
|
||||
else
|
||||
create_devices_for_udev_device (manager, device);
|
||||
on_drm_udev_add_or_change (manager, action, device);
|
||||
} else {
|
||||
ply_trace ("ignoring since we only handle subsystem %s devices after timeout", subsystem);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue