Created
January 23, 2021 17:37
-
-
Save VinDuv/ccfa293f8a665512fc3e87ab05902bee to your computer and use it in GitHub Desktop.
Display the boot logo at a smaller size for low-power CPUs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c | |
index 8268bbee8..708c1846e 100644 | |
--- a/drivers/video/fbdev/core/fbmem.c | |
+++ b/drivers/video/fbdev/core/fbmem.c | |
@@ -45,6 +45,8 @@ | |
#define FBPIXMAPSIZE (1024 * 8) | |
+#define RESIZE_RATIO 75 | |
+ | |
static DEFINE_MUTEX(registration_lock); | |
struct fb_info *registered_fb[FB_MAX] __read_mostly; | |
@@ -416,6 +418,36 @@ static void fb_rotate_logo(struct fb_info *info, u8 *dst, | |
image->data = dst; | |
} | |
+#ifdef CONFIG_LOGO_SMALL | |
+static char* fb_resize_logo(struct fb_image *target, const struct fb_image *source) { | |
+ char* resized_data; | |
+ | |
+ target->dx = 0; | |
+ target->dy = 0; | |
+ target->width = source->width * RESIZE_RATIO / 100; | |
+ target->height = source->height * RESIZE_RATIO / 100; | |
+ target->fg_color = source->fg_color; | |
+ target->bg_color = source->bg_color; | |
+ resized_data = kmalloc_array(target->width, target->height, GFP_KERNEL); | |
+ target->data = resized_data; | |
+ target->cmap = source->cmap; | |
+ | |
+ if (resized_data) { | |
+ int x, y; | |
+ | |
+ for (x = 0 ; x < target->width ; x++) { | |
+ for (y = 0 ; y < target->height ; y++) { | |
+ int target_x = x * 100 / RESIZE_RATIO; | |
+ int target_y = y * 100 / RESIZE_RATIO; | |
+ resized_data[x + y * target->width] = source->data[target_x + target_y * source->width]; | |
+ } | |
+ } | |
+ } | |
+ | |
+ return resized_data; | |
+} | |
+#endif | |
+ | |
static void fb_do_show_logo(struct fb_info *info, struct fb_image *image, | |
int rotate, unsigned int num) | |
{ | |
@@ -457,11 +489,16 @@ static void fb_do_show_logo(struct fb_info *info, struct fb_image *image, | |
static int fb_show_logo_line(struct fb_info *info, int rotate, | |
const struct linux_logo *logo, int y, | |
- unsigned int n) | |
+ unsigned int n, unsigned int n_small | |
+) | |
{ | |
u32 *palette = NULL, *saved_pseudo_palette = NULL; | |
unsigned char *logo_new = NULL, *logo_rotate = NULL; | |
struct fb_image image; | |
+ #ifdef CONFIG_LOGO_SMALL | |
+ struct fb_image small_image; | |
+ unsigned char *small_logo_data = NULL, *small_logo_rotate = NULL; | |
+ #endif | |
/* Return if the frame buffer is not mapped or suspended */ | |
if (logo == NULL || info->state != FBINFO_STATE_RUNNING || | |
@@ -502,6 +539,13 @@ static int fb_show_logo_line(struct fb_info *info, int rotate, | |
fb_set_logo(info, logo, logo_new, fb_logo.depth); | |
} | |
+ image.width = logo->width; | |
+ image.height = logo->height; | |
+ | |
+ #ifdef CONFIG_LOGO_SMALL | |
+ small_logo_data = fb_resize_logo(&small_image, &image); | |
+ #endif | |
+ | |
if (fb_center_logo) { | |
int xres = info->var.xres; | |
int yres = info->var.yres; | |
@@ -513,30 +557,59 @@ static int fb_show_logo_line(struct fb_info *info, int rotate, | |
while (n && (n * (logo->width + 8) - 8 > xres)) | |
--n; | |
- image.dx = (xres - n * (logo->width + 8) - 8) / 2; | |
+ | |
+ // Remaining empty space around the logo | |
+ xres = xres - n * (logo->width + 8) - 8; | |
+ | |
+ #ifdef CONFIG_LOGO_SMALL | |
+ while (n_small && (n_small * (small_image.width + 8) - 8 > xres)) | |
+ --n_small; | |
+ | |
+ xres = xres - n_small * (small_image.width + 8) - 8; | |
+ #endif | |
+ | |
+ image.dx = xres / 2; | |
image.dy = y ?: (yres - logo->height) / 2; | |
} else { | |
image.dx = 0; | |
image.dy = y; | |
} | |
- image.width = logo->width; | |
- image.height = logo->height; | |
+ #ifdef CONFIG_LOGO_SMALL | |
+ small_image.dx = image.dx + n * (logo->width + 8); | |
+ small_image.dy = image.dy + (logo->height - small_image.height); | |
+ #endif | |
if (rotate) { | |
logo_rotate = kmalloc_array(logo->width, logo->height, | |
GFP_KERNEL); | |
- if (logo_rotate) | |
+ if (logo_rotate) { | |
fb_rotate_logo(info, logo_rotate, &image, rotate); | |
+ } | |
+ | |
+ #ifdef CONFIG_LOGO_SMALL | |
+ small_logo_rotate = kmalloc_array(small_image.width, small_image.height, | |
+ GFP_KERNEL); | |
+ if (small_logo_rotate) { | |
+ fb_rotate_logo(info, small_logo_rotate, &small_image, rotate); | |
+ } | |
+ #endif | |
} | |
fb_do_show_logo(info, &image, rotate, n); | |
+ #ifdef CONFIG_LOGO_SMALL | |
+ fb_do_show_logo(info, &small_image, rotate, n_small); | |
+ #endif | |
kfree(palette); | |
if (saved_pseudo_palette != NULL) | |
info->pseudo_palette = saved_pseudo_palette; | |
kfree(logo_new); | |
kfree(logo_rotate); | |
+ #ifdef CONFIG_LOGO_SMALL | |
+ kfree(small_logo_data); | |
+ kfree(small_logo_rotate); | |
+ #endif | |
return image.dy + logo->height; | |
} | |
@@ -590,7 +663,8 @@ static int fb_show_extra_logos(struct fb_info *info, int y, int rotate) | |
for (i = 0; i < fb_logo_ex_num; i++) | |
y = fb_show_logo_line(info, rotate, | |
- fb_logo_ex[i].logo, y, fb_logo_ex[i].n); | |
+ fb_logo_ex[i].logo, y, fb_logo_ex[i].n, | |
+ 0); | |
return y; | |
} | |
@@ -694,7 +768,11 @@ int fb_show_logo(struct fb_info *info, int rotate) | |
return 0; | |
count = fb_logo_count < 0 ? num_online_cpus() : fb_logo_count; | |
- y = fb_show_logo_line(info, rotate, fb_logo.logo, 0, count); | |
+ #ifdef CONFIG_LOGO_SMALL | |
+ y = fb_show_logo_line(info, rotate, fb_logo.logo, 0, count - (count / 2), count / 2); | |
+ #else | |
+ y = fb_show_logo_line(info, rotate, fb_logo.logo, 0, count, 0); | |
+ #endif | |
y = fb_show_extra_logos(info, y, rotate); | |
return y; | |
diff --git a/drivers/video/logo/Kconfig b/drivers/video/logo/Kconfig | |
index 6d6f8c087..d6d7349f9 100644 | |
--- a/drivers/video/logo/Kconfig | |
+++ b/drivers/video/logo/Kconfig | |
@@ -16,6 +16,12 @@ config FB_LOGO_EXTRA | |
depends on FB=y | |
default y if SPU_BASE | |
+config LOGO_SMALL | |
+ bool "Use a smaller logo for low-power CPUs" | |
+ help | |
+ Instead of displaying the normal logo for each CPU in the system, | |
+ use a small version of the logo for system CPUs that are low-power. | |
+ | |
config LOGO_LINUX_MONO | |
bool "Standard black and white Linux logo" | |
default y |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment