From 5d0d9781e290db2d428a0cd07d602542ce8fe29f Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Thu, 4 Oct 2018 15:59:35 +0200 Subject: [PATCH] Add patches from upstream to fix the disk unlock screen sometimes having a very low resolution on UEFI machines: https://gitlab.freedesktop.org/plymouth/plymouth/issues/68 --- ...n-ensure-tty-is-closed-on-deactivate.patch | 71 +++ ...el-commandline-parsing-functions-to-.patch | 494 ++++++++++++++++++ ...mma-table-before-the-first-drmModeSe.patch | 123 +++++ ...-ply_renderer_connector_get_rotation.patch | 144 +++++ ...d-mode-for-outputs-instead-of-curren.patch | 126 +++++ plymouth.spec | 15 +- 6 files changed, 972 insertions(+), 1 deletion(-) create mode 100644 0001-main-ensure-tty-is-closed-on-deactivate.patch create mode 100644 0002-libply-Move-kernel-commandline-parsing-functions-to-.patch create mode 100644 0003-drm-Reset-LUT-gamma-table-before-the-first-drmModeSe.patch create mode 100644 0004-drm-Refactor-ply_renderer_connector_get_rotation.patch create mode 100644 0005-drm-Use-preferred-mode-for-outputs-instead-of-curren.patch diff --git a/0001-main-ensure-tty-is-closed-on-deactivate.patch b/0001-main-ensure-tty-is-closed-on-deactivate.patch new file mode 100644 index 0000000..e6a048f --- /dev/null +++ b/0001-main-ensure-tty-is-closed-on-deactivate.patch @@ -0,0 +1,71 @@ +From 28ee4012c94b4045b97e5a2a66f66b7688b2dff3 Mon Sep 17 00:00:00 2001 +From: Ray Strode +Date: Sat, 25 Aug 2018 12:21:45 -0400 +Subject: [PATCH 1/5] main: ensure tty is closed on deactivate + +If plymouth doesn't get explicitly "activated" then when +GDM tries to deactivate it, the deactivation request is +a noop. + +One aspect of being active, though is having ownership and +control of the terminal. This happens immediately, even +before a splash is shown. + +The `deactivate` request needs to relinguish such control, +unconditionally, since some display server is about to use +the tty. + +This commit fixes that. +--- + src/main.c | 20 ++++++++++++++------ + 1 file changed, 14 insertions(+), 6 deletions(-) + +diff --git a/src/main.c b/src/main.c +index 7e58fff..0564e15 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -1267,13 +1267,8 @@ quit_program (state_t *state) + } + + static void +-deactivate_splash (state_t *state) ++deactivate_console (state_t *state) + { +- assert (!state->is_inactive); +- +- if (state->boot_splash && ply_boot_splash_uses_pixel_displays (state->boot_splash)) +- ply_device_manager_deactivate_renderers (state->device_manager); +- + detach_from_running_session (state); + + if (state->local_console_terminal != NULL) { +@@ -1287,6 +1282,18 @@ deactivate_splash (state_t *state) + if (command_line_has_argument (state->kernel_command_line, "plymouth.debug")) + ply_logger_close_file (ply_logger_get_error_default ()); + ++} ++ ++static void ++deactivate_splash (state_t *state) ++{ ++ assert (!state->is_inactive); ++ ++ if (state->boot_splash && ply_boot_splash_uses_pixel_displays (state->boot_splash)) ++ ply_device_manager_deactivate_renderers (state->device_manager); ++ ++ deactivate_console (state); ++ + state->is_inactive = true; + + ply_trigger_pull (state->deactivate_trigger, NULL); +@@ -1322,6 +1329,7 @@ on_deactivate (state_t *state, + ply_trigger_t *deactivate_trigger) + { + if (state->is_inactive) { ++ deactivate_console (state); + ply_trigger_pull (deactivate_trigger, NULL); + return; + } +-- +2.19.0 + diff --git a/0002-libply-Move-kernel-commandline-parsing-functions-to-.patch b/0002-libply-Move-kernel-commandline-parsing-functions-to-.patch new file mode 100644 index 0000000..58af9e9 --- /dev/null +++ b/0002-libply-Move-kernel-commandline-parsing-functions-to-.patch @@ -0,0 +1,494 @@ +From 13d95b10dd15974a74f645e99f99d934544afe37 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Thu, 4 Oct 2018 12:47:52 +0200 +Subject: [PATCH 2/5] libply: Move kernel commandline parsing functions to + libply/ply-utils + +Move kernel commandline parsing functions to libply/ply-utils to avoid +code duplication between the daemon, the client and the plugins. + +Signed-off-by: Hans de Goede +--- + src/client/plymouth.c | 34 +--------- + src/libply/ply-utils.c | 94 ++++++++++++++++++++++++++++ + src/libply/ply-utils.h | 4 ++ + src/main.c | 137 ++++++----------------------------------- + 4 files changed, 120 insertions(+), 149 deletions(-) + +diff --git a/src/client/plymouth.c b/src/client/plymouth.c +index 46a64f5..4e14603 100644 +--- a/src/client/plymouth.c ++++ b/src/client/plymouth.c +@@ -49,7 +49,6 @@ typedef struct + ply_event_loop_t *loop; + ply_boot_client_t *client; + ply_command_parser_t *command_parser; +- char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE]; + } state_t; + + typedef struct +@@ -704,31 +703,6 @@ on_quit_request (state_t *state, + on_failure, state); + } + +-static bool +-get_kernel_command_line (state_t *state) +-{ +- int fd; +- +- ply_trace ("opening /proc/cmdline"); +- fd = open ("/proc/cmdline", O_RDONLY); +- +- if (fd < 0) { +- ply_trace ("couldn't open it: %m"); +- return false; +- } +- +- ply_trace ("reading kernel command line"); +- if (read (fd, state->kernel_command_line, sizeof(state->kernel_command_line) - 1) < 0) { +- ply_trace ("couldn't read it: %m"); +- close (fd); +- return false; +- } +- +- ply_trace ("Kernel command line is: '%s'", state->kernel_command_line); +- close (fd); +- return true; +-} +- + static void + on_update_root_fs_request (state_t *state, + const char *command) +@@ -1099,12 +1073,8 @@ main (int argc, + return 0; + } + +- if (get_kernel_command_line (&state)) { +- if ((strstr (state.kernel_command_line, "plymouth.debug") != NULL || +- strstr (state.kernel_command_line, "plymouth:debug") != NULL) +- && !ply_is_tracing ()) +- ply_toggle_tracing (); +- } ++ if (ply_kernel_cmd_line_has_argument ("plymouth.debug") && !ply_is_tracing ()) ++ ply_toggle_tracing (); + + if (should_be_verbose && !ply_is_tracing ()) + ply_toggle_tracing (); +diff --git a/src/libply/ply-utils.c b/src/libply/ply-utils.c +index 89e37e9..1f7f07c 100644 +--- a/src/libply/ply-utils.c ++++ b/src/libply/ply-utils.c +@@ -24,6 +24,7 @@ + #include "ply-utils.h" + + #include ++#include + #include + #include + #include +@@ -80,6 +81,9 @@ static int errno_stack_position = 0; + + static int overridden_device_scale = 0; + ++static char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE]; ++static bool kernel_command_line_is_set; ++ + bool + ply_open_unidirectional_pipe (int *sender_fd, + int *receiver_fd) +@@ -1015,4 +1019,94 @@ ply_get_device_scale (uint32_t width, + return device_scale; + } + ++static const char * ++ply_get_kernel_command_line (void) ++{ ++ const char *remaining_command_line; ++ char *key; ++ int fd; ++ ++ if (kernel_command_line_is_set) ++ return kernel_command_line; ++ ++ ply_trace ("opening /proc/cmdline"); ++ fd = open ("/proc/cmdline", O_RDONLY); ++ ++ if (fd < 0) { ++ ply_trace ("couldn't open it: %m"); ++ return NULL; ++ } ++ ++ ply_trace ("reading kernel command line"); ++ if (read (fd, kernel_command_line, sizeof(kernel_command_line) - 1) < 0) { ++ ply_trace ("couldn't read it: %m"); ++ close (fd); ++ return NULL; ++ } ++ ++ /* we now use plymouth.argument for kernel commandline arguments. ++ * It used to be plymouth:argument. This bit just rewrites all : to be . ++ */ ++ remaining_command_line = kernel_command_line; ++ while ((key = strstr (remaining_command_line, "plymouth:")) != NULL) { ++ char *colon; ++ ++ colon = key + strlen ("plymouth"); ++ *colon = '.'; ++ ++ remaining_command_line = colon + 1; ++ } ++ ply_trace ("Kernel command line is: '%s'", kernel_command_line); ++ ++ close (fd); ++ ++ kernel_command_line_is_set = true; ++ return kernel_command_line; ++} ++ ++const char * ++ply_kernel_cmd_line_get_string_after_prefix (const char *prefix) ++{ ++ const char *command_line = ply_get_kernel_command_line(); ++ char *argument; ++ ++ if (!command_line) ++ return NULL; ++ ++ argument = strstr (command_line, prefix); ++ ++ if (argument == NULL) ++ return NULL; ++ ++ if (argument == command_line || ++ argument[-1] == ' ') ++ return argument + strlen (prefix); ++ ++ return NULL; ++} ++ ++bool ++ply_kernel_cmd_line_has_argument (const char *argument) ++{ ++ const char *string; ++ ++ string = ply_kernel_cmd_line_get_string_after_prefix (argument); ++ ++ if (string == NULL) ++ return false; ++ ++ if (!isspace ((int) string[0]) && string[0] != '\0') ++ return false; ++ ++ return true; ++} ++ ++void ++ply_kernel_cmd_line_set (const char *cmd_line) ++{ ++ strncpy (kernel_command_line, cmd_line, sizeof(kernel_command_line)); ++ kernel_command_line[sizeof(kernel_command_line) - 1] = '\0'; ++ kernel_command_line_is_set = true; ++} ++ + /* vim: set ts=4 sw=4 expandtab autoindent cindent cino={.5s,(0: */ +diff --git a/src/libply/ply-utils.h b/src/libply/ply-utils.h +index c46603e..6016484 100644 +--- a/src/libply/ply-utils.h ++++ b/src/libply/ply-utils.h +@@ -128,6 +128,10 @@ int ply_get_device_scale (uint32_t width, + uint32_t width_mm, + uint32_t height_mm); + ++const char *ply_kernel_cmd_line_get_string_after_prefix (const char *prefix); ++bool ply_kernel_cmd_line_has_argument (const char *argument); ++void ply_kernel_cmd_line_set (const char *cmd_line); ++ + #endif + + #endif /* PLY_UTILS_H */ +diff --git a/src/main.c b/src/main.c +index 0564e15..61d94c1 100644 +--- a/src/main.c ++++ b/src/main.c +@@ -24,7 +24,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -56,10 +55,6 @@ + #include "ply-utils.h" + #include "ply-progress.h" + +-#ifndef PLY_MAX_COMMAND_LINE_SIZE +-#define PLY_MAX_COMMAND_LINE_SIZE 4097 +-#endif +- + #define BOOT_DURATION_FILE PLYMOUTH_TIME_DIRECTORY "/boot-duration" + #define SHUTDOWN_DURATION_FILE PLYMOUTH_TIME_DIRECTORY "/shutdown-duration" + +@@ -109,8 +104,6 @@ typedef struct + double splash_delay; + double device_timeout; + +- char kernel_command_line[PLY_MAX_COMMAND_LINE_SIZE]; +- uint32_t kernel_command_line_is_set : 1; + uint32_t no_boot_log : 1; + uint32_t showing_details : 1; + uint32_t system_initialized : 1; +@@ -381,41 +374,6 @@ show_detailed_splash (state_t *state) + update_display (state); + } + +-static const char * +-command_line_get_string_after_prefix (const char *command_line, +- const char *prefix) +-{ +- char *argument; +- +- argument = strstr (command_line, prefix); +- +- if (argument == NULL) +- return NULL; +- +- if (argument == command_line || +- argument[-1] == ' ') +- return argument + strlen (prefix); +- +- return NULL; +-} +- +-static bool +-command_line_has_argument (const char *command_line, +- const char *argument) +-{ +- const char *string; +- +- string = command_line_get_string_after_prefix (command_line, argument); +- +- if (string == NULL) +- return false; +- +- if (!isspace ((int) string[0]) && string[0] != '\0') +- return false; +- +- return true; +-} +- + static void + find_override_splash (state_t *state) + { +@@ -424,8 +382,7 @@ find_override_splash (state_t *state) + if (state->override_splash_path != NULL) + return; + +- splash_string = command_line_get_string_after_prefix (state->kernel_command_line, +- "plymouth.splash="); ++ splash_string = ply_kernel_cmd_line_get_string_after_prefix ("plymouth.splash="); + + if (splash_string != NULL) { + const char *end; +@@ -452,7 +409,7 @@ find_override_splash (state_t *state) + if (isnan (state->splash_delay)) { + const char *delay_string; + +- delay_string = command_line_get_string_after_prefix (state->kernel_command_line, "plymouth.splash-delay="); ++ delay_string = ply_kernel_cmd_line_get_string_after_prefix ("plymouth.splash-delay="); + + if (delay_string != NULL) + state->splash_delay = atof (delay_string); +@@ -464,7 +421,7 @@ find_force_scale (state_t *state) + { + const char *scale_string; + +- scale_string = command_line_get_string_after_prefix (state->kernel_command_line, "plymouth.force-scale="); ++ scale_string = ply_kernel_cmd_line_get_string_after_prefix ("plymouth.force-scale="); + + if (scale_string != NULL) + ply_set_device_scale (strtoul (scale_string, NULL, 0)); +@@ -879,10 +836,10 @@ static bool + plymouth_should_ignore_show_splash_calls (state_t *state) + { + ply_trace ("checking if plymouth should be running"); +- if (state->mode != PLY_MODE_BOOT || command_line_has_argument (state->kernel_command_line, "plymouth.force-splash")) ++ if (state->mode != PLY_MODE_BOOT || ply_kernel_cmd_line_has_argument ("plymouth.force-splash")) + return false; + +- if (command_line_has_argument (state->kernel_command_line, "plymouth.ignore-show-splash")) ++ if (ply_kernel_cmd_line_has_argument ("plymouth.ignore-show-splash")) + return true; + + return false; +@@ -894,7 +851,7 @@ sh_is_init (state_t *state) + const char *init_string; + size_t length; + +- init_string = command_line_get_string_after_prefix (state->kernel_command_line, "init="); ++ init_string = ply_kernel_cmd_line_get_string_after_prefix ("init="); + + if (init_string) { + length = strcspn (init_string, " \n"); +@@ -919,28 +876,28 @@ plymouth_should_show_default_splash (state_t *state) + return false; + + for (i = 0; strings[i] != NULL; i++) { +- if (command_line_has_argument (state->kernel_command_line, strings[i])) { ++ if (ply_kernel_cmd_line_has_argument (strings[i])) { + ply_trace ("no default splash because kernel command line has option \"%s\"", strings[i]); + return false; + } + } + +- if (command_line_has_argument (state->kernel_command_line, "splash=verbose")) { ++ if (ply_kernel_cmd_line_has_argument ("splash=verbose")) { + ply_trace ("no default splash because kernel command line has option \"splash=verbose\""); + return false; + } + +- if (command_line_has_argument (state->kernel_command_line, "rhgb")) { ++ if (ply_kernel_cmd_line_has_argument ("rhgb")) { + ply_trace ("using default splash because kernel command line has option \"rhgb\""); + return true; + } + +- if (command_line_has_argument (state->kernel_command_line, "splash")) { ++ if (ply_kernel_cmd_line_has_argument ("splash")) { + ply_trace ("using default splash because kernel command line has option \"splash\""); + return true; + } + +- if (command_line_has_argument (state->kernel_command_line, "splash=silent")) { ++ if (ply_kernel_cmd_line_has_argument ("splash=silent")) { + ply_trace ("using default splash because kernel command line has option \"splash=silent\""); + return true; + } +@@ -1279,7 +1236,7 @@ deactivate_console (state_t *state) + } + + /* do not let any tty opened where we could write after deactivate */ +- if (command_line_has_argument (state->kernel_command_line, "plymouth.debug")) ++ if (ply_kernel_cmd_line_has_argument ("plymouth.debug")) + ply_logger_close_file (ply_logger_get_error_default ()); + + } +@@ -1872,52 +1829,6 @@ detach_from_running_session (state_t *state) + state->is_attached = false; + } + +-static bool +-get_kernel_command_line (state_t *state) +-{ +- int fd; +- const char *remaining_command_line; +- char *key; +- +- if (state->kernel_command_line_is_set) +- return true; +- +- ply_trace ("opening /proc/cmdline"); +- fd = open ("/proc/cmdline", O_RDONLY); +- +- if (fd < 0) { +- ply_trace ("couldn't open it: %m"); +- return false; +- } +- +- ply_trace ("reading kernel command line"); +- if (read (fd, state->kernel_command_line, sizeof(state->kernel_command_line) - 1) < 0) { +- ply_trace ("couldn't read it: %m"); +- close (fd); +- return false; +- } +- +- +- /* we now use plymouth.argument for kernel commandline arguments. +- * It used to be plymouth:argument. This bit just rewrites all : to be . +- */ +- remaining_command_line = state->kernel_command_line; +- while ((key = strstr (remaining_command_line, "plymouth:")) != NULL) { +- char *colon; +- +- colon = key + strlen ("plymouth"); +- *colon = '.'; +- +- remaining_command_line = colon + 1; +- } +- ply_trace ("Kernel command line is: '%s'", state->kernel_command_line); +- +- close (fd); +- +- state->kernel_command_line_is_set = true; +- return true; +-} +- + static void + check_verbosity (state_t *state) + { +@@ -1926,13 +1837,11 @@ check_verbosity (state_t *state) + + ply_trace ("checking if tracing should be enabled"); + +- stream = command_line_get_string_after_prefix (state->kernel_command_line, +- "plymouth.debug=stream:"); ++ stream = ply_kernel_cmd_line_get_string_after_prefix ("plymouth.debug=stream:"); + +- path = command_line_get_string_after_prefix (state->kernel_command_line, +- "plymouth.debug=file:"); ++ path = ply_kernel_cmd_line_get_string_after_prefix ("plymouth.debug=file:"); + if (stream != NULL || path != NULL || +- command_line_has_argument (state->kernel_command_line, "plymouth.debug")) { ++ ply_kernel_cmd_line_has_argument ("plymouth.debug")) { + int fd; + + ply_trace ("tracing should be enabled!"); +@@ -2010,7 +1919,7 @@ check_logging (state_t *state) + + ply_trace ("checking if console messages should be redirected and logged"); + +- kernel_no_log = command_line_has_argument (state->kernel_command_line, "plymouth.nolog"); ++ kernel_no_log = ply_kernel_cmd_line_has_argument ("plymouth.nolog"); + if (kernel_no_log) + state->no_boot_log = true; + +@@ -2064,9 +1973,6 @@ initialize_environment (state_t *state) + { + ply_trace ("initializing minimal work environment"); + +- if (!get_kernel_command_line (state)) +- return false; +- + if (!state->default_tty) + if (getenv ("DISPLAY") != NULL && access (PLYMOUTH_PLUGIN_PATH "renderers/x11.so", F_OK) == 0) + state->default_tty = "/dev/tty"; +@@ -2279,11 +2185,8 @@ main (int argc, + if (tty != NULL) + state.default_tty = tty; + +- if (kernel_command_line != NULL) { +- strncpy (state.kernel_command_line, kernel_command_line, sizeof(state.kernel_command_line)); +- state.kernel_command_line[sizeof(state.kernel_command_line) - 1] = '\0'; +- state.kernel_command_line_is_set = true; +- } ++ if (kernel_command_line != NULL) ++ ply_kernel_cmd_line_set (kernel_command_line); + + if (geteuid () != 0) { + ply_error ("plymouthd must be run as root user"); +@@ -2375,10 +2278,10 @@ main (int argc, + find_system_default_splash (&state); + find_distribution_default_splash (&state); + +- if (command_line_has_argument (state.kernel_command_line, "plymouth.ignore-serial-consoles")) ++ if (ply_kernel_cmd_line_has_argument ("plymouth.ignore-serial-consoles")) + device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_IGNORE_SERIAL_CONSOLES; + +- if (command_line_has_argument (state.kernel_command_line, "plymouth.ignore-udev") || ++ if (ply_kernel_cmd_line_has_argument ("plymouth.ignore-udev") || + (getenv ("DISPLAY") != NULL)) + device_manager_flags |= PLY_DEVICE_MANAGER_FLAGS_IGNORE_UDEV; + +-- +2.19.0 + diff --git a/0003-drm-Reset-LUT-gamma-table-before-the-first-drmModeSe.patch b/0003-drm-Reset-LUT-gamma-table-before-the-first-drmModeSe.patch new file mode 100644 index 0000000..08e7790 --- /dev/null +++ b/0003-drm-Reset-LUT-gamma-table-before-the-first-drmModeSe.patch @@ -0,0 +1,123 @@ +From 2da4f7614e5aecb470b748752a3864d2ecae365a Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 2 Oct 2018 10:26:28 +0200 +Subject: [PATCH 3/5] drm: Reset LUT/gamma table before the first + drmModeSetCrtc call + +When we takeover the kms master from whatever process came before us the +LUT table may be a mess making the graphics funky. So lets reset it once +before our first drmModeSetCrtc call. + +Closes #59 + +Signed-off-by: Hans de Goede +--- + src/plugins/renderers/drm/plugin.c | 40 +++++++++++++++++++++++++++--- + 1 file changed, 37 insertions(+), 3 deletions(-) + +diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c +index 1080590..6e6b520 100644 +--- a/src/plugins/renderers/drm/plugin.c ++++ b/src/plugins/renderers/drm/plugin.c +@@ -84,6 +84,9 @@ struct _ply_renderer_head + uint32_t encoder_id; + uint32_t console_buffer_id; + uint32_t scan_out_buffer_id; ++ ++ int gamma_size; ++ uint16_t *gamma; + }; + + struct _ply_renderer_input_source +@@ -451,11 +454,13 @@ ply_renderer_head_new (ply_renderer_backend_t *backend, + int connector_mode_index, + uint32_t encoder_id, + uint32_t controller_id, +- uint32_t console_buffer_id) ++ uint32_t console_buffer_id, ++ int gamma_size) + { + ply_renderer_head_t *head; + drmModeModeInfo *mode; +- int rotation; ++ unsigned int shift; ++ int i, rotation; + + head = calloc (1, sizeof(ply_renderer_head_t)); + +@@ -476,6 +481,20 @@ ply_renderer_head_new (ply_renderer_backend_t *backend, + head->area.width = mode->hdisplay; + head->area.height = mode->vdisplay; + ++ if (gamma_size) { ++ head->gamma_size = gamma_size; ++ head->gamma = malloc(gamma_size * 3 * sizeof(uint16_t)); ++ ++ /* gamma_size is always a power of 2 */ ++ for (shift = 0; (gamma_size << shift) < (1 << 16); shift++); ++ ++ for (i = 0; i < gamma_size; i++) { ++ head->gamma[0 * gamma_size + i] = i << shift; /* red */ ++ head->gamma[1 * gamma_size + i] = i << shift; /* green */ ++ head->gamma[2 * gamma_size + i] = i << shift; /* blue */ ++ } ++ } ++ + ply_renderer_head_add_connector (head, connector, connector_mode_index); + assert (ply_array_get_size (head->connector_ids) > 0); + +@@ -502,6 +521,7 @@ ply_renderer_head_free (ply_renderer_head_t *head) + + drmModeFreeConnector (head->connector0); + ply_array_free (head->connector_ids); ++ free (head->gamma); + free (head); + } + +@@ -601,6 +621,18 @@ ply_renderer_head_set_scan_out_buffer (ply_renderer_backend_t *backend, + ply_trace ("Setting scan out buffer of %ldx%ld head to our buffer", + head->area.width, head->area.height); + ++ /* Set gamma table, do this only once */ ++ if (head->gamma) { ++ drmModeCrtcSetGamma (backend->device_fd, ++ head->controller_id, ++ head->gamma_size, ++ head->gamma + 0 * head->gamma_size, ++ head->gamma + 1 * head->gamma_size, ++ head->gamma + 2 * head->gamma_size); ++ free (head->gamma); ++ head->gamma = NULL; ++ } ++ + /* Tell the controller to use the allocated scan out buffer on each connectors + */ + if (drmModeSetCrtc (backend->device_fd, head->controller_id, buffer_id, +@@ -1024,6 +1056,7 @@ create_heads_for_active_connectors (ply_renderer_backend_t *backend) + uint32_t controller_id; + uint32_t console_buffer_id; + int connector_mode_index; ++ int gamma_size; + + connector = drmModeGetConnector (backend->device_fd, + backend->resources->connectors[i]); +@@ -1069,6 +1102,7 @@ create_heads_for_active_connectors (ply_renderer_backend_t *backend) + } + + console_buffer_id = controller->buffer_id; ++ gamma_size = controller->gamma_size; + drmModeFreeCrtc (controller); + + head = ply_hashtable_lookup (heads_by_controller_id, +@@ -1077,7 +1111,7 @@ create_heads_for_active_connectors (ply_renderer_backend_t *backend) + if (head == NULL) { + head = ply_renderer_head_new (backend, connector, connector_mode_index, + encoder_id, controller_id, +- console_buffer_id); ++ console_buffer_id, gamma_size); + + ply_list_append_data (backend->heads, head); + +-- +2.19.0 + diff --git a/0004-drm-Refactor-ply_renderer_connector_get_rotation.patch b/0004-drm-Refactor-ply_renderer_connector_get_rotation.patch new file mode 100644 index 0000000..0bc50cd --- /dev/null +++ b/0004-drm-Refactor-ply_renderer_connector_get_rotation.patch @@ -0,0 +1,144 @@ +From 8db07cf2629d3a211b78c24b676f803703b1ec1f Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 2 Oct 2018 14:13:19 +0200 +Subject: [PATCH 4/5] drm: Refactor ply_renderer_connector_get_rotation + +ply_renderer_connector_get_rotation walks over all properties to add +support for selecting the preferred mode we also want to know if a connector +is part of a tiled output or not, which also requires walking over the props. + +This commit refactors ply_renderer_connector_get_rotation into +ply_renderer_connector_get_rotation_and_tiled to prepare for this. + +While at also properly use ply_pixel_buffer_rotation_t for the orientation +instead of an int. + +Signed-off-by: Hans de Goede +--- + src/plugins/renderers/drm/plugin.c | 52 +++++++++++++++++------------- + 1 file changed, 30 insertions(+), 22 deletions(-) + +diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c +index 6e6b520..2d90ecb 100644 +--- a/src/plugins/renderers/drm/plugin.c ++++ b/src/plugins/renderers/drm/plugin.c +@@ -376,7 +376,7 @@ destroy_output_buffer (ply_renderer_backend_t *backend, + ply_renderer_buffer_free (backend, buffer); + } + +-static int ++static ply_pixel_buffer_rotation_t + connector_orientation_prop_to_rotation (drmModePropertyPtr prop, + int orientation) + { +@@ -398,12 +398,17 @@ connector_orientation_prop_to_rotation (drmModePropertyPtr prop, + return PLY_PIXEL_BUFFER_ROTATE_UPRIGHT; + } + +-static int +-ply_renderer_connector_get_rotation (ply_renderer_backend_t *backend, +- drmModeConnector *connector) ++static void ++ply_renderer_connector_get_rotation_and_tiled (ply_renderer_backend_t *backend, ++ drmModeConnector *connector, ++ ply_pixel_buffer_rotation_t *rotation, ++ bool *tiled) + { + drmModePropertyPtr prop; +- int i, rotation; ++ int i; ++ ++ *rotation = PLY_PIXEL_BUFFER_ROTATE_UPRIGHT; ++ *tiled = false; + + for (i = 0; i < connector->count_props; i++) { + prop = drmModeGetProperty (backend->device_fd, connector->props[i]); +@@ -411,16 +416,15 @@ ply_renderer_connector_get_rotation (ply_renderer_backend_t *backend, + continue; + + if ((prop->flags & DRM_MODE_PROP_ENUM) && +- strcmp (prop->name, "panel orientation") == 0) { +- rotation = connector_orientation_prop_to_rotation (prop, connector->prop_values[i]); +- drmModeFreeProperty (prop); +- return rotation; +- } ++ strcmp (prop->name, "panel orientation") == 0) ++ *rotation = connector_orientation_prop_to_rotation (prop, connector->prop_values[i]); ++ ++ if ((prop->flags & DRM_MODE_PROP_BLOB) && ++ strcmp (prop->name, "TILE") == 0) ++ *tiled = true; + + drmModeFreeProperty (prop); + } +- +- return PLY_PIXEL_BUFFER_ROTATE_UPRIGHT; + } + + static bool +@@ -449,18 +453,19 @@ ply_renderer_head_add_connector (ply_renderer_head_t *head, + } + + static ply_renderer_head_t * +-ply_renderer_head_new (ply_renderer_backend_t *backend, +- drmModeConnector *connector, +- int connector_mode_index, +- uint32_t encoder_id, +- uint32_t controller_id, +- uint32_t console_buffer_id, +- int gamma_size) ++ply_renderer_head_new (ply_renderer_backend_t *backend, ++ drmModeConnector *connector, ++ int connector_mode_index, ++ uint32_t encoder_id, ++ uint32_t controller_id, ++ uint32_t console_buffer_id, ++ int gamma_size, ++ ply_pixel_buffer_rotation_t rotation) + { + ply_renderer_head_t *head; + drmModeModeInfo *mode; + unsigned int shift; +- int i, rotation; ++ int i; + + head = calloc (1, sizeof(ply_renderer_head_t)); + +@@ -498,7 +503,6 @@ ply_renderer_head_new (ply_renderer_backend_t *backend, + ply_renderer_head_add_connector (head, connector, connector_mode_index); + assert (ply_array_get_size (head->connector_ids) > 0); + +- rotation = ply_renderer_connector_get_rotation (backend, connector); + head->pixel_buffer = ply_pixel_buffer_new_with_device_rotation (head->area.width, head->area.height, rotation); + ply_pixel_buffer_set_device_scale (head->pixel_buffer, + ply_get_device_scale (head->area.width, +@@ -1057,6 +1061,8 @@ create_heads_for_active_connectors (ply_renderer_backend_t *backend) + uint32_t console_buffer_id; + int connector_mode_index; + int gamma_size; ++ ply_pixel_buffer_rotation_t rotation; ++ bool tiled; + + connector = drmModeGetConnector (backend->device_fd, + backend->resources->connectors[i]); +@@ -1092,6 +1098,8 @@ create_heads_for_active_connectors (ply_renderer_backend_t *backend) + + controller_id = controller->crtc_id; + ++ ply_renderer_connector_get_rotation_and_tiled (backend, connector, &rotation, &tiled); ++ + connector_mode_index = get_index_of_active_mode (backend, controller, connector); + + /* If we couldn't find the current active mode, fall back to the first available. +@@ -1111,7 +1119,7 @@ create_heads_for_active_connectors (ply_renderer_backend_t *backend) + if (head == NULL) { + head = ply_renderer_head_new (backend, connector, connector_mode_index, + encoder_id, controller_id, +- console_buffer_id, gamma_size); ++ console_buffer_id, gamma_size, rotation); + + ply_list_append_data (backend->heads, head); + +-- +2.19.0 + diff --git a/0005-drm-Use-preferred-mode-for-outputs-instead-of-curren.patch b/0005-drm-Use-preferred-mode-for-outputs-instead-of-curren.patch new file mode 100644 index 0000000..21944cf --- /dev/null +++ b/0005-drm-Use-preferred-mode-for-outputs-instead-of-curren.patch @@ -0,0 +1,126 @@ +From 65fce3926d6519b2991f67097517c1614c8fc535 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Tue, 2 Oct 2018 11:44:28 +0200 +Subject: [PATCH 5/5] drm: Use preferred mode for outputs instead of current + mode + +When enumerating outputs pick the preferred mode instead of the current +active mode, which may be e.g. a very low res mode. + +Sofar we've been relying on fbcon setting up the modes for us, but as +mentioned in https://bugs.freedesktop.org/show_bug.cgi?id=101520#c22 +we really should not rely on this. + +With the recent flickerfree boot changes we can no longer rely on fbcon +to do the setup for us, hence this commit. For now this commit only +changes the mode-picking logic on UEFI setups as we only have +flickerfree boot there. Once the setup code is more mature we should +probably always use it. + +Closes #68 + +Signed-off-by: Hans de Goede +--- + src/plugins/renderers/drm/plugin.c | 51 ++++++++++++++++++++++++++++-- + 1 file changed, 49 insertions(+), 2 deletions(-) + +diff --git a/src/plugins/renderers/drm/plugin.c b/src/plugins/renderers/drm/plugin.c +index 2d90ecb..e72f6c6 100644 +--- a/src/plugins/renderers/drm/plugin.c ++++ b/src/plugins/renderers/drm/plugin.c +@@ -137,6 +137,7 @@ struct _ply_renderer_backend + + uint32_t is_active : 1; + uint32_t requires_explicit_flushing : 1; ++ uint32_t use_preferred_mode : 1; + }; + + ply_renderer_plugin_interface_t *ply_renderer_backend_get_interface (void); +@@ -149,6 +150,31 @@ static bool reset_scan_out_buffer_if_needed (ply_renderer_backend_t *backend, + static void flush_head (ply_renderer_backend_t *backend, + ply_renderer_head_t *head); + ++/* A small helper to determine if we should try to keep the current mode ++ * or pick the best mode ourselves, we keep the current mode if: ++ * 1. The user specified a specific mode using video= on the commandline ++ * 2. The code to pick the best mode was added because with flicker-free boot ++ * we can no longer rely on the kernel's fbcon code setting things up. ++ * We should be able to do a better job then fbcon regardless, but for ++ * now lets only use the new code on flicker-free systems until it is ++ * more mature, this means only using it on UEFI systems. ++ */ ++static bool ++should_use_preferred_mode (void) ++{ ++ bool use_preferred_mode = true; ++ ++ if (ply_kernel_cmd_line_get_string_after_prefix ("video=")) ++ use_preferred_mode = false; ++ ++ if (access("/sys/firmware/efi/efivars/", F_OK) != 0) ++ use_preferred_mode = false; ++ ++ ply_trace ("should_use_preferred_mode: %d", use_preferred_mode); ++ ++ return use_preferred_mode; ++} ++ + static bool + ply_renderer_buffer_map (ply_renderer_backend_t *backend, + ply_renderer_buffer_t *buffer) +@@ -779,6 +805,7 @@ create_backend (const char *device_name, + backend->requires_explicit_flushing = true; + backend->output_buffers = ply_hashtable_new (ply_hashtable_direct_hash, + ply_hashtable_direct_compare); ++ backend->use_preferred_mode = should_use_preferred_mode(); + + return backend; + } +@@ -1027,6 +1054,22 @@ find_index_of_mode (ply_renderer_backend_t *backend, + return -1; + } + ++static int ++get_index_of_preferred_mode (drmModeConnector *connector) ++{ ++ int i; ++ ++ for (i = 0; i < connector->count_modes; i++) ++ if (connector->modes[i].type & DRM_MODE_TYPE_PREFERRED) { ++ ply_trace("Found preferred mode %dx%d at index %d\n", ++ connector->modes[i].hdisplay, ++ connector->modes[i].vdisplay, i); ++ return i; ++ } ++ ++ return -1; ++} ++ + static int + get_index_of_active_mode (ply_renderer_backend_t *backend, + drmModeCrtc *controller, +@@ -1059,7 +1102,7 @@ create_heads_for_active_connectors (ply_renderer_backend_t *backend) + drmModeCrtc *controller; + uint32_t controller_id; + uint32_t console_buffer_id; +- int connector_mode_index; ++ int connector_mode_index = -1; + int gamma_size; + ply_pixel_buffer_rotation_t rotation; + bool tiled; +@@ -1100,7 +1143,11 @@ create_heads_for_active_connectors (ply_renderer_backend_t *backend) + + ply_renderer_connector_get_rotation_and_tiled (backend, connector, &rotation, &tiled); + +- connector_mode_index = get_index_of_active_mode (backend, controller, connector); ++ if (!tiled && backend->use_preferred_mode) ++ connector_mode_index = get_index_of_preferred_mode (connector); ++ ++ if (connector_mode_index < 0) ++ connector_mode_index = get_index_of_active_mode (backend, controller, connector); + + /* If we couldn't find the current active mode, fall back to the first available. + */ +-- +2.19.0 + diff --git a/plymouth.spec b/plymouth.spec index 5cf2258..fbfa74a 100644 --- a/plymouth.spec +++ b/plymouth.spec @@ -16,7 +16,7 @@ Summary: Graphical Boot Animation and Logger Name: plymouth Version: 0.9.3 -Release: 13%{?snapshot_rel}%{?dist} +Release: 14%{?snapshot_rel}%{?dist} License: GPLv2+ URL: http://www.freedesktop.org/wiki/Software/Plymouth @@ -51,6 +51,14 @@ Patch14: 0005-main-Show-details-when-ESC-is-pressed-during-splash_.patch Patch15: 0006-main-Fix-getting-detailed-logs-from-systemd.patch Patch16: 0007-main-fix-build.patch +# Patches from upstream git to set the mode to the preferred mode, +# addressing: https://gitlab.freedesktop.org/plymouth/plymouth/issues/68 +Patch17: 0001-main-ensure-tty-is-closed-on-deactivate.patch +Patch18: 0002-libply-Move-kernel-commandline-parsing-functions-to-.patch +Patch19: 0003-drm-Reset-LUT-gamma-table-before-the-first-drmModeSe.patch +Patch20: 0004-drm-Refactor-ply_renderer_connector_get_rotation.patch +Patch21: 0005-drm-Use-preferred-mode-for-outputs-instead-of-curren.patch + BuildRequires: gcc BuildRequires: pkgconfig(libdrm) BuildRequires: pkgconfig(libudev) @@ -453,6 +461,11 @@ fi %files system-theme %changelog +* Thu Oct 04 2018 Hans de Goede - 0.9.3-14 +- Add patches from upstream to fix the disk unlock screen sometimes having + a very low resolution on UEFI machines: + https://gitlab.freedesktop.org/plymouth/plymouth/issues/68 + * Mon Aug 06 2018 Hans de Goede - 0.9.3-13 - Update patches for CONFIG_FRAMEBUFFER_CONSOLE_DEFERRED_TAKEOVER interaction to the latest patches from master, this fixes the transition from plymouth