Merge branch 'simpledrm-early-probe' into 'main'

ply-device-manager: Create renderer for simpledrm devices right away

See merge request plymouth/plymouth!323
This commit is contained in:
Hans de Goede 2024-06-07 18:08:07 +00:00
commit 3ce6441aa0
5 changed files with 88 additions and 27 deletions

View file

@ -339,11 +339,15 @@ remove_input_device_from_renderers (ply_device_manager_t *manager,
ply_hashtable_foreach (manager->renderers, (ply_hashtable_foreach_func_t *) on_each_input_device_remove_from_renderer, input_device);
}
static bool
syspath_is_simpledrm (const char *syspath)
{
return ply_string_has_suffix (syspath, "simple-framebuffer.0/drm/card0");
}
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
@ -352,8 +356,7 @@ verify_drm_device (struct udev_device *device)
* 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"))
if (!syspath_is_simpledrm (udev_device_get_syspath (device)))
return true; /* Not a SimpleDRM device */
/*
@ -377,7 +380,7 @@ static bool
create_devices_for_udev_device (ply_device_manager_t *manager,
struct udev_device *device)
{
const char *device_path, *device_sysname;
const char *device_path, *device_sysname, *device_syspath;
bool created = false;
bool force_fb = false;
@ -386,6 +389,7 @@ create_devices_for_udev_device (ply_device_manager_t *manager,
device_path = udev_device_get_devnode (device);
device_sysname = udev_device_get_sysname (device);
device_syspath = udev_device_get_syspath (device);
if (device_path != NULL) {
const char *subsystem;
@ -399,8 +403,15 @@ create_devices_for_udev_device (ply_device_manager_t *manager,
ply_trace ("ignoring since we only handle SimpleDRM devices after timeout");
return false;
}
if (ply_string_has_prefix (device_path, "/dev/dri/render")) {
ply_trace ("ignoring since it is a render node");
return false;
}
ply_trace ("found DRM device %s", device_path);
renderer_type = PLY_RENDERER_TYPE_DRM;
if (syspath_is_simpledrm (device_syspath))
renderer_type = PLY_RENDERER_TYPE_SIMPLEDRM;
else
renderer_type = PLY_RENDERER_TYPE_DRM;
} else if (strcmp (subsystem, SUBSYSTEM_FRAME_BUFFER) == 0) {
ply_trace ("found frame buffer device %s", device_path);
if (!fb_device_has_drm_device (manager, device))
@ -430,20 +441,13 @@ create_devices_for_udev_device (ply_device_manager_t *manager,
}
if (renderer_type != PLY_RENDERER_TYPE_NONE) {
ply_terminal_t *terminal = NULL;
if (!manager->local_console_managed &&
manager->local_console_terminal != NULL &&
ply_terminal_is_vt (manager->local_console_terminal)) {
terminal = manager->local_console_terminal;
}
created = create_devices_for_terminal_and_renderer_type (manager,
device_path,
terminal,
NULL,
renderer_type);
if (created) {
if (renderer_type == PLY_RENDERER_TYPE_DRM)
if (renderer_type == PLY_RENDERER_TYPE_DRM ||
renderer_type == PLY_RENDERER_TYPE_SIMPLEDRM)
manager->found_drm_device = 1;
if (renderer_type == PLY_RENDERER_TYPE_FRAME_BUFFER)
manager->found_fb_device = 1;
@ -454,23 +458,22 @@ create_devices_for_udev_device (ply_device_manager_t *manager,
return created;
}
static bool
static void
create_devices_for_subsystem (ply_device_manager_t *manager,
const char *subsystem)
{
struct udev_enumerate *matches;
struct udev_list_entry *entry;
bool found_device = false;
if (strcmp (subsystem, SUBSYSTEM_INPUT) == 0) {
if (ply_kernel_command_line_has_argument ("plymouth.use-legacy-input")) {
ply_trace ("Not creating devices for subsystem " SUBSYSTEM_INPUT " because plymouth.use-legacy-input on command line");
return false;
return;
}
if (manager->xkb_keymap == NULL) {
ply_trace ("Not creating devices for subsystem " SUBSYSTEM_INPUT " because there is no configure XKB layout");
return false;
return;
}
}
@ -486,6 +489,7 @@ create_devices_for_subsystem (ply_device_manager_t *manager,
udev_list_entry_foreach (entry, udev_enumerate_get_list_entry (matches)){
struct udev_device *device = NULL;
const char *path, *node;
int initialized;
path = udev_list_entry_get_name (entry);
@ -498,15 +502,16 @@ create_devices_for_subsystem (ply_device_manager_t *manager,
device = udev_device_new_from_syspath (manager->udev_context, path);
/* if device isn't fully initialized, we'll get an add event later
*/
if (udev_device_get_is_initialized (device)) {
ply_trace ("device is initialized");
/* If device isn't fully initialized, we'll get an add event later */
initialized = udev_device_get_is_initialized (device);
/* Simpledrm can be handled uninitialized and this shows the splash sooner */
if (initialized || syspath_is_simpledrm (path)) {
ply_trace ("device is initialized %d", initialized);
node = udev_device_get_devnode (device);
if (node != NULL) {
ply_trace ("found node %s", node);
found_device = create_devices_for_udev_device (manager, device);
create_devices_for_udev_device (manager, device);
}
} else {
ply_trace ("it's not initialized");
@ -516,8 +521,6 @@ create_devices_for_subsystem (ply_device_manager_t *manager,
}
udev_enumerate_unref (matches);
return found_device;
}
static void
@ -1076,6 +1079,18 @@ create_text_displays_for_terminal (ply_device_manager_t *manager,
manager->text_display_added_handler (manager->event_handler_data, display);
}
static void
free_simpledrm_renderer (char *device_path,
ply_renderer_t *renderer,
ply_device_manager_t *manager)
{
if (ply_renderer_get_type (renderer) != PLY_RENDERER_TYPE_SIMPLEDRM)
return;
ply_trace ("removing simpledrm renderer %s", device_path);
free_devices_from_device_path (manager, device_path, true);
}
static bool
create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager,
const char *device_path,
@ -1093,6 +1108,23 @@ create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager,
return true;
}
/*
* simpledrm udev remove events may arrive after normal drm device add
* events, leaving the local_console unmanaged breaking legacy input.
* Remove simpledrm renderers before adding drm renderers to avoid this.
*/
if (renderer_type == PLY_RENDERER_TYPE_DRM) {
ply_hashtable_foreach (manager->renderers,
(ply_hashtable_foreach_func_t *)
free_simpledrm_renderer,
manager);
}
if (!terminal && !manager->local_console_managed &&
manager->local_console_terminal != NULL &&
ply_terminal_is_vt (manager->local_console_terminal))
terminal = manager->local_console_terminal;
ply_trace ("creating devices for %s (renderer type: %u) (terminal: %s)",
device_path ? : "", renderer_type, terminal ? ply_terminal_get_name (terminal) : "none");

