2 * linux/drivers/video/bootsplash/render.c - splash screen render functions.
5 #include <linux/module.h>
6 #include <linux/types.h>
8 #include <linux/vt_kern.h>
9 #include <linux/selection.h>
12 #include "../console/fbcon.h"
13 #include <linux/bootsplash.h>
16 # define SPLASH_DEBUG(fmt, args...)
18 # define SPLASH_DEBUG(fmt, args...) \
19 printk(KERN_WARNING "%s: " fmt "\n", __func__, ##args)
22 /* fake a region sync */
23 void splash_sync_region(struct fb_info *info, int x, int y,
24 int width, int height)
26 struct splash_data *sd = info->splash_data;
27 if (sd && sd->need_sync) {
28 /* issue a fake copyarea (copy to the very same position)
29 * for marking the dirty region; this is required for Xen fb
32 struct fb_copyarea area;
33 area.sx = area.dx = x;
34 area.sy = area.dy = y;
37 info->fbops->fb_copyarea(info, &area);
41 void splash_putcs(struct vc_data *vc, struct fb_info *info,
42 const unsigned short *s, int count, int ypos, int xpos)
44 struct splash_data *sd;
45 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
46 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
47 int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
49 union pt dst, splashsrc;
53 int fg_color, bg_color, transparent;
55 int octpp = (info->var.bits_per_pixel + 1) >> 3;
59 && (console_blanked || info->splash_data->splash_dosilent))
61 sd = info->splash_data;
63 fg_color = attr_fgcol(fgshift, c);
64 bg_color = attr_bgcol(bgshift, c);
65 transparent = sd->imgd->splash_color == bg_color;
66 xpos = xpos * vc->vc_font.width + sd->imgd->splash_text_xo;
67 ypos = ypos * vc->vc_font.height + sd->imgd->splash_text_yo;
68 splashsrc.ub = (u8 *)(sd->pic->splash_pic
69 + ypos * sd->pic->splash_pic_stride
71 dst.ub = (u8 *)(info->screen_base
72 + ypos * info->fix.line_length
74 fgx = ((u32 *)info->pseudo_palette)[fg_color];
75 if (transparent && sd->imgd->splash_color == 15) {
78 else if (fgx == 0x57ea)
80 else if (fgx == 0xffff)
83 bgx = ((u32 *)info->pseudo_palette)[bg_color];
88 src.ub = vc->vc_font.data
91 * ((vc->vc_font.width + 7) >> 3));
92 for (y = 0; y < vc->vc_font.height; y++) {
93 for (x = 0; x < vc->vc_font.width; ) {
102 *splashsrc.us : bgx);
107 dd |= (transparent ? *splashsrc.us : bgx) << 16;
111 fb_writel(dd, dst.ul);
115 for (n = 0; n <= 16; n += 8) {
117 dd = (fgx >> n) & 0xff;
119 dd = (transparent ? *splashsrc.ul : ((bgx >> n) & 0xff));
121 fb_writeb(dd, dst.ub);
131 dd = (transparent ? *splashsrc.ul : bgx);
135 fb_writel(dd, dst.ul);
140 dst.ub += info->fix.line_length
141 - vc->vc_font.width * octpp;
142 splashsrc.ub += sd->pic->splash_pic_stride
143 - vc->vc_font.width * octpp;
145 dst.ub -= info->fix.line_length * vc->vc_font.height
146 - vc->vc_font.width * octpp;
147 splashsrc.ub -= sd->pic->splash_pic_stride * vc->vc_font.height
148 - vc->vc_font.width * octpp;
149 drawn_width += vc->vc_font.width;
151 splash_sync_region(info, xpos, ypos, drawn_width, vc->vc_font.height);
154 static void splash_renderc(struct fb_info *info,
155 int fg_color, int bg_color,
158 int height, int width)
160 struct splash_data *sd;
163 union pt dst, splashsrc;
164 unsigned int d, x, y;
166 int octpp = (info->var.bits_per_pixel + 1) >> 3;
168 if (!oops_in_progress
169 && (console_blanked || info->splash_data->splash_dosilent))
172 sd = info->splash_data;
174 transparent = sd->imgd->splash_color == bg_color;
175 splashsrc.ub = (u8 *)(sd->pic->splash_pic
176 + ypos * sd->pic->splash_pic_stride
178 dst.ub = (u8 *)(info->screen_base
179 + ypos * info->fix.line_length
181 fgx = ((u32 *)info->pseudo_palette)[fg_color];
182 if (transparent && (sd->imgd->splash_color == 15)) {
185 else if (fgx == 0x57ea)
187 else if (fgx == 0xffff)
190 bgx = ((u32 *)info->pseudo_palette)[bg_color];
192 for (y = 0; y < height; y++) {
193 for (x = 0; x < width; ) {
201 dd = (transparent ? *splashsrc.us : bgx);
206 dd |= (transparent ? *splashsrc.us : bgx) << 16;
210 fb_writel(dd, dst.ul);
214 for (n = 0; n <= 16; n += 8) {
216 dd = (fgx >> n) & 0xff;
218 dd = (transparent ? *splashsrc.ub : bgx);
220 fb_writeb(dd, dst.ub);
230 dd = (transparent ? *splashsrc.ul : bgx);
234 fb_writel(dd, dst.ul);
239 dst.ub += info->fix.line_length - width * octpp;
240 splashsrc.ub += sd->pic->splash_pic_stride - width * octpp;
242 splash_sync_region(info, xpos, ypos, width, height);
245 void splashcopy(u8 *dst, u8 *src, int height, int width,
246 int dstbytes, int srcbytes, int octpp)
251 while (height-- > 0) {
255 for (i = 0; i < width / 4; i++)
256 fb_writel(*q.ul++, p.ul++);
258 fb_writew(*q.us++, p.us++);
260 fb_writeb(*q.ub, p.ub);
266 static void splashset(u8 *dst, int height, int width,
267 int dstbytes, u32 bgx, int octpp) {
273 while (height-- > 0) {
277 for (i = 0; i < width / 4; i++)
278 fb_writel(bgx, p.ul++);
280 fb_writew(bgx, p.us++);
282 fb_writeb(bgx, p.ub);
285 for (i = 0; i < width; i++)
286 fb_writeb((bgx >> ((i % 3) * 8)) & 0xff,
292 static void splashfill(struct fb_info *info, int sy, int sx,
293 int height, int width) {
294 int octpp = (info->var.bits_per_pixel + 1) >> 3;
295 struct splash_data *sd = info->splash_data;
297 splashcopy((u8 *)(info->screen_base
298 + sy * info->fix.line_length + sx * octpp),
299 (u8 *)(sd->pic->splash_pic
300 + sy * sd->pic->splash_pic_stride
302 height, width, info->fix.line_length,
303 sd->pic->splash_pic_stride,
305 splash_sync_region(info, sx, sy, width, height);
308 void splash_clear(struct vc_data *vc, struct fb_info *info, int sy,
309 int sx, int height, int width)
311 struct splash_data *sd;
312 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
313 int bg_color = attr_bgcol_ec(bgshift, vc, info);
315 int octpp = (info->var.bits_per_pixel + 1) >> 3;
319 if (!oops_in_progress
320 && (console_blanked || info->splash_data->splash_dosilent))
323 sd = info->splash_data;
325 transparent = sd->imgd->splash_color == bg_color;
327 sy = sy * vc->vc_font.height + sd->imgd->splash_text_yo;
328 sx = sx * vc->vc_font.width + sd->imgd->splash_text_xo;
329 height *= vc->vc_font.height;
330 width *= vc->vc_font.width;
332 splashfill(info, sy, sx, height, width);
335 dst = (u8 *)(info->screen_base
336 + sy * info->fix.line_length
338 bgx = ((u32 *)info->pseudo_palette)[bg_color];
341 info->fix.line_length,
343 (info->var.bits_per_pixel + 1) >> 3);
344 splash_sync_region(info, sx, sy, width, height);
347 void splash_bmove(struct vc_data *vc, struct fb_info *info, int sy,
348 int sx, int dy, int dx, int height, int width)
350 struct splash_data *sd;
351 struct fb_copyarea area;
353 if (!oops_in_progress
354 && (console_blanked || info->splash_data->splash_dosilent))
357 sd = info->splash_data;
359 area.sx = sx * vc->vc_font.width;
360 area.sy = sy * vc->vc_font.height;
361 area.dx = dx * vc->vc_font.width;
362 area.dy = dy * vc->vc_font.height;
363 area.sx += sd->imgd->splash_text_xo;
364 area.sy += sd->imgd->splash_text_yo;
365 area.dx += sd->imgd->splash_text_xo;
366 area.dy += sd->imgd->splash_text_yo;
367 area.height = height * vc->vc_font.height;
368 area.width = width * vc->vc_font.width;
370 info->fbops->fb_copyarea(info, &area);
373 void splash_clear_margins(struct vc_data *vc, struct fb_info *info,
376 struct splash_data *sd;
377 unsigned int tw = vc->vc_cols*vc->vc_font.width;
378 unsigned int th = vc->vc_rows*vc->vc_font.height;
381 if (!oops_in_progress
382 && (console_blanked || info->splash_data->splash_dosilent))
385 sd = info->splash_data;
392 sd->imgd->splash_text_yo,
396 sd->imgd->splash_text_yo,
399 sd->imgd->splash_text_xo);
402 sd->imgd->splash_text_yo,
403 sd->imgd->splash_text_xo + tw,
405 info->var.xres - sd->imgd->splash_text_xo - tw);
408 sd->imgd->splash_text_yo + th,
410 info->var.yres - sd->imgd->splash_text_yo - th,
414 int splash_cursor(struct fb_info *info, struct fb_cursor *cursor)
416 struct splash_data *sd;
418 unsigned int dsize, s_pitch;
420 if (info->state != FBINFO_STATE_RUNNING)
423 sd = info->splash_data;
425 s_pitch = (cursor->image.width + 7) >> 3;
426 dsize = s_pitch * cursor->image.height;
427 if (cursor->enable) {
428 switch (cursor->rop) {
430 for (i = 0; i < dsize; i++)
431 info->fb_cursordata[i] = cursor->image.data[i]
436 for (i = 0; i < dsize; i++)
437 info->fb_cursordata[i] = cursor->image.data[i]
441 } else if (info->fb_cursordata != cursor->image.data)
442 memcpy(info->fb_cursordata, cursor->image.data, dsize);
443 cursor->image.data = info->fb_cursordata;
444 splash_renderc(info, cursor->image.fg_color, cursor->image.bg_color,
445 (u8 *)info->fb_cursordata,
446 cursor->image.dy + sd->imgd->splash_text_yo,
447 cursor->image.dx + sd->imgd->splash_text_xo,
448 cursor->image.height,
449 cursor->image.width);
453 void splash_bmove_redraw(struct vc_data *vc, struct fb_info *info,
454 int y, int sx, int dx, int width)
456 struct splash_data *sd;
457 unsigned short *d = (unsigned short *) (vc->vc_origin
458 + vc->vc_size_row * y
460 unsigned short *s = d + (dx - sx);
461 unsigned short *start = d;
462 unsigned short *ls = d;
463 unsigned short *le = d + width;
466 unsigned short attr = 1;
468 if (console_blanked || info->splash_data->splash_dosilent)
471 sd = info->splash_data;
475 if (attr != (c & 0xff00)) {
478 splash_putcs(vc, info, start, d - start, y, x);
483 if (s >= ls && s < le && c == scr_readw(s)) {
485 splash_putcs(vc, info, start, d - start, y, x);
497 splash_putcs(vc, info, start, d - start, y, x);
500 void splash_blank(struct vc_data *vc, struct fb_info *info, int blank)
505 splashset((u8 *)info->screen_base,
506 info->var.yres, info->var.xres,
507 info->fix.line_length,
509 (info->var.bits_per_pixel + 1) >> 3);
510 splash_sync_region(info, 0, 0, info->var.xres, info->var.yres);
512 /* splash_prepare(vc, info); *//* do we really need this? */
513 splash_clear_margins(vc, info, 0);
514 /* no longer needed, done in fbcon_blank */
515 /* update_screen(vc->vc_num); */