alaurie / rpms / plymouth

Forked from rpms/plymouth 4 days ago
Clone

Blame SOURCES/0002-ply-device-manager-Treat-SimpleDRM-drm-devices-as-fb.patch

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