View file

@ -102,6 +102,12 @@ ply_renderer_get_device_name (ply_renderer_t *renderer)
return renderer->device_name;
}
ply_renderer_type_t
ply_renderer_get_type (ply_renderer_t *renderer)
{
return renderer->type;
}
static bool
ply_renderer_load_plugin (ply_renderer_t *renderer,
const char *module_path)
@ -269,6 +275,7 @@ ply_renderer_open (ply_renderer_t *renderer)
{
{ PLY_RENDERER_TYPE_X11, PLYMOUTH_PLUGIN_PATH "renderers/x11.so" },
{ PLY_RENDERER_TYPE_DRM, PLYMOUTH_PLUGIN_PATH "renderers/drm.so" },
{ PLY_RENDERER_TYPE_SIMPLEDRM, PLYMOUTH_PLUGIN_PATH "renderers/drm.so" },
{ PLY_RENDERER_TYPE_FRAME_BUFFER, PLYMOUTH_PLUGIN_PATH "renderers/frame-buffer.so" },
{ PLY_RENDERER_TYPE_NONE, NULL }
};

View file

@ -41,6 +41,7 @@ typedef enum
PLY_RENDERER_TYPE_NONE = -1,
PLY_RENDERER_TYPE_AUTO,
PLY_RENDERER_TYPE_DRM,
PLY_RENDERER_TYPE_SIMPLEDRM,
PLY_RENDERER_TYPE_FRAME_BUFFER,
PLY_RENDERER_TYPE_X11
} ply_renderer_type_t;
@ -62,6 +63,7 @@ void ply_renderer_activate (ply_renderer_t *renderer);
void ply_renderer_deactivate (ply_renderer_t *renderer);
bool ply_renderer_is_active (ply_renderer_t *renderer);
const char *ply_renderer_get_device_name (ply_renderer_t *renderer);
ply_renderer_type_t ply_renderer_get_type (ply_renderer_t *renderer);
ply_list_t *ply_renderer_get_heads (ply_renderer_t *renderer);
ply_pixel_buffer_t *ply_renderer_get_buffer_for_head (ply_renderer_t *renderer,
ply_renderer_head_t *head);

View file

@ -473,6 +473,24 @@ ply_string_has_prefix (const char *str,
return strncmp (str, prefix, strlen (prefix)) == 0;
}
bool
ply_string_has_suffix (const char *str,
const char *suffix)
{
size_t str_len, suffix_len;
if (str == NULL || suffix == NULL)
return false;
str_len = strlen (str);
suffix_len = strlen (suffix);
if (suffix_len > str_len)
return false;
return strcmp (str + (str_len - suffix_len), suffix) == 0;
}
double
ply_get_timestamp (void)
{

View file

@ -109,6 +109,8 @@ char **ply_copy_string_array (const char *const *array);
void ply_free_string_array (char **array);
bool ply_string_has_prefix (const char *str,
const char *prefix);
bool ply_string_has_suffix (const char *str,
const char *suffix);
double ply_get_timestamp (void);
void ply_save_errno (void);