From ccb1a425efa1a21ba0d6730b8eba030c5f1d4ada Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Mon, 28 Feb 2022 16:07:11 +0100
Subject: [PATCH 2/6] ply-device-manager: Treat SimpleDRM drm devices as fbdev
devices
Simple-framebuffer devices driven by simpledrm lack information
like panel-rotation info and physical size, causing the splash
to briefly render on its side / without HiDPI scaling, switching
to the correct rendering when the native driver loads.
To avoid this treat simpledrm devices as fbdev devices and only
use them after the timeout.
Also adds 2 exceptions to this:
1. If nomodeset is passed on the kernel commandline then no native
drivers will load, so in this case it is best to immediately use
SimpleDRM devices when they are detected.
2. On some devics the firmware leave the panel black at boot. In this
case it is desirable to show the splash to the user ASAP so that there
is some visual feedback that the device is booting. Add a support for a
"plymouth.use-simpledrm" kernel cmdline option to show the splash
immediately on SimpleDRM devices rather then waiting for the native
driver to load.
Closes #167
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
src/libply-splash-core/ply-device-manager.c | 39 +++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/src/libply-splash-core/ply-device-manager.c b/src/libply-splash-core/ply-device-manager.c
index aed7bac..b2484b4 100644
--- a/src/libply-splash-core/ply-device-manager.c
+++ b/src/libply-splash-core/ply-device-manager.c
@@ -378,78 +378,117 @@ create_devices_for_subsystem (ply_device_manager_t *manager,
static void
on_drm_udev_add_or_change (ply_device_manager_t *manager,
const char *action,
const char *device_path,
struct udev_device *device)
{
ply_renderer_t *renderer;
bool changed;
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
+verify_drm_device (struct udev_device *device)
+{
+ const char *id_path;
+
+ /*
+ * Simple-framebuffer devices driven by simpledrm lack information
+ * like panel-rotation info and physical size, causing the splash
+ * to briefly render on its side / without HiDPI scaling, switching
+ * to the correct rendering when the native driver loads.
+ * To avoid this treat simpledrm devices as fbdev devices and only
+ * use them after the timeout.
+ */
+ id_path = udev_device_get_property_value (device, "ID_PATH");
+ if (!ply_string_has_prefix (id_path, "platform-simple-framebuffer"))
+ return true; /* Not a SimpleDRM device */
+
+ /*
+ * With nomodeset, no native drivers will load, so SimpleDRM devices
+ * should be used immediately.
+ */
+ if (ply_kernel_command_line_has_argument ("nomodeset"))
+ return true;
+
+ /*
+ * Some firmwares leave the panel black at boot. Allow enabling SimpleDRM
+ * use from the cmdline to show something to the user ASAP.
+ */
+ if (ply_kernel_command_line_has_argument ("plymouth.use-simpledrm"))
+ return true;
+
+ return false;
+}
+
static bool
verify_add_or_change (ply_device_manager_t *manager,
const char *action,
const char *device_path,
struct udev_device *device)
{
const char *subsystem = udev_device_get_subsystem (device);
if (strcmp (action, "add") && strcmp (action, "change"))
return false;
subsystem = udev_device_get_subsystem (device);
if (strcmp (subsystem, SUBSYSTEM_DRM) == 0) {
if (manager->local_console_managed && manager->local_console_is_text) {
ply_trace ("ignoring since we're already using text splash for local console");
return false;
}
+
+ if (!verify_drm_device (device)) {
+ ply_trace ("ignoring since we only handle SimpleDRM devices after timeout");
+ return false;
+ }
} else {
ply_trace ("ignoring since we only handle subsystem %s devices after timeout", subsystem);
return false;
}
return true;
}
static bool
duplicate_device_path (ply_list_t *events, const char *device_path)
{
struct udev_device *device;
ply_list_node_t *node;
for (node = ply_list_get_first_node (events);
node; node = ply_list_get_next_node (events, node)) {
device = ply_list_node_get_data (node);
if (strcmp (udev_device_get_devnode (device), device_path) == 0)
return true;
}
return false;
}
static void
process_udev_add_or_change_events (ply_device_manager_t *manager, ply_list_t *events)
{
const char *action, *device_path;
struct udev_device *device;
--
2.37.0.rc1