2010-07-07 11:12:45 +00:00
From 1319de907e12d28894d8db0b3215a0443ff4bd5d Mon Sep 17 00:00:00 2001
From: Egbert Eich <eich@suse.de>
Date: Thu, 22 Oct 2009 13:32:11 +0200
Subject: [PATCH] Cleanup and make boot splash work with KMS
References: bnc#544645
Patch-mainline: not yet
- Fix API: remove unneeded function argument
- Remove unneeded function splash_putc().
- Remove need for 2 framebuffer basis: when swiching from silent to
verbose rely on update_region() to redraw the verbose picture.
This removes the need to double the framebuffer size when using
splash.
- Use worker to switch to verbose mode.
- Add support for 24 and 32bpp (24bpp still disabled due to lack of testing).
Acked-by: Michal Marek <mmarek@suse.cz>
---
2011-04-19 20:09:59 +00:00
drivers/tty/vt/vt.c | 10
2010-07-07 11:12:45 +00:00
drivers/video/bootsplash/bootsplash.c | 407 +++++++++++++++++++++---------
drivers/video/bootsplash/bootsplash.h | 23 -
drivers/video/bootsplash/decode-jpg.c | 50 +++
drivers/video/bootsplash/render.c | 451 +++++++++++++++++++++-------------
drivers/video/console/bitblit.c | 12
drivers/video/console/fbcon.c | 4
drivers/video/vesafb.c | 8
include/linux/fb.h | 3
9 files changed, 652 insertions(+), 316 deletions(-)
2011-04-19 20:09:59 +00:00
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -4216,7 +4216,7 @@ void vcs_scr_updated(struct vc_data *vc)
2010-07-07 11:12:45 +00:00
#ifdef CONFIG_BOOTSPLASH
void con_remap_def_color(struct vc_data *vc, int new_color)
{
- unsigned short *sbuf = vc->vc_screenbuf;
+ unsigned short *sbuf = screenpos(vc, 0, 1);
unsigned c, len = vc->vc_screenbuf_size >> 1;
int old_color;
2011-04-19 20:09:59 +00:00
@@ -4224,11 +4224,13 @@ void con_remap_def_color(struct vc_data
2010-07-07 11:12:45 +00:00
old_color = vc->vc_def_color << 8;
new_color <<= 8;
while(len--) {
- c = *sbuf;
+ c = scr_readw(sbuf);
if (((c ^ old_color) & 0xf000) == 0)
- *sbuf ^= (old_color ^ new_color) & 0xf000;
+ scr_writew(c ^ ((old_color ^ new_color) & 0xf000), sbuf);
+ *sbuf ^= (old_color ^ new_color) & 0xf000;
if (((c ^ old_color) & 0x0f00) == 0)
- *sbuf ^= (old_color ^ new_color) & 0x0f00;
+ scr_writew(c ^ ((old_color ^ new_color) & 0x0f00), sbuf);
+ *sbuf ^= (old_color ^ new_color) & 0x0f00;
sbuf++;
}
new_color >>= 8;
--- a/drivers/video/bootsplash/bootsplash.c
+++ b/drivers/video/bootsplash/bootsplash.c
@@ -19,6 +19,8 @@
#include <linux/vmalloc.h>
#include <linux/unistd.h>
#include <linux/syscalls.h>
+#include <linux/console.h>
+#include <linux/workqueue.h>
#include <asm/irq.h>
#include <asm/system.h>
@@ -27,7 +29,12 @@
#include "bootsplash.h"
#include "decode-jpg.h"
-extern struct fb_ops vesafb_ops;
+#ifndef DEBUG
+# define SPLASH_DEBUG(fmt, args...)
+#else
+# define SPLASH_DEBUG(fmt, args...) \
+ printk(KERN_WARNING "%s: " fmt "\n",__FUNCTION__, ##args)
+#endif
extern signed char con2fb_map[MAX_NR_CONSOLES];
#define SPLASH_VERSION "3.1.6-2004/03/31"
@@ -113,18 +120,20 @@ static int boxextract(unsigned char *buf
return 12;
}
-static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num, int percent, int overpaint)
+static void boxit(unsigned char *pic, int bytes, unsigned char *buf, int num, int percent, int overpaint, int octpp)
{
- int x, y, i, p, doblend, r, g, b, a, add;
+ int x, y, p, doblend, r, g, b, a, add;
+ unsigned int i = 0;
unsigned short data1[4];
unsigned char cols1[16];
unsigned short data2[4];
unsigned char cols2[16];
unsigned char *bufend;
- unsigned short *picp;
+ union pt picp;
unsigned int stipple[32], sti, stin, stinn, stixs, stixe, stiys, stiye;
int xs, xe, ys, ye, xo, yo;
+ SPLASH_DEBUG();
if (num == 0)
return;
bufend = buf + num * 12;
@@ -236,11 +245,21 @@ static void boxit(unsigned char *pic, in
}
add = (xs & 1);
add ^= (add ^ y) & 1 ? 1 : 3; /* 2x2 ordered dithering */
- picp = (unsigned short *)(pic + xs * 2 + y * bytes);
+ picp.ub = (pic + xs * octpp + y * bytes);
for (x = xs; x <= xe; x++) {
if (!(sti & 0x80000000)) {
sti <<= 1;
- picp++;
+ switch (octpp) {
+ case 2:
+ picp.us++;
+ break;
+ case 3:
+ picp.ub += 3;
+ break;
+ case 4:
+ picp.ul++;
+ break;
+ }
add ^= 3;
continue;
}
@@ -255,18 +274,37 @@ static void boxit(unsigned char *pic, in
r = cols2[0];
g = cols2[1];
b = cols2[2];
- if (a != 255) {
- i = *picp;
- r = ((i >> 8 & 0xf8) * (255 - a) + r * a) / 255;
- g = ((i >> 3 & 0xfc) * (255 - a) + g * a) / 255;
- b = ((i << 3 & 0xf8) * (255 - a) + b * a) / 255;
- }
- #define CLAMP(x) ((x) >= 256 ? 255 : (x))
- i = ((CLAMP(r + add*2+1) & 0xf8) << 8) |
- ((CLAMP(g + add ) & 0xfc) << 3) |
- ((CLAMP(b + add*2+1) ) >> 3);
- *picp++ = i;
- add ^= 3;
+#define CLAMP(x) ((x) >= 256 ? 255 : (x))
+ switch (octpp) {
+ case 2:
+ i = *picp.us;
+ if (a != 255) {
+ r = ((i >> 8 & 0xf8) * (255 - a) + r * a) / 255;
+ g = ((i >> 3 & 0xfc) * (255 - a) + g * a) / 255;
+ b = ((i << 3 & 0xf8) * (255 - a) + b * a) / 255;
+ }
+ i = ((CLAMP(r + add*2+1) & 0xf8) << 8) |
+ ((CLAMP(g + add ) & 0xfc) << 3) |
+ ((CLAMP(b + add*2+1) ) >> 3);
+ *(picp.us++) = i;
+ break;
+ case 3:
+ *(picp.ub++) = CLAMP(a == 255 ? r : (((i & 0xff) * (255 - a) + r * a) / 255));
+ *(picp.ub++) = CLAMP(a == 255 ? r : (((i >> 8 & 0xff) * (255 - a) + r * a) / 255));
+ *(picp.ub++) = CLAMP(a == 255 ? r : (((i >> 16 & 0xff) * (255 - a) + r * a) / 255));
+ break;
+ case 4:
+ i = *picp.ul;
+ if (a != 255) {
+ r = ((i >> 16 & 0xff) * (255 - a) + r * a) / 255;
+ g = ((i >> 8 & 0xff) * (255 - a) + r * a) / 255;
+ b = ((i & 0xff) * (255 - a) + r * a) / 255;
+ }
+ i = ((CLAMP(r) << 16) | (CLAMP(g) << 8) | (CLAMP(b)));
+ *(picp.ul++) = i;
+ break;
+ }
+ add ^= 3;
}
}
}
@@ -293,16 +331,14 @@ static int splash_check_jpeg(unsigned ch
static void splash_free(struct vc_data *vc, struct fb_info *info)
{
- if (!vc->vc_splash_data)
- return;
- if (info->silent_screen_base)
- info->screen_base = info->silent_screen_base;
- info->silent_screen_base = 0;
- if (vc->vc_splash_data->splash_silentjpeg)
- vfree(vc->vc_splash_data->splash_sboxes);
- vfree(vc->vc_splash_data);
- vc->vc_splash_data = 0;
- info->splash_data = 0;
+ SPLASH_DEBUG();
+ if (!vc->vc_splash_data)
+ return;
+ if (vc->vc_splash_data->splash_silentjpeg)
+ vfree(vc->vc_splash_data->splash_sboxes);
+ vfree(vc->vc_splash_data);
+ vc->vc_splash_data = 0;
+ info->splash_data = 0;
}
static int splash_mkpenguin(struct splash_data *data, int pxo, int pyo, int pwi, int phe, int pr, int pg, int pb)
@@ -590,37 +626,69 @@ static int splash_getraw(unsigned char *
return -1;
}
-int splash_verbose(void)
+int splash_do_verbose(void)
{
- struct vc_data *vc;
- struct fb_info *info;
+ struct vc_data *vc;
+ struct fb_info *info;
+ int ret = 0;
- if (!splash_usesilent)
- return 0;
+ SPLASH_DEBUG();
+ if (!oops_in_progress)
2011-04-19 20:09:59 +00:00
+ console_lock();
2010-07-07 11:12:45 +00:00
- vc = vc_cons[0].d;
+ if (!splash_usesilent)
+ goto done;
- if (!vc || !vc->vc_splash_data || !vc->vc_splash_data->splash_state)
- return 0;
- if (fg_console != vc->vc_num)
- return 0;
- if (!vc->vc_splash_data->splash_silentjpeg || !vc->vc_splash_data->splash_dosilent)
- return 0;
- vc->vc_splash_data->splash_dosilent = 0;
- info = registered_fb[(int)con2fb_map[0]];
- if (!info->silent_screen_base)
+ vc = vc_cons[0].d;
+
+ if (!vc || !vc->vc_splash_data || !vc->vc_splash_data->splash_state)
+ goto done;
+ if (fg_console != vc->vc_num)
+ goto done;
+ if (!vc->vc_splash_data->splash_silentjpeg)
+ goto done;
+
+ if(!vc->vc_splash_data->splash_dosilent)
+ goto done;
+ vc->vc_splash_data->splash_dosilent = 0;
+
+ info = registered_fb[(int)con2fb_map[0]];
+
+ if (!info->splash_data)
+ goto done;
+
+ update_region(vc,
+ vc->vc_origin + vc->vc_size_row * vc->vc_top,
+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
+ splash_clear_margins(vc, info, 0);
+ ret = 0;
+
+ done:
+ if (!oops_in_progress)
2011-04-19 20:09:59 +00:00
+ console_unlock();
2010-07-07 11:12:45 +00:00
+
+ return ret;
+}
+
+static void splash_verbose_callback(struct work_struct *ignored)
+{
+ splash_do_verbose();
+}
+
+static DECLARE_WORK(splash_work, splash_verbose_callback);
+
+int splash_verbose(void)
+{
+ if (!oops_in_progress)
+ schedule_work(&splash_work);
+ else
+ return splash_do_verbose();
return 0;
- splashcopy(info->silent_screen_base, info->screen_base, info->var.yres, info->var.xres, info->fix.line_length, info->fix.line_length);
- info->screen_base = info->silent_screen_base;
- info->silent_screen_base = 0;
- return 1;
}
static void splash_off(struct fb_info *info)
{
- if (info->silent_screen_base)
- info->screen_base = info->silent_screen_base;
- info->silent_screen_base = 0;
+ SPLASH_DEBUG();
info->splash_data = 0;
if (info->splash_pic)
vfree(info->splash_pic);
@@ -631,8 +699,9 @@ static void splash_off(struct fb_info *i
int splash_prepare(struct vc_data *vc, struct fb_info *info)
{
int err;
- int width, height, depth, size, sbytes;
+ int width, height, depth, octpp, size, sbytes;
+ SPLASH_DEBUG("vc_num: %i", vc->vc_num);
if (!vc->vc_splash_data || !vc->vc_splash_data->splash_state) {
if (decdata)
vfree(decdata);
@@ -644,15 +713,19 @@ int splash_prepare(struct vc_data *vc, s
width = info->var.xres;
height = info->var.yres;
depth = info->var.bits_per_pixel;
- if (depth != 16) { /* Other targets might need fixing */
+ octpp = (depth + 1) >> 3;
+
+ if (depth == 24 || depth < 15) { /* Other targets might need fixing */
splash_off(info);
return -2;
}
- sbytes = ((width + 15) & ~15) * (depth >> 3);
+ sbytes = ((width + 15) & ~15) * octpp;
size = sbytes * ((height + 15) & ~15);
- if (size != info->splash_pic_size)
- splash_off(info);
+ if (size != info->splash_pic_size) {
+ vfree(info->splash_pic);
+ info->splash_pic = NULL;
+ }
if (!info->splash_pic)
info->splash_pic = vmalloc(size);
@@ -668,38 +741,52 @@ int splash_prepare(struct vc_data *vc, s
if (vc->vc_splash_data->splash_silentjpeg && vc->vc_splash_data->splash_dosilent) {
/* fill area after framebuffer with other jpeg */
if ((err = jpeg_decode(vc->vc_splash_data->splash_silentjpeg, info->splash_pic,
- ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
- printk(KERN_INFO "bootsplash: error while decompressing silent picture: %s (%d)\n", jpg_errors[err - 1], err);
- if (info->silent_screen_base)
- info->screen_base = info->silent_screen_base;
+ ((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
+ printk(KERN_INFO "bootsplash: error while decompressing silent picture: %s (%d)\n",
+ jpg_errors[err - 1], err);
vc->vc_splash_data->splash_dosilent = 0;
} else {
if (vc->vc_splash_data->splash_sboxcount)
- boxit(info->splash_pic, sbytes, vc->vc_splash_data->splash_sboxes,
- vc->vc_splash_data->splash_sboxcount, vc->vc_splash_data->splash_percent, 0);
-
- if (!info->silent_screen_base)
- info->silent_screen_base = info->screen_base;
- splashcopy(info->silent_screen_base, info->splash_pic, info->var.yres, info->var.xres, info->fix.line_length, sbytes);
- info->screen_base = info->silent_screen_base + info->fix.line_length * info->var.yres;
+ boxit(info->splash_pic,
+ sbytes,
+ vc->vc_splash_data->splash_sboxes,
+ vc->vc_splash_data->splash_sboxcount,
+ vc->vc_splash_data->splash_percent,
+ 0,
+ octpp);
+ splashcopy(info->screen_base,
+ info->splash_pic,
+ info->var.yres,
+ info->var.xres,
+ info->fix.line_length, sbytes,
+ octpp );
}
- } else if (info->silent_screen_base)
- info->screen_base = info->silent_screen_base;
+ } else
+ vc->vc_splash_data->splash_dosilent = 0;
if ((err = jpeg_decode(vc->vc_splash_data->splash_jpeg, info->splash_pic,
((width + 15) & ~15), ((height + 15) & ~15), depth, decdata))) {
- printk(KERN_INFO "bootsplash: error while decompressing picture: %s (%d) .\n", jpg_errors[err - 1], err);
+ printk(KERN_INFO "bootsplash: error while decompressing picture: %s (%d) .\n",
+ jpg_errors[err - 1], err);
splash_off(info);
return -4;
}
info->splash_pic_size = size;
- info->splash_bytes = sbytes;
+ info->splash_pic_stride = sbytes;
if (vc->vc_splash_data->splash_boxcount)
- boxit(info->splash_pic, sbytes, vc->vc_splash_data->splash_boxes, vc->vc_splash_data->splash_boxcount, vc->vc_splash_data->splash_percent, 0);
+ boxit(info->splash_pic,
+ sbytes,
+ vc->vc_splash_data->splash_boxes,
+ vc->vc_splash_data->splash_boxcount,
+ vc->vc_splash_data->splash_percent,
+ 0,
+ octpp);
if (vc->vc_splash_data->splash_state)
info->splash_data = vc->vc_splash_data;
- else
+ else {
splash_off(info);
+ return -5;
+ }
return 0;
}
@@ -720,6 +807,7 @@ static struct proc_dir_entry *proc_splas
static int splash_recolor(struct vc_data *vc)
{
+ SPLASH_DEBUG();
if (!vc->vc_splash_data)
return -1;
if (!vc->vc_splash_data->splash_state)
@@ -736,20 +824,27 @@ static int splash_recolor(struct vc_data
static int splash_status(struct vc_data *vc)
{
struct fb_info *info;
- printk(KERN_INFO "bootsplash: status on console %d changed to %s\n", vc->vc_num, vc->vc_splash_data && vc->vc_splash_data->splash_state ? "on" : "off");
+ SPLASH_DEBUG("vc_num: %i",vc->vc_num);
+ printk(KERN_INFO "bootsplash: status on console %d changed to %s\n",
+ vc->vc_num,
+ vc->vc_splash_data && vc->vc_splash_data->splash_state ? "on" : "off");
info = registered_fb[(int) con2fb_map[vc->vc_num]];
+
if (fg_console == vc->vc_num)
splash_prepare(vc, info);
if (vc->vc_splash_data && vc->vc_splash_data->splash_state) {
- con_remap_def_color(vc, vc->vc_splash_data->splash_color << 4 | vc->vc_splash_data->splash_fg_color);
- /* vc_resize also calls con_switch which resets yscroll */
- vc_resize(vc, vc->vc_splash_data->splash_text_wi / vc->vc_font.width, vc->vc_splash_data->splash_text_he / vc->vc_font.height);
- if (fg_console == vc->vc_num) {
- update_region(vc,
- vc->vc_origin + vc->vc_size_row * vc->vc_top,
- vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
- splash_clear_margins(vc->vc_splash_data, vc, info, 0);
+ if (info->splash_data) {
+ con_remap_def_color(vc, info->splash_data->splash_color << 4 | info->splash_data->splash_fg_color);
+ /* vc_resize also calls con_switch which resets yscroll */
+ vc_resize(vc, info->splash_data->splash_text_wi / vc->vc_font.width,
+ info->splash_data->splash_text_he / vc->vc_font.height);
+ if (fg_console == vc->vc_num) {
+ update_region(vc,
+ vc->vc_origin + vc->vc_size_row * vc->vc_top,
+ vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
+ splash_clear_margins(vc, info, 0);
+ }
}
} else {
/* Switch bootsplash off */
@@ -787,6 +882,8 @@ void splash_set_percent(struct vc_data *
struct fbcon_ops *ops;
int oldpe;
+ SPLASH_DEBUG();
+
if (pe < 0)
pe = 0;
if (pe > 65535)
@@ -805,15 +902,38 @@ void splash_set_percent(struct vc_data *
ops = info->fbcon_par;
if (ops->blank_state)
return;
- if (!vc->vc_splash_data->splash_overpaintok || pe == 65536 || pe < oldpe) {
- if (splash_hasinter(vc->vc_splash_data->splash_boxes, vc->vc_splash_data->splash_boxcount))
- splash_status(vc);
- else
- splash_prepare(vc, info);
+ if (!vc->vc_splash_data->splash_overpaintok
+ || pe == 65536
+ || pe < oldpe) {
+ if (splash_hasinter(vc->vc_splash_data->splash_boxes,
+ vc->vc_splash_data->splash_boxcount)) {
+ splash_status(vc);
+ }
+ else
+ splash_prepare(vc, info);
} else {
- if (vc->vc_splash_data->splash_silentjpeg && vc->vc_splash_data->splash_dosilent && info->silent_screen_base)
- boxit(info->silent_screen_base, info->fix.line_length, vc->vc_splash_data->splash_sboxes, vc->vc_splash_data->splash_sboxcount, vc->vc_splash_data->splash_percent, 1);
- boxit(info->screen_base, info->fix.line_length, vc->vc_splash_data->splash_boxes, vc->vc_splash_data->splash_boxcount, vc->vc_splash_data->splash_percent, 1);
+ int octpp = (info->var.bits_per_pixel + 1) >> 3;
+ if (info->splash_data) {
+ if ( info->splash_data->splash_silentjpeg
+ && info->splash_data->splash_dosilent)
+ boxit(info->screen_base,
+ info->fix.line_length,
+ info->splash_data->splash_sboxes,
+ info->splash_data->splash_sboxcount,
+ info->splash_data->splash_percent,
+ 1,
+ octpp);
+#if 0
+ if (!info->splash_dosilent)
+ boxit(info->screen_base,
+ info->fix.line_length,
+ info->splash_data->splash_boxes,
+ info->splash_data->splash_boxcount,
+ info->splash_data->splash_percent,
+ 1,
+ octpp);
+#endif
+ }
}
}
@@ -823,6 +943,8 @@ static int splash_write_proc(struct file
int new, unit;
struct vc_data *vc;
+ SPLASH_DEBUG();
+
if (!buffer || !splash_default)
return count;
@@ -842,8 +964,10 @@ static int splash_write_proc(struct file
return count;
}
}
+ SPLASH_DEBUG(" unit: %i",unit);
vc = vc_cons[unit].d;
if (!strncmp(buffer, "redraw", 6)) {
+ SPLASH_DEBUG( " redraw");
splash_status(vc);
2011-04-19 20:09:59 +00:00
console_unlock();
2010-07-07 11:12:45 +00:00
return count;
@@ -851,6 +975,7 @@ static int splash_write_proc(struct file
if (!strncmp(buffer, "show", 4) || !strncmp(buffer, "hide", 4)) {
int pe;
+ SPLASH_DEBUG( " show/hide");
if (buffer[4] == ' ' && buffer[5] == 'p')
pe = 0;
else if (buffer[4] == '\n')
@@ -867,51 +992,77 @@ static int splash_write_proc(struct file
2011-04-19 20:09:59 +00:00
console_unlock();
2010-07-07 11:12:45 +00:00
return count;
}
+
if (!strncmp(buffer,"silent\n",7) || !strncmp(buffer,"verbose\n",8)) {
+ SPLASH_DEBUG( " silent/verbose");
if (vc->vc_splash_data && vc->vc_splash_data->splash_silentjpeg) {
- if (vc->vc_splash_data->splash_dosilent != (buffer[0] == 's')) {
- vc->vc_splash_data->splash_dosilent = buffer[0] == 's';
- splash_status(vc);
- }
+ if (vc->vc_splash_data->splash_dosilent != (buffer[0] == 's')) {
+ vc->vc_splash_data->splash_dosilent = buffer[0] == 's';
+ splash_status(vc);
+ }
}
2011-04-19 20:09:59 +00:00
console_unlock();
2010-07-07 11:12:45 +00:00
return count;
}
if (!strncmp(buffer,"freesilent\n",11)) {
+ SPLASH_DEBUG( " freesilent");
if (vc->vc_splash_data && vc->vc_splash_data->splash_silentjpeg) {
- printk(KERN_INFO "bootsplash: freeing silent jpeg\n");
- vc->vc_splash_data->splash_silentjpeg = 0;
- vfree(vc->vc_splash_data->splash_sboxes);
- vc->vc_splash_data->splash_sboxes = 0;
- vc->vc_splash_data->splash_sboxcount = 0;
- if (vc->vc_splash_data->splash_dosilent)
- splash_status(vc);
- vc->vc_splash_data->splash_dosilent = 0;
+ printk(KERN_INFO "bootsplash: freeing silent jpeg\n");
+ vc->vc_splash_data->splash_silentjpeg = 0;
+ vfree(vc->vc_splash_data->splash_sboxes);
+ vc->vc_splash_data->splash_sboxes = 0;
+ vc->vc_splash_data->splash_sboxcount = 0;
+ if (vc->vc_splash_data->splash_dosilent) {
+ splash_status(vc);
+ }
+ vc->vc_splash_data->splash_dosilent = 0;
}
2011-04-19 20:09:59 +00:00
console_unlock();
2010-07-07 11:12:45 +00:00
return count;
}
-
if (!strncmp(buffer, "BOOTSPL", 7)) {
- int up = -1;
- unit = splash_getraw((unsigned char *)buffer, (unsigned char *)buffer + count, &up);
- if (unit >= 0) {
- vc = vc_cons[unit].d;
- if (up == -1)
- splash_status(vc);
- else {
- struct fb_info *info = registered_fb[(int) con2fb_map[vc->vc_num]];
- struct fbcon_ops *ops = info->fbcon_par;
- if (ops->blank_state)
- up = 0;
- if ((up & 2) != 0 && vc->vc_splash_data->splash_silentjpeg && vc->vc_splash_data->splash_dosilent && info->silent_screen_base)
- boxit(info->silent_screen_base, info->fix.line_length, vc->vc_splash_data->splash_sboxes, vc->vc_splash_data->splash_sboxcount, vc->vc_splash_data->splash_percent, 1);
- if ((up & 1) != 0)
- boxit(info->screen_base, info->fix.line_length, vc->vc_splash_data->splash_boxes, vc->vc_splash_data->splash_boxcount, vc->vc_splash_data->splash_percent, 1);
+ int up = -1;
+
+ SPLASH_DEBUG( " BOOTSPL");
+ unit = splash_getraw((unsigned char *)buffer,
+ (unsigned char *)buffer + count,
+ &up);
+ SPLASH_DEBUG( " unit: %i up: %i",unit,up);
+ if (unit >= 0) {
+ struct fb_info *info;
+
+ vc = vc_cons[unit].d;
+ info = registered_fb[(int) con2fb_map[vc->vc_num]];
+ if (up == -1) {
+ splash_status(vc);
+ } else {
+ struct fbcon_ops *ops = info->fbcon_par;
+ int octpp = (info->var.bits_per_pixel + 1) >> 3;
+ if (ops->blank_state || !vc->vc_splash_data || !info->splash_data)
+ up = 0;
+ if ((up & 2) != 0
+ && info->splash_data->splash_silentjpeg
+ && info->splash_data->splash_dosilent) {
+ boxit(info->screen_base,
+ info->fix.line_length,
+ info->splash_data->splash_sboxes,
+ info->splash_data->splash_sboxcount,
+ info->splash_data->splash_percent,
+ 1,
+ octpp);
+ } else if ((up & 1) != 0) {
+ boxit(info->screen_base,
+ info->fix.line_length,
+ info->splash_data->splash_boxes,
+ info->splash_data->splash_boxcount,
+ info->splash_data->splash_percent,
+ 1,
+ octpp);
+ }
+ }
}
- }
2011-04-19 20:09:59 +00:00
- console_unlock();
2010-07-07 11:12:45 +00:00
- return count;
2011-04-19 20:09:59 +00:00
+ console_unlock();
2010-07-07 11:12:45 +00:00
+ return count;
}
if (!vc->vc_splash_data) {
2011-04-19 20:09:59 +00:00
console_unlock();
2010-07-07 11:12:45 +00:00
@@ -919,6 +1070,7 @@ static int splash_write_proc(struct file
}
if (buffer[0] == 't') {
vc->vc_splash_data->splash_state ^= 1;
+ SPLASH_DEBUG(" t");
splash_status(vc);
2011-04-19 20:09:59 +00:00
console_unlock();
2010-07-07 11:12:45 +00:00
return count;
@@ -959,6 +1111,8 @@ static int splash_proc_unregister(void)
# endif
#endif /* CONFIG_PROC_FS */
+#define INIT_CONSOLE 0
+
void splash_init(void)
{
struct fb_info *info;
@@ -971,9 +1125,12 @@ void splash_init(void)
if (splash_registered)
return;
- vc = vc_cons[0].d;
- info = registered_fb[0];
- if (!vc || !info || info->var.bits_per_pixel != 16)
+ vc = vc_cons[INIT_CONSOLE].d;
+ info = registered_fb[(int)con2fb_map[INIT_CONSOLE]];
+ if (!vc
+ || !info
+ || info->var.bits_per_pixel == 24 /* not tested */
+ || info->var.bits_per_pixel < 15) /* not supported */
return;
#ifdef CONFIG_PROC_FS
splash_proc_register();
@@ -1004,7 +1161,9 @@ void splash_init(void)
mem = vmalloc(len);
if (mem) {
2011-04-19 20:09:59 +00:00
console_lock();
2010-07-07 11:12:45 +00:00
- if ((int)sys_read(fd, mem, len) == len && splash_getraw((unsigned char *)mem, (unsigned char *)mem + len, (int *)0) == 0 && vc->vc_splash_data)
+ if ((int)sys_read(fd, mem, len) == len
+ && splash_getraw((unsigned char *)mem, (unsigned char *)mem + len, (int *)0) == INIT_CONSOLE
+ && vc->vc_splash_data)
vc->vc_splash_data->splash_state = splash_default & 1;
2011-04-19 20:09:59 +00:00
console_unlock();
2010-07-07 11:12:45 +00:00
vfree(mem);
--- a/drivers/video/bootsplash/bootsplash.h
+++ b/drivers/video/bootsplash/bootsplash.h
@@ -12,27 +12,30 @@
#define __BOOTSPLASH_H
struct fb_info;
+union pt {
+ u32 *ul;
+ u16 *us;
+ u8 *ub;
+};
/* splash.c */
extern int splash_prepare(struct vc_data *, struct fb_info *);
extern void splash_init(void);
/* splash_render.c */
-extern void splash_putcs(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
+extern void splash_putcs(struct vc_data *vc, struct fb_info *info,
const unsigned short *s, int count, int ypos, int xpos);
-extern void splash_putc(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
- int c, int ypos, int xpos);
-extern void splashcopy(u8 *dst, u8 *src, int height, int width, int dstbytes, int srcbytes);
-extern void splash_clear(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int sy,
+extern void splashcopy(u8 *dst, u8 *src, int height, int width, int dstbytes, int srcbytes, int depth);
+extern void splash_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width);
-extern void splash_bmove(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int sy,
+extern void splash_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width);
-extern void splash_clear_margins(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
+extern void splash_clear_margins(struct vc_data *vc, struct fb_info *info,
int bottom_only);
-extern int splash_cursor(struct splash_data *sd, struct fb_info *info, struct fb_cursor *cursor);
-extern void splash_bmove_redraw(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
+extern int splash_cursor(struct fb_info *info, struct fb_cursor *cursor);
+extern void splash_bmove_redraw(struct vc_data *vc, struct fb_info *info,
int y, int sx, int dx, int width);
-extern void splash_blank(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
+extern void splash_blank(struct vc_data *vc, struct fb_info *info,
int blank);
/* vt.c */
--- a/drivers/video/bootsplash/decode-jpg.c
+++ b/drivers/video/bootsplash/decode-jpg.c
@@ -86,6 +86,7 @@ static void initcol __P((PREC[][64]));
static void col221111 __P((int *, unsigned char *, int));
static void col221111_16 __P((int *, unsigned char *, int));
+static void col221111_32 __P((int *, unsigned char *, int));
/*********************************/
@@ -369,6 +370,9 @@ struct jpeg_decdata *decdata;
idct(decdata->dcts + 320, decdata->out + 320, decdata->dquant[2], IFIX(0.5), max[5]);
switch (depth) {
+ case 32:
+ col221111_32(decdata->out, pic + (my * 16 * mcusx + mx) * 16 * 4, mcusx * 16 * 4);
+ break;
case 24:
col221111(decdata->out, pic + (my * 16 * mcusx + mx) * 16 * 3, mcusx * 16 * 3);
break;
@@ -882,6 +886,15 @@ PREC q[][64];
#endif
#endif
+#define PIC_32(yin, xin, p, xout) \
+( \
+ y = outy[(yin) * 8 + xin], \
+ STORECLAMP(p[(xout) * 4 + 0], y + cr), \
+ STORECLAMP(p[(xout) * 4 + 1], y - cg), \
+ STORECLAMP(p[(xout) * 4 + 2], y + cb), \
+ p[(xout) * 4 + 3] = 0 \
+)
+
#define PIC221111(xin) \
( \
CBCRCG(0, xin), \
@@ -900,6 +913,15 @@ PREC q[][64];
PIC_16(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1, 2) \
)
+#define PIC221111_32(xin) \
+( \
+ CBCRCG(0, xin), \
+ PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 0, pic0, xin * 2 + 0),\
+ PIC_32(xin / 4 * 8 + 0, (xin & 3) * 2 + 1, pic0, xin * 2 + 1),\
+ PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 0, pic1, xin * 2 + 0),\
+ PIC_32(xin / 4 * 8 + 1, (xin & 3) * 2 + 1, pic1, xin * 2 + 1) \
+)
+
static void col221111(out, pic, width)
int *out;
unsigned char *pic;
@@ -949,6 +971,34 @@ int width;
}
outc += 8;
outy += 16;
+ pic0 += 2 * width;
+ pic1 += 2 * width;
+ }
+ outy += 64 * 2 - 16 * 4;
+ }
+}
+
+static void col221111_32(out, pic, width)
+int *out;
+unsigned char *pic;
+int width;
+{
+ int i, j, k;
+ unsigned char *pic0, *pic1;
+ int *outy, *outc;
+ int cr, cg, cb, y;
+
+ pic0 = pic;
+ pic1 = pic + width;
+ outy = out;
+ outc = out + 64 * 4;
+ for (i = 2; i > 0; i--) {
+ for (j = 4; j > 0; j--) {
+ for (k = 0; k < 8; k++) {
+ PIC221111_32(k);
+ }
+ outc += 8;
+ outy += 16;
pic0 += 2 * width;
pic1 += 2 * width;
}
--- a/drivers/video/bootsplash/render.c
+++ b/drivers/video/bootsplash/render.c
@@ -13,82 +13,131 @@
#include "../console/fbcon.h"
#include "bootsplash.h"
-void splash_putcs(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
- const unsigned short *s, int count, int ypos, int xpos)
-{
- unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
- int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
- u8 *src;
- u8 *dst, *splashsrc;
- unsigned int d, x, y;
- u32 dd, fgx, bgx;
- u16 c = scr_readw(s);
+#ifndef DEBUG
+# define SPLASH_DEBUG(fmt, args...)
+#else
+# define SPLASH_DEBUG(fmt, args...) \
+ printk(KERN_WARNING "%s: " fmt "\n",__FUNCTION__, ##args)
+#endif
- int fg_color, bg_color, transparent;
- if (console_blanked)
- return;
- fg_color = attr_fgcol(fgshift, c);
- bg_color = attr_bgcol(bgshift, c);
- transparent = sd->splash_color == bg_color;
- xpos = xpos * vc->vc_font.width + sd->splash_text_xo;
- ypos = ypos * vc->vc_font.height + sd->splash_text_yo;
- splashsrc = (u8 *)(info->splash_pic + ypos * info->splash_bytes + xpos * 2);
- dst = (u8 *)(info->screen_base + ypos * info->fix.line_length + xpos * 2);
-
- fgx = ((u32 *)info->pseudo_palette)[fg_color];
- if (transparent && sd->splash_color == 15) {
- if (fgx == 0xffea)
- fgx = 0xfe4a;
- else if (fgx == 0x57ea)
- fgx = 0x0540;
- else if (fgx == 0xffff)
- fgx = 0x52aa;
- }
- bgx = ((u32 *)info->pseudo_palette)[bg_color];
- d = 0;
-
- while (count--) {
- c = scr_readw(s++);
- src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * ((vc->vc_font.width + 7) >> 3);
-
- for (y = 0; y < vc->vc_font.height; y++) {
- for (x = 0; x < vc->vc_font.width; x += 2) {
- if ((x & 7) == 0)
- d = *src++;
- if (d & 0x80)
- dd = fgx;
- else
- dd = transparent ? *(u16 *)splashsrc : bgx;
- splashsrc += 2;
- if (d & 0x40)
- dd |= fgx << 16;
- else
- dd |= (transparent ? *(u16 *)splashsrc : bgx) << 16;
- splashsrc += 2;
- d <<= 2;
- fb_writel(dd, dst);
- dst += 4;
- }
- dst += info->fix.line_length - vc->vc_font.width * 2;
- splashsrc += info->splash_bytes - vc->vc_font.width * 2;
- }
- dst -= info->fix.line_length * vc->vc_font.height - vc->vc_font.width * 2;
- splashsrc -= info->splash_bytes * vc->vc_font.height - vc->vc_font.width * 2;
- }
-}
-
-static void splash_renderc(struct splash_data *sd, struct fb_info *info, int fg_color, int bg_color, u8 *src, int ypos, int xpos, int height, int width)
+void splash_putcs(struct vc_data *vc, struct fb_info *info,
+ const unsigned short *s, int count, int ypos, int xpos)
+{
+ struct splash_data *sd;
+ unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
+ int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
+ int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
+ union pt src;
+ union pt dst, splashsrc;
+ unsigned int d, x, y;
+ u32 dd, fgx, bgx;
+ u16 c = scr_readw(s);
+ int fg_color, bg_color, transparent;
+ int n;
+ int octpp = (info->var.bits_per_pixel + 1) >> 3;
+
+ if (!oops_in_progress && (console_blanked || info->splash_data->splash_dosilent))
+ return;
+ sd = info->splash_data;
+
+ fg_color = attr_fgcol(fgshift, c);
+ bg_color = attr_bgcol(bgshift, c);
+ transparent = sd->splash_color == bg_color;
+ xpos = xpos * vc->vc_font.width + sd->splash_text_xo;
+ ypos = ypos * vc->vc_font.height + sd->splash_text_yo;
+ splashsrc.ub = (u8 *)(info->splash_pic + ypos * info->splash_pic_stride + xpos * octpp);
+ dst.ub = (u8 *)(info->screen_base + ypos * info->fix.line_length + xpos * octpp);
+ fgx = ((u32 *)info->pseudo_palette)[fg_color];
+ if (transparent && sd->splash_color == 15) {
+ if (fgx == 0xffea)
+ fgx = 0xfe4a;
+ else if (fgx == 0x57ea)
+ fgx = 0x0540;
+ else if (fgx == 0xffff)
+ fgx = 0x52aa;
+ }
+ bgx = ((u32 *)info->pseudo_palette)[bg_color];
+ d = 0;
+ while (count--) {
+ c = scr_readw(s++);
+ src.ub = vc->vc_font.data + (c & charmask) * vc->vc_font.height * ((vc->vc_font.width + 7) >> 3);
+ for (y = 0; y < vc->vc_font.height; y++) {
+ for (x = 0; x < vc->vc_font.width; ) {
+ if ((x & 7) == 0)
+ d = *src.ub++;
+ switch (octpp) {
+ case 2:
+ if (d & 0x80)
+ dd = fgx;
+ else
+ dd = transparent ? *splashsrc.us : bgx;
+ splashsrc.us += 1;
+ if (d & 0x40)
+ dd |= fgx << 16;
+ else
+ dd |= (transparent ? *splashsrc.us : bgx) << 16;
+ splashsrc.us += 1;
+ d <<= 2;
+ x += 2;
+ fb_writel(dd, dst.ul);
+ dst.ul += 1;
+ break;
+ case 3:
+ for (n = 0; n <= 16; n += 8) {
+ if (d & 0x80)
+ dd = (fgx >> n) && 0xff;
+ else
+ dd = (transparent ? *splashsrc.ul : ((bgx >> n) & 0xff) );
+ splashsrc.ub += 1;
+ fb_writeb(dd, dst.ub);
+ dst.ub += 1;
+ }
+ d <<= 1;
+ x += 1;
+ break;
+ case 4:
+ if (d & 0x80)
+ dd = fgx;
+ else
+ dd = (transparent ? *splashsrc.ul : bgx);
+ splashsrc.ul += 1;
+ d <<= 1;
+ x += 1;
+ fb_writel(dd, dst.ul);
+ dst.ul += 1;
+ break;
+ }
+ }
+ dst.ub += info->fix.line_length - vc->vc_font.width * octpp;
+ splashsrc.ub += info->splash_pic_stride - vc->vc_font.width * octpp;
+ }
+ dst.ub -= info->fix.line_length * vc->vc_font.height - vc->vc_font.width * octpp;
+ splashsrc.ub -= info->splash_pic_stride * vc->vc_font.height - vc->vc_font.width * octpp;
+ }
+}
+
+static void splash_renderc(struct fb_info *info,
+ int fg_color, int bg_color,
+ u8 *src,
+ int ypos, int xpos,
+ int height, int width)
{
- int transparent = sd->splash_color == bg_color;
+ struct splash_data *sd;
+ int transparent;
u32 dd, fgx, bgx;
- u8 *dst, *splashsrc;
+ union pt dst, splashsrc;
unsigned int d, x, y;
+ int n;
+ int octpp = (info->var.bits_per_pixel + 1) >> 3;
- if (console_blanked)
- return;
- splashsrc = (u8 *)(info->splash_pic + ypos * info->splash_bytes + xpos * 2);
- dst = (u8 *)(info->screen_base + ypos * info->fix.line_length + xpos * 2);
+ if (!oops_in_progress && (console_blanked || info->splash_data->splash_dosilent))
+ return;
+
+ sd = info->splash_data;
+
+ transparent = sd->splash_color == bg_color;
+ splashsrc.ub = (u8*)(info->splash_pic + ypos * info->splash_pic_stride + xpos * octpp);
+ dst.ub = (u8*)(info->screen_base + ypos * info->fix.line_length + xpos * octpp);
fgx = ((u32 *)info->pseudo_palette)[fg_color];
if (transparent && sd->splash_color == 15) {
if (fgx == 0xffea)
@@ -101,93 +150,136 @@ static void splash_renderc(struct splash
bgx = ((u32 *)info->pseudo_palette)[bg_color];
d = 0;
for (y = 0; y < height; y++) {
- for (x = 0; x < width; x += 2) {
- if ((x & 7) == 0)
- d = *src++;
- if (d & 0x80)
- dd = fgx;
- else
- dd = transparent ? *(u16 *)splashsrc : bgx;
- splashsrc += 2;
- if (d & 0x40)
- dd |= fgx << 16;
- else
- dd |= (transparent ? *(u16 *)splashsrc : bgx) << 16;
- splashsrc += 2;
- d <<= 2;
- fb_writel(dd, dst);
- dst += 4;
- }
- dst += info->fix.line_length - width * 2;
- splashsrc += info->splash_bytes - width * 2;
+ for (x = 0; x < width; ) {
+ if ((x & 7) == 0)
+ d = *src++;
+ switch (octpp) {
+ case 2:
+ if (d & 0x80)
+ dd = fgx;
+ else
+ dd = transparent ? *splashsrc.us : bgx;
+ splashsrc.us += 1;
+ if (d & 0x40)
+ dd |= fgx << 16;
+ else
+ dd |= (transparent ? *splashsrc.us : bgx) << 16;
+ splashsrc.us += 1;
+ d <<= 2;
+ x += 2;
+ fb_writel(dd, dst.ul);
+ dst.ul += 1;
+ break;
+ case 3:
+ for (n = 0; n <= 16; n += 8) {
+ if (d & 0x80)
+ dd = (fgx >> n) & 0xff;
+ else
+ dd = transparent ? *splashsrc.ub : bgx;
+ splashsrc.ub += 1;
+ fb_writeb(dd, dst.ub);
+ dst.ub += 1;
+ }
+ d <<= 1;
+ x += 1;
+ break;
+ case 4:
+ if (d & 0x80)
+ dd = fgx;
+ else
+ dd = transparent ? *splashsrc.ul : bgx;
+ splashsrc.ul += 1;
+ d <<= 1;
+ x += 1;
+ fb_writel(dd, dst.ul);
+ dst.ul += 1;
+ break;
+ }
+ }
+ dst.ub += info->fix.line_length - width * octpp;
+ splashsrc.ub += info->splash_pic_stride - width * octpp;
}
}
-void splash_putc(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
- int c, int ypos, int xpos)
-{
- unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
- int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
- int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
- u8 *src = vc->vc_font.data + (c & charmask) * vc->vc_font.height * ((vc->vc_font.width + 7) >> 3);
- xpos = xpos * vc->vc_font.width + sd->splash_text_xo;
- ypos = ypos * vc->vc_font.height + sd->splash_text_yo;
- splash_renderc(sd, info, attr_fgcol(fgshift, c), attr_bgcol(bgshift, c), src, ypos, xpos, vc->vc_font.height, vc->vc_font.width);
-}
-
-void splashcopy(u8 *dst, u8 *src, int height, int width, int dstbytes, int srcbytes)
+void splashcopy(u8 *dst, u8 *src, int height, int width, int dstbytes, int srcbytes, int octpp)
{
int i;
+ width *= octpp;
while (height-- > 0) {
- u32 *p = (u32 *)dst;
- u32 *q = (u32 *)src;
- for (i=0; i < width/4; i++) {
- fb_writel(*q++,p++);
- fb_writel(*q++,p++);
- }
- if (width & 2)
- fb_writel(*q++,p++);
- if (width & 1)
- fb_writew(*(u16*)q,(u16*)p);
- dst += dstbytes;
- src += srcbytes;
+ union pt p, q;
+ p.ul = (u32 *)dst;
+ q.ul = (u32 *)src;
+ for (i=0; i < width/8; i++) {
+ fb_writel(*q.ul++,p.ul++);
+ fb_writel(*q.ul++,p.ul++);
+ }
+ if (width & 4)
+ fb_writel(*q.ul++,p.ul++);
+ if (width & 2)
+ fb_writew(*q.us++,p.us++);
+ if (width & 1)
+ fb_writeb(*q.ub,p.ub);
+ dst += dstbytes;
+ src += srcbytes;
}
}
-static void splashset(u8 *dst, int height, int width, int dstbytes, u32 bgx) {
+static void splashset(u8 *dst, int height, int width, int dstbytes, u32 bgx, int octpp) {
int i;
- bgx |= bgx << 16;
+ width *= octpp;
+ if (octpp == 2)
+ bgx |= bgx << 16;
while (height-- > 0) {
- u32 *p = (u32 *)dst;
- for (i=0; i < width/4; i++) {
- fb_writel(bgx,p++);
- fb_writel(bgx,p++);
- }
- if (width & 2)
- fb_writel(bgx,p++);
- if (width & 1)
- fb_writew(bgx,(u16*)p);
- dst += dstbytes;
+ union pt p;
+ p.ul = (u32 *)dst;
+ if (octpp != 3) {
+ for (i=0; i < width/8; i++) {
+ fb_writel(bgx,p.ul++);
+ fb_writel(bgx,p.ul++);
+ }
+ if (width & 4)
+ fb_writel(bgx,p.ul++);
+ if (width & 2)
+ fb_writew(bgx,p.us++);
+ if (width & 1)
+ fb_writeb(bgx,p.ub);
+ dst += dstbytes;
+ } else { /* slow! */
+ for (i=0; i < width; i++)
+ fb_writeb((bgx >> ((i & 0x3) * 8)) && 0xff,p.ub++);
+ }
}
}
static void splashfill(struct fb_info *info, int sy, int sx, int height, int width) {
- splashcopy((u8 *)(info->screen_base + sy * info->fix.line_length + sx * 2), (u8 *)(info->splash_pic + sy * info->splash_bytes + sx * 2), height, width, info->fix.line_length, info->splash_bytes);
+ int octpp = (info->var.bits_per_pixel + 1) >> 3;
+
+ splashcopy((u8 *)(info->screen_base + sy * info->fix.line_length + sx * octpp),
+ (u8 *)(info->splash_pic + sy * info->splash_pic_stride + sx * octpp),
+ height, width, info->fix.line_length, info->splash_pic_stride,
+ octpp);
}
-void splash_clear(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int sy,
+void splash_clear(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int height, int width)
{
+ struct splash_data *sd;
int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
int bg_color = attr_bgcol_ec(bgshift, vc, info);
- int transparent = sd->splash_color == bg_color;
+ int transparent;
+ int octpp = (info->var.bits_per_pixel + 1) >> 3;
u32 bgx;
u8 *dst;
- if (console_blanked)
- return;
+ if (!oops_in_progress && (console_blanked || info->splash_data->splash_dosilent))
+ return;
+
+ sd = info->splash_data;
+
+ transparent = sd->splash_color == bg_color;
+
sy = sy * vc->vc_font.height + sd->splash_text_yo;
sx = sx * vc->vc_font.width + sd->splash_text_xo;
height *= vc->vc_font.height;
@@ -196,18 +288,26 @@ void splash_clear(struct splash_data *sd
splashfill(info, sy, sx, height, width);
return;
}
- dst = (u8 *)(info->screen_base + sy * info->fix.line_length + sx * 2);
+ dst = (u8 *)(info->screen_base + sy * info->fix.line_length + sx * octpp);
bgx = ((u32 *)info->pseudo_palette)[bg_color];
- splashset(dst, height, width, info->fix.line_length, bgx);
+ splashset(dst,
+ height, width,
+ info->fix.line_length,
+ bgx,
+ (info->var.bits_per_pixel + 1) >> 3);
}
-void splash_bmove(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int sy,
+void splash_bmove(struct vc_data *vc, struct fb_info *info, int sy,
int sx, int dy, int dx, int height, int width)
{
+ struct splash_data *sd;
struct fb_copyarea area;
- if (console_blanked)
- return;
+ if (!oops_in_progress && (console_blanked || info->splash_data->splash_dosilent))
+ return;
+
+ sd = info->splash_data;
+
area.sx = sx * vc->vc_font.width;
area.sy = sy * vc->vc_font.height;
area.dx = dx * vc->vc_font.width;
@@ -222,34 +322,57 @@ void splash_bmove(struct splash_data *sd
info->fbops->fb_copyarea(info, &area);
}
-void splash_clear_margins(struct splash_data *sd, struct vc_data *vc, struct fb_info *info,
+void splash_clear_margins(struct vc_data *vc, struct fb_info *info,
int bottom_only)
{
+ struct splash_data *sd;
unsigned int tw = vc->vc_cols*vc->vc_font.width;
unsigned int th = vc->vc_rows*vc->vc_font.height;
+ SPLASH_DEBUG();
+
+ if (!oops_in_progress && (console_blanked || info->splash_data->splash_dosilent))
+ return;
+
+ sd = info->splash_data;
- if (console_blanked)
- return;
if (!bottom_only) {
/* top margin */
- splashfill(info, 0, 0, sd->splash_text_yo, info->var.xres);
+ splashfill(info,
+ 0,
+ 0,
+ sd->splash_text_yo,
+ info->var.xres);
/* left margin */
- splashfill(info, sd->splash_text_yo, 0, th, sd->splash_text_xo);
+ splashfill(info,
+ sd->splash_text_yo,
+ 0,
+ th,
+ sd->splash_text_xo);
/* right margin */
- splashfill(info, sd->splash_text_yo, sd->splash_text_xo + tw, th, info->var.xres - sd->splash_text_xo - tw);
-
+ splashfill(info,
+ sd->splash_text_yo,
+ sd->splash_text_xo + tw,
+ th,
+ info->var.xres - sd->splash_text_xo - tw);
}
- splashfill(info, sd->splash_text_yo + th, 0, info->var.yres - sd->splash_text_yo - th, info->var.xres);
+ splashfill(info,
+ sd->splash_text_yo + th,
+ 0,
+ info->var.yres - sd->splash_text_yo - th,
+ info->var.xres);
}
-int splash_cursor(struct splash_data *sd, struct fb_info *info, struct fb_cursor *cursor)
+int splash_cursor(struct fb_info *info, struct fb_cursor *cursor)
{
+ struct splash_data *sd;
int i;
unsigned int dsize, s_pitch;
if (info->state != FBINFO_STATE_RUNNING)
return 0;
+ sd = info->splash_data;
+
s_pitch = (cursor->image.width + 7) >> 3;
dsize = s_pitch * cursor->image.height;
if (cursor->enable) {
@@ -267,13 +390,15 @@ int splash_cursor(struct splash_data *sd
} else if (info->fb_cursordata != cursor->image.data)
memcpy(info->fb_cursordata, cursor->image.data, dsize);
cursor->image.data = info->fb_cursordata;
- splash_renderc(sd, info, cursor->image.fg_color, cursor->image.bg_color, (u8 *)info->fb_cursordata, cursor->image.dy + sd->splash_text_yo, cursor->image.dx + sd->splash_text_xo, cursor->image.height, cursor->image.width);
+ splash_renderc(info, cursor->image.fg_color, cursor->image.bg_color, (u8 *)info->fb_cursordata, cursor->image.dy + sd->splash_text_yo, cursor->image.dx + sd->splash_text_xo, cursor->image.height, cursor->image.width);
return 0;
}
-void splash_bmove_redraw(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width)
+void splash_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width)
{
- unsigned short *d = (unsigned short *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
+ struct splash_data *sd;
+ int octpp = (info->var.bits_per_pixel + 1) >> 3;
+ unsigned short *d = (unsigned short *) (vc->vc_origin + vc->vc_size_row * y + dx * octpp);
unsigned short *s = d + (dx - sx);
unsigned short *start = d;
unsigned short *ls = d;
@@ -282,21 +407,24 @@ void splash_bmove_redraw(struct splash_d
int x = dx;
unsigned short attr = 1;
- if (console_blanked)
+ if (console_blanked || info->splash_data->splash_dosilent)
return;
+
+ sd = info->splash_data;
+
do {
c = scr_readw(d);
if (attr != (c & 0xff00)) {
attr = c & 0xff00;
if (d > start) {
- splash_putcs(sd, vc, info, start, d - start, y, x);
+ splash_putcs(vc, info, start, d - start, y, x);
x += d - start;
start = d;
}
}
if (s >= ls && s < le && c == scr_readw(s)) {
if (d > start) {
- splash_putcs(sd, vc, info, start, d - start, y, x);
+ splash_putcs(vc, info, start, d - start, y, x);
x += d - start + 1;
start = d + 1;
} else {
@@ -308,21 +436,22 @@ void splash_bmove_redraw(struct splash_d
d++;
} while (d < le);
if (d > start)
- splash_putcs(sd, vc, info, start, d - start, y, x);
+ splash_putcs(vc, info, start, d - start, y, x);
}
-void splash_blank(struct splash_data *sd, struct vc_data *vc, struct fb_info *info, int blank)
+void splash_blank(struct vc_data *vc, struct fb_info *info, int blank)
{
+ SPLASH_DEBUG();
if (blank) {
- if (info->silent_screen_base)
- splashset((u8 *)info->silent_screen_base, info->var.yres, info->var.xres, info->fix.line_length, 0);
- splashset((u8 *)info->screen_base, info->var.yres, info->var.xres, info->fix.line_length, 0);
+ splashset((u8 *)info->screen_base,
+ info->var.yres, info->var.xres,
+ info->fix.line_length,
+ 0,
+ (info->var.bits_per_pixel + 1) >> 3);
} else {
- if (info->silent_screen_base)
- splash_prepare(vc, info);
- splash_clear_margins(vc->vc_splash_data, vc, info, 0);
+ // splash_prepare(vc, info); /* do we really need this? */
+ splash_clear_margins(vc, info, 0);
/* no longer needed, done in fbcon_blank */
/* update_screen(vc->vc_num); */
}
}
-
--- a/drivers/video/console/bitblit.c
+++ b/drivers/video/console/bitblit.c
2011-04-19 20:09:59 +00:00
@@ -53,7 +53,7 @@ static void bit_bmove(struct vc_data *vc
2010-07-07 11:12:45 +00:00
#ifdef CONFIG_BOOTSPLASH
if (info->splash_data) {
- splash_bmove(info->splash_data, vc, info,
+ splash_bmove(vc, info,
sy, sx, dy, dx, height, width);
return;
}
2011-04-19 20:09:59 +00:00
@@ -76,8 +76,8 @@ static void bit_clear(struct vc_data *vc
2010-07-07 11:12:45 +00:00
#ifdef CONFIG_BOOTSPLASH
if (info->splash_data) {
- splash_clear(info->splash_data, vc, info,
- sy, sx, height, width);
+ splash_clear(vc, info,
+ sy, sx, height, width);
return;
}
#endif
2011-04-19 20:09:59 +00:00
@@ -180,7 +180,7 @@ static void bit_putcs(struct vc_data *vc
2010-07-07 11:12:45 +00:00
#ifdef CONFIG_BOOTSPLASH
if (info->splash_data) {
- splash_putcs(info->splash_data, vc, info, s, count, yy, xx);
+ splash_putcs(vc, info, s, count, yy, xx);
return;
}
#endif
2011-04-19 20:09:59 +00:00
@@ -240,7 +240,7 @@ static void bit_clear_margins(struct vc_
2010-07-07 11:12:45 +00:00
#ifdef CONFIG_BOOTSPLASH
if (info->splash_data) {
- splash_clear_margins(info->splash_data, vc, info, bottom_only);
+ splash_clear_margins(vc, info, bottom_only);
return;
}
#endif
2011-04-19 20:09:59 +00:00
@@ -413,7 +413,7 @@ static void bit_cursor(struct vc_data *v
2010-07-07 11:12:45 +00:00
#ifdef CONFIG_BOOTSPLASH
if (info->splash_data) {
- splash_cursor(info->splash_data, info, &cursor);
+ splash_cursor(info, &cursor);
ops->cursor_reset = 0;
return;
}
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
2011-04-19 20:09:59 +00:00
@@ -2074,7 +2074,7 @@ static void fbcon_bmove_rec(struct vc_da
2010-07-07 11:12:45 +00:00
#ifdef CONFIG_BOOTSPLASH
if (info->splash_data && sy == dy && height == 1) {
/* must use slower redraw bmove to keep background pic intact */
- splash_bmove_redraw(info->splash_data, vc, info, sy, sx, dx, width);
+ splash_bmove_redraw(vc, info, sy, sx, dx, width);
return;
}
#endif
2011-04-19 20:09:59 +00:00
@@ -2325,7 +2325,7 @@ static void fbcon_generic_blank(struct v
2010-07-07 11:12:45 +00:00
#ifdef CONFIG_BOOTSPLASH
if (info->splash_data) {
- splash_blank(info->splash_data, vc, info, blank);
+ splash_blank(vc, info, blank);
return;
}
#endif
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
2011-04-19 20:09:59 +00:00
@@ -181,10 +181,7 @@ static void vesafb_destroy(struct fb_inf
2010-07-07 11:12:45 +00:00
framebuffer_release(info);
}
-#ifndef CONFIG_BOOTSPLASH
-static
-#endif
-struct fb_ops vesafb_ops = {
+static struct fb_ops vesafb_ops = {
.owner = THIS_MODULE,
.fb_destroy = vesafb_destroy,
.fb_setcolreg = vesafb_setcolreg,
2011-04-19 20:09:59 +00:00
@@ -269,9 +266,6 @@ static int __init vesafb_probe(struct pl
2010-07-07 11:12:45 +00:00
* option to simply use size_total as that
* wastes plenty of kernel address space. */
size_remap = size_vmode * 2;
-#ifdef CONFIG_BOOTSPLASH
- size_remap *= 2; /* some more for the images */
-#endif
if (vram_remap)
size_remap = vram_remap * 1024 * 1024;
if (size_remap < size_vmode)
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
2011-04-19 20:09:59 +00:00
@@ -879,8 +879,7 @@ struct fb_info {
2010-07-07 11:12:45 +00:00
struct splash_data *splash_data;
unsigned char *splash_pic;
int splash_pic_size;
- int splash_bytes;
- char *silent_screen_base; /* real screen base */
+ int splash_pic_stride;
char fb_cursordata[64];
#endif
/* we need the PCI or similiar aperture base/size not