alaurie / rpms / plymouth

Forked from rpms/plymouth 4 days ago
Clone

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

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