Merge branch 'use_simpledrm-config' into 'main'

Make simpledrm selection configurable from config file

Closes #264

See merge request plymouth/plymouth!342
This commit is contained in:
Hans de Goede 2025-05-06 11:37:33 +00:00
commit 655aae1e3d
17 changed files with 175 additions and 107 deletions

View file

@ -345,35 +345,15 @@ syspath_is_simpledrm (const char *syspath)
return ply_string_has_suffix (syspath, "simple-framebuffer.0/drm/card0");
}
/* Only use SimpleDRM devices if requested to do so */
static bool
verify_drm_device (struct udev_device *device)
verify_drm_device (ply_device_manager_t *manager,
struct udev_device *device)
{
/*
* 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.
*/
if (!syspath_is_simpledrm (udev_device_get_syspath (device)))
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;
return manager->flags & PLY_DEVICE_MANAGER_FLAGS_USE_SIMPLEDRM;
}
static bool
@ -399,7 +379,8 @@ create_devices_for_udev_device (ply_device_manager_t *manager,
ply_trace ("device subsystem is %s", subsystem);
if (strcmp (subsystem, SUBSYSTEM_DRM) == 0) {
if (!manager->device_timeout_elapsed && !verify_drm_device (device)) {
if (!manager->device_timeout_elapsed &&
!verify_drm_device (manager, device)) {
ply_trace ("ignoring since we only handle SimpleDRM devices after timeout");
return false;
}
@ -1132,9 +1113,12 @@ create_devices_for_terminal_and_renderer_type (ply_device_manager_t *manager,
if (renderer_type != PLY_RENDERER_TYPE_NONE) {
ply_renderer_t *old_renderer = NULL;
bool force = manager->device_timeout_elapsed ||
(manager->flags & PLY_DEVICE_MANAGER_FLAGS_FORCE_OPEN);
renderer = ply_renderer_new (renderer_type, device_path, terminal);
if (renderer != NULL && !ply_renderer_open (renderer)) {
if (renderer != NULL && !ply_renderer_open (renderer, force)) {
ply_trace ("could not open renderer for %s", device_path);
ply_renderer_free (renderer);
renderer = NULL;

View file

@ -33,7 +33,9 @@ typedef enum
PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES = 1 << 0,
PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV = 1 << 1,
PLY_DEVICE_MANAGER_FLAGS_SKIP_RENDERERS = 1 << 2,
PLY_DEVICE_MANAGER_FLAGS_FORCE_FRAME_BUFFER = 1 << 3
PLY_DEVICE_MANAGER_FLAGS_FORCE_FRAME_BUFFER = 1 << 3,
PLY_DEVICE_MANAGER_FLAGS_USE_SIMPLEDRM = 1 << 4,
PLY_DEVICE_MANAGER_FLAGS_FORCE_OPEN = 1 << 5,
} ply_device_manager_flags_t;
typedef struct _ply_device_manager ply_device_manager_t;

View file

@ -43,7 +43,8 @@ typedef struct
void (*destroy_backend)(ply_renderer_backend_t *backend);
bool (*open_device)(ply_renderer_backend_t *backend);
void (*close_device)(ply_renderer_backend_t *backend);
bool (*query_device)(ply_renderer_backend_t *backend);
bool (*query_device)(ply_renderer_backend_t *backend,
bool force);
bool (*handle_change_event)(ply_renderer_backend_t *backend);
bool (*map_to_device)(ply_renderer_backend_t *backend);
void (*unmap_from_device)(ply_renderer_backend_t *backend);

View file

@ -199,12 +199,13 @@ ply_renderer_close_device (ply_renderer_t *renderer)
}
static bool
ply_renderer_query_device (ply_renderer_t *renderer)
ply_renderer_query_device (ply_renderer_t *renderer,
bool force)
{
assert (renderer != NULL);
assert (renderer->plugin_interface != NULL);
return renderer->plugin_interface->query_device (renderer->backend);
return renderer->plugin_interface->query_device (renderer->backend, force);
}
static bool
@ -236,7 +237,8 @@ ply_renderer_unmap_from_device (ply_renderer_t *renderer)
static bool
ply_renderer_open_plugin (ply_renderer_t *renderer,
const char *plugin_path)
const char *plugin_path,
bool force)
{
ply_trace ("trying to open renderer plugin %s", plugin_path);
@ -250,7 +252,7 @@ ply_renderer_open_plugin (ply_renderer_t *renderer,
return false;
}
if (!ply_renderer_query_device (renderer)) {
if (!ply_renderer_query_device (renderer, force)) {
ply_trace ("could not query rendering device for plugin %s",
plugin_path);
ply_renderer_close_device (renderer);
@ -263,7 +265,8 @@ ply_renderer_open_plugin (ply_renderer_t *renderer,
}
bool
ply_renderer_open (ply_renderer_t *renderer)
ply_renderer_open (ply_renderer_t *renderer,
bool force)
{
int i;
@ -284,7 +287,7 @@ ply_renderer_open (ply_renderer_t *renderer)
for (i = 0; known_plugins[i].type != PLY_RENDERER_TYPE_NONE; i++) {
if (renderer->type == known_plugins[i].type ||
renderer->type == PLY_RENDERER_TYPE_AUTO) {
if (ply_renderer_open_plugin (renderer, known_plugins[i].path)) {
if (ply_renderer_open_plugin (renderer, known_plugins[i].path, force)) {
renderer->is_active = true;
goto out;
}

View file

@ -55,7 +55,8 @@ ply_renderer_t *ply_renderer_new (ply_renderer_type_t renderer_type,
const char *device_name,
ply_terminal_t *terminal);
void ply_renderer_free (ply_renderer_t *renderer);
bool ply_renderer_open (ply_renderer_t *renderer);
bool ply_renderer_open (ply_renderer_t *renderer,
bool force);
void ply_renderer_close (ply_renderer_t *renderer);
/* Returns true when the heads have changed as a result of the change event */
bool ply_renderer_handle_change_event (ply_renderer_t *renderer);

View file

@ -406,18 +406,27 @@ ply_key_file_get_double (ply_key_file_t *key_file,
return ply_strtod (raw_value);
}
double
ply_key_file_get_long (ply_key_file_t *key_file,
const char *group,
const char *key,
long default_value)
unsigned long
ply_key_file_get_ulong (ply_key_file_t *key_file,
const char *group,
const char *key,
unsigned long default_value)
{
char *raw_value = ply_key_file_get_raw_value (key_file, group, key);
char *endptr = NULL;
unsigned long u;
if (!raw_value)
return default_value;
return strtol (raw_value, NULL, 0);
u = strtoul (raw_value, &endptr, 0);
if (*endptr != '\0') {
ply_trace ("group '%s' key '%s' val '%s' is not a valid unsigned number",
group, key, raw_value);
return default_value;
}
return u;
}
static void

View file

@ -55,10 +55,10 @@ double ply_key_file_get_double (ply_key_file_t *key_file,
const char *group_name,
const char *key,
double default_value);
double ply_key_file_get_long (ply_key_file_t *key_file,
const char *group,
const char *key,
long default_value);
unsigned long ply_key_file_get_ulong (ply_key_file_t *key_file,
const char *group,
const char *key,
unsigned long default_value);
void ply_key_file_foreach_entry (ply_key_file_t *key_file,
ply_key_file_foreach_func_t func,
void *user_data);

View file

@ -1251,6 +1251,28 @@ ply_kernel_command_line_get_key_value (const char *key)
return strndup (value, strcspn (value, " \n"));
}
unsigned long
ply_kernel_command_line_get_ulong (const char *key,
unsigned long default_value)
{
const char *raw_value;
char *endptr = NULL;
unsigned long u;
raw_value = ply_kernel_command_line_get_string_after_prefix (key);
if (raw_value == NULL || raw_value[0] == '\0')
return default_value;
u = strtoul (raw_value, &endptr, 0);
if (!isspace ((int) *endptr) && *endptr != '\0') {
ply_trace ("'%s' argument '%s' is not a valid unsigned number",
key, raw_value);
return default_value;
}
return u;
}
void
ply_kernel_command_line_override (const char *command_line)
{

View file

@ -175,6 +175,8 @@ const char *ply_kernel_command_line_get_string_after_prefix (const char *prefix)
bool ply_kernel_command_line_has_argument (const char *argument);
void ply_kernel_command_line_override (const char *command_line);
char *ply_kernel_command_line_get_key_value (const char *key);
unsigned long ply_kernel_command_line_get_ulong (const char *key,
unsigned long default_value);
char *ply_get_primary_kernel_console_type (void);

View file

@ -101,6 +101,8 @@ typedef struct
double start_time;
double splash_delay;
double device_timeout;
int device_scale;
int use_simpledrm;
uint32_t no_boot_log : 1;
uint32_t showing_details : 1;
@ -307,7 +309,6 @@ load_settings (state_t *state,
{
ply_key_file_t *key_file = NULL;
bool settings_loaded = false;
char *scale_string = NULL;
char *splash_string = NULL;
ply_trace ("Trying to load %s", path);
@ -336,12 +337,11 @@ load_settings (state_t *state,
ply_trace ("Device timeout is set to %lf", state->device_timeout);
}
scale_string = ply_key_file_get_value (key_file, "Daemon", "DeviceScale");
if (state->device_scale == -1)
state->device_scale = ply_key_file_get_ulong (key_file, "Daemon", "DeviceScale", -1);
if (scale_string != NULL) {
ply_set_device_scale (strtoul (scale_string, NULL, 0));
free (scale_string);
}
if (state->use_simpledrm == -1)
state->use_simpledrm = ply_key_file_get_ulong (key_file, "Daemon", "UseSimpledrm", -1);
settings_loaded = true;
out:
@ -401,17 +401,19 @@ find_override_splash (state_t *state)
if (delay_string != NULL)
state->splash_delay = ply_strtod (delay_string);
}
}
static void
find_force_scale (state_t *state)
{
const char *scale_string;
if (state->device_scale == -1)
state->device_scale = ply_kernel_command_line_get_ulong ("plymouth.force-scale=", -1);
scale_string = ply_kernel_command_line_get_string_after_prefix ("plymouth.force-scale=");
if (state->use_simpledrm == -1)
state->use_simpledrm = ply_kernel_command_line_get_ulong ("plymouth.use-simpledrm=", -1);
if (scale_string != NULL)
ply_set_device_scale (strtoul (scale_string, NULL, 0));
if (state->use_simpledrm == -1) {
if (ply_kernel_command_line_has_argument ("plymouth.use-simpledrm"))
state->use_simpledrm = 1;
else if (ply_kernel_command_line_has_argument ("nomodeset"))
state->use_simpledrm = 2;
}
}
static void
@ -2532,6 +2534,8 @@ main (int argc,
state.progress = ply_progress_new ();
state.splash_delay = NAN;
state.device_timeout = NAN;
state.device_scale = -1;
state.use_simpledrm = -1;
ply_progress_load_cache (state.progress,
get_cache_file_for_mode (state.mode));
@ -2572,7 +2576,14 @@ main (int argc,
state.splash_delay = NAN;
}
find_force_scale (&state);
if (state.device_scale != -1)
ply_set_device_scale (state.device_scale);
if (state.use_simpledrm >= 1)
device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_USE_SIMPLEDRM;
if (state.use_simpledrm >= 2)
device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_FORCE_OPEN;
load_devices (&state, device_manager_flags);

View file

@ -1391,12 +1391,37 @@ check_if_output_has_changed (ply_renderer_backend_t *backend,
return true;
}
/* Sometimes the EFI firmware sets up the framebuffer at 800x600 or 1024x768
* instead of the native panel resolution. In this case it is better to wait
* for the native driver to load, so we return false from query_device ().
*/
static bool
check_simpledrm_resolution (ply_renderer_backend_t *backend,
ply_output_t *output)
{
if (!backend->simpledrm)
return true;
if (!output->connected)
return true;
if ((output->mode.hdisplay == 800 && output->mode.vdisplay == 600) ||
(output->mode.hdisplay == 1024 && output->mode.vdisplay == 768)) {
ply_trace ("Skipping simpledrm device with mode %dx%d",
output->mode.hdisplay, output->mode.vdisplay);
return false;
}
return true;
}
/* Update our outputs array to match the hardware state and
* create and/or remove heads as necessary.
* Returns true if any heads were modified.
*/
static bool
create_heads_for_active_connectors (ply_renderer_backend_t *backend,
bool force,
bool change)
{
int i, j, number_of_setup_outputs, outputs_len;
@ -1420,6 +1445,11 @@ create_heads_for_active_connectors (ply_renderer_backend_t *backend,
for (i = 0; i < outputs_len; i++) {
get_output_info (backend, backend->resources->connectors[i], &outputs[i]);
if (!force && !check_simpledrm_resolution (backend, &outputs[i])) {
free (outputs);
return false;
}
if (check_if_output_has_changed (backend, &outputs[i]))
changed = true;
@ -1563,7 +1593,8 @@ has_32bpp_support (ply_renderer_backend_t *backend)
}
static bool
query_device (ply_renderer_backend_t *backend)
query_device (ply_renderer_backend_t *backend,
bool force)
{
bool ret = true;
@ -1577,7 +1608,7 @@ query_device (ply_renderer_backend_t *backend)
return false;
}
if (!create_heads_for_active_connectors (backend, false)) {
if (!create_heads_for_active_connectors (backend, force, false)) {
ply_trace ("Could not initialize heads");
ret = false;
} else if (!has_32bpp_support (backend)) {
@ -1602,7 +1633,7 @@ handle_change_event (ply_renderer_backend_t *backend)
return false;
}
ret = create_heads_for_active_connectors (backend, true);
ret = create_heads_for_active_connectors (backend, true, true);
drmModeFreeResources (backend->resources);
backend->resources = NULL;

View file

@ -420,7 +420,8 @@ static const char *get_visual_name (int visual)
}
static bool
query_device (ply_renderer_backend_t *backend)
query_device (ply_renderer_backend_t *backend,
bool force)
{
struct fb_var_screeninfo variable_screen_info;
struct fb_fix_screeninfo fixed_screen_info;

View file

@ -284,7 +284,8 @@ create_fullscreen_single_head_setup (ply_renderer_backend_t *backend)
}
static bool
query_device (ply_renderer_backend_t *backend)
query_device (ply_renderer_backend_t *backend,
bool force)
{
assert (backend != NULL);

View file

@ -255,14 +255,14 @@ create_plugin (ply_key_file_t *key_file)
plugin->monospace_font = strdup ("monospace 10");
plugin->console_text_color =
ply_key_file_get_long (key_file, "fade-throbber",
"ConsoleLogTextColor",
PLY_CONSOLE_VIEWER_LOG_TEXT_COLOR);
ply_key_file_get_ulong (key_file, "fade-throbber",
"ConsoleLogTextColor",
PLY_CONSOLE_VIEWER_LOG_TEXT_COLOR);
plugin->console_background_color =
ply_key_file_get_long (key_file, "fade-throbber",
"ConsoleLogBackgroundColor",
0x00000000);
ply_key_file_get_ulong (key_file, "fade-throbber",
"ConsoleLogBackgroundColor",
0x00000000);
plugin->image_dir = image_dir;

View file

@ -233,14 +233,14 @@ create_plugin (ply_key_file_t *key_file)
plugin->monospace_font = strdup ("monospace 10");
plugin->console_text_color =
ply_key_file_get_long (key_file, "script",
"ConsoleLogTextColor",
PLY_CONSOLE_VIEWER_LOG_TEXT_COLOR);
ply_key_file_get_ulong (key_file, "script",
"ConsoleLogTextColor",
PLY_CONSOLE_VIEWER_LOG_TEXT_COLOR);
plugin->console_background_color =
ply_key_file_get_long (key_file, "script",
"ConsoleLogBackgroundColor",
0x00000000);
ply_key_file_get_ulong (key_file, "script",
"ConsoleLogBackgroundColor",
0x00000000);
plugin->displays = ply_list_new ();

View file

@ -634,14 +634,14 @@ create_plugin (ply_key_file_t *key_file)
plugin->monospace_font = strdup ("monospace 10");
plugin->console_text_color =
ply_key_file_get_long (key_file, "space-flares",
"ConsoleLogTextColor",
PLY_CONSOLE_VIEWER_LOG_TEXT_COLOR);
ply_key_file_get_ulong (key_file, "space-flares",
"ConsoleLogTextColor",
PLY_CONSOLE_VIEWER_LOG_TEXT_COLOR);
plugin->console_background_color =
ply_key_file_get_long (key_file, "space-flares",
"ConsoleLogBackgroundColor",
0x00000000);
ply_key_file_get_ulong (key_file, "space-flares",
"ConsoleLogBackgroundColor",
0x00000000);
plugin->state = PLY_BOOT_SPLASH_DISPLAY_NORMAL;
plugin->progress = 0;

View file

@ -1286,44 +1286,44 @@ create_plugin (ply_key_file_t *key_file)
plugin->console_text_color =
ply_key_file_get_long (key_file, "two-step",
"ConsoleLogTextColor",
PLY_CONSOLE_VIEWER_LOG_TEXT_COLOR);
ply_key_file_get_ulong (key_file, "two-step",
"ConsoleLogTextColor",
PLY_CONSOLE_VIEWER_LOG_TEXT_COLOR);
plugin->console_background_color =
ply_key_file_get_long (key_file, "two-step",
"ConsoleLogBackgroundColor",
0x00000000);
ply_key_file_get_ulong (key_file, "two-step",
"ConsoleLogBackgroundColor",
0x00000000);
plugin->transition_duration =
ply_key_file_get_double (key_file, "two-step",
"TransitionDuration", 0.0);
plugin->background_start_color =
ply_key_file_get_long (key_file, "two-step",
"BackgroundStartColor",
PLYMOUTH_BACKGROUND_START_COLOR);
ply_key_file_get_ulong (key_file, "two-step",
"BackgroundStartColor",
PLYMOUTH_BACKGROUND_START_COLOR);
plugin->background_end_color =
ply_key_file_get_long (key_file, "two-step",
"BackgroundEndColor",
PLYMOUTH_BACKGROUND_END_COLOR);
ply_key_file_get_ulong (key_file, "two-step",
"BackgroundEndColor",
PLYMOUTH_BACKGROUND_END_COLOR);
plugin->progress_bar_bg_color =
ply_key_file_get_long (key_file, "two-step",
"ProgressBarBackgroundColor",
0xffffff /* white */);
ply_key_file_get_ulong (key_file, "two-step",
"ProgressBarBackgroundColor",
0xffffff /* white */);
plugin->progress_bar_fg_color =
ply_key_file_get_long (key_file, "two-step",
"ProgressBarForegroundColor",
0x000000 /* black */);
ply_key_file_get_ulong (key_file, "two-step",
"ProgressBarForegroundColor",
0x000000 /* black */);
plugin->progress_bar_width =
ply_key_file_get_long (key_file, "two-step",
"ProgressBarWidth",
PROGRESS_BAR_WIDTH);
ply_key_file_get_ulong (key_file, "two-step",
"ProgressBarWidth",
PROGRESS_BAR_WIDTH);
plugin->progress_bar_height =
ply_key_file_get_long (key_file, "two-step",
"ProgressBarHeight",
PROGRESS_BAR_HEIGHT);
ply_key_file_get_ulong (key_file, "two-step",
"ProgressBarHeight",
PROGRESS_BAR_HEIGHT);
load_mode_settings (plugin, key_file, "boot-up", PLY_BOOT_SPLASH_MODE_BOOT_UP);
load_mode_settings (plugin, key_file, "shutdown", PLY_BOOT_SPLASH_MODE_SHUTDOWN);