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>
11 #include <asm/system.h>
13 #include "../console/fbcon.h"
14 #include <linux/bootsplash.h>
17 # define SPLASH_DEBUG(fmt, args...)
19 # define SPLASH_DEBUG(fmt, args...) \
20 printk(KERN_WARNING "%s: " fmt "\n", __func__, ##args)
23 /* fake a region sync */
24 void splash_sync_region(struct fb_info *info, int x, int y,
25 int width, int height)
27 struct splash_data *sd = info->splash_data;
28 if (sd && sd->need_sync) {
29 /* issue a fake copyarea (copy to the very same position)
30 * for marking the dirty region; this is required for Xen fb
33 struct fb_copyarea area;
34 area.sx = area.dx = x;
35 area.sy = area.dy = y;
38 info->fbops->fb_copyarea(info, &area);
42 void splash_putcs(struct vc_data *vc, struct fb_info *info,
43 const unsigned short *s, int count, int ypos, int xpos)
45 struct splash_data *sd;
46 unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
47 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
48 int fgshift = (vc->vc_hi_font_mask) ? 9 : 8;
50 union pt dst, splashsrc;
54 int fg_color, bg_color, transparent;
56 int octpp = (info->var.bits_per_pixel + 1) >> 3;
60 && (console_blanked || info->splash_data->splash_dosilent))
62 sd = info->splash_data;
64 fg_color = attr_fgcol(fgshift, c);
65 bg_color = attr_bgcol(bgshift, c);
66 transparent = sd->imgd->splash_color == bg_color;
67 xpos = xpos * vc->vc_font.width + sd->imgd->splash_text_xo;
68 ypos = ypos * vc->vc_font.height + sd->imgd->splash_text_yo;
69 splashsrc.ub = (u8 *)(sd->pic->splash_pic
70 + ypos * sd->pic->splash_pic_stride
72 dst.ub = (u8 *)(info->screen_base
73 + ypos * info->fix.line_length
75 fgx = ((u32 *)info->pseudo_palette)[fg_color];
76 if (transparent && sd->imgd->splash_color == 15) {
79 else if (fgx == 0x57ea)
81 else if (fgx == 0xffff)
84 bgx = ((u32 *)info->pseudo_palette)[bg_color];
89 src.ub = vc->vc_font.data
92 * ((vc->vc_font.width + 7) >> 3));
93 for (y = 0; y < vc->vc_font.height; y++) {
94 for (x = 0; x < vc->vc_font.width; ) {
103 *splashsrc.us : bgx);
108 dd |= (transparent ? *splashsrc.us : bgx) << 16;
112 fb_writel(dd, dst.ul);
116 for (n = 0; n <= 16; n += 8) {
118 dd = (fgx >> n) & 0xff;
120 dd = (transparent ? *splashsrc.ul : ((bgx >> n) & 0xff));
122 fb_writeb(dd, dst.ub);
132 dd = (transparent ? *splashsrc.ul : bgx);
136 fb_writel(dd, dst.ul);
141 dst.ub += info->fix.line_length
142 - vc->vc_font.width * octpp;
143 splashsrc.ub += sd->pic->splash_pic_stride
144 - vc->vc_font.width * octpp;
146 dst.ub -= info->fix.line_length * vc->vc_font.height
147 - vc->vc_font.width * octpp;
148 splashsrc.ub -= sd->pic->splash_pic_stride * vc->vc_font.height
149 - vc->vc_font.width * octpp;
150 drawn_width += vc->vc_font.width;
152 splash_sync_region(info, xpos, ypos, drawn_width, vc->vc_font.height);
155 static void splash_renderc(struct fb_info *info,
156 int fg_color, int bg_color,
159 int height, int width)
161 struct splash_data *sd;
164 union pt dst, splashsrc;
165 unsigned int d, x, y;
167 int octpp = (info->var.bits_per_pixel + 1) >> 3;
169 if (!oops_in_progress
170 && (console_blanked || info->splash_data->splash_dosilent))
173 sd = info->splash_data;
175 transparent = sd->imgd->splash_color == bg_color;
176 splashsrc.ub = (u8 *)(sd->pic->splash_pic
177 + ypos * sd->pic->splash_pic_stride
179 dst.ub = (u8 *)(info->screen_base
180 + ypos * info->fix.line_length
182 fgx = ((u32 *)info->pseudo_palette)[fg_color];
183 if (transparent && (sd->imgd->splash_color == 15)) {
186 else if (fgx == 0x57ea)
188 else if (fgx == 0xffff)
191 bgx = ((u32 *)info->pseudo_palette)[bg_color];
193 for (y = 0; y < height; y++) {
194 for (x = 0; x < width; ) {
202 dd = (transparent ? *splashsrc.us : bgx);
207 dd |= (transparent ? *splashsrc.us : bgx) << 16;
211 fb_writel(dd, dst.ul);
215 for (n = 0; n <= 16; n += 8) {
217 dd = (fgx >> n) & 0xff;
219 dd = (transparent ? *splashsrc.ub : bgx);
221 fb_writeb(dd, dst.ub);
231 dd = (transparent ? *splashsrc.ul : bgx);
235 fb_writel(dd, dst.ul);
240 dst.ub += info->fix.line_length - width * octpp;
241 splashsrc.ub += sd->pic->splash_pic_stride - width * octpp;
243 splash_sync_region(info, xpos, ypos, width, height);
246 void splashcopy(u8 *dst, u8 *src, int height, int width,
247 int dstbytes, int srcbytes, int octpp)
252 while (height-- > 0) {
256 for (i = 0; i < width / 4; i++)
257 fb_writel(*q.ul++, p.ul++);
259 fb_writew(*q.us++, p.us++);
261 fb_writeb(*q.ub, p.ub);
267 static void splashset(u8 *dst, int height, int width,
268 int dstbytes, u32 bgx, int octpp) {
274 while (height-- > 0) {
278 for (i = 0; i < width / 4; i++)
279 fb_writel(bgx, p.ul++);
281 fb_writew(bgx, p.us++);
283 fb_writeb(bgx, p.ub);
286 for (i = 0; i < width; i++)
287 fb_writeb((bgx >> ((i % 3) * 8)) & 0xff,
293 static void splashfill(struct fb_info *info, int sy, int sx,
294 int height, int width) {
295 int octpp = (info->var.bits_per_pixel + 1) >> 3;
296 struct splash_data *sd = info->splash_data;
298 splashcopy((u8 *)(info->screen_base
299 + sy * info->fix.line_length + sx * octpp),
300 (u8 *)(sd->pic->splash_pic
301 + sy * sd->pic->splash_pic_stride
303 height, width, info->fix.line_length,
304 sd->pic->splash_pic_stride,
306 splash_sync_region(info, sx, sy, width, height);
309 void splash_clear(struct vc_data *vc, struct fb_info *info, int sy,
310 int sx, int height, int width)
312 struct splash_data *sd;
313 int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
314 int bg_color = attr_bgcol_ec(bgshift, vc, info);
316 int octpp = (info->var.bits_per_pixel + 1) >> 3;
320 if (!oops_in_progress
321 && (console_blanked || info->splash_data->splash_dosilent))
324 sd = info->splash_data;
326 transparent = sd->imgd->splash_color == bg_color;
328 sy = sy * vc->vc_font.height + sd->imgd->splash_text_yo;
329 sx = sx * vc->vc_font.width + sd->imgd->splash_text_xo;
330 height *= vc->vc_font.height;
331 width *= vc->vc_font.width;
333 splashfill(info, sy, sx, height, width);
336 dst = (u8 *)(info->screen_base
337 + sy * info->fix.line_length
339 bgx = ((u32 *)info->pseudo_palette)[bg_color];
342 info->fix.line_length,
344 (info->var.bits_per_pixel + 1) >> 3);
345 splash_sync_region(info, sx, sy, width, height);
348 void splash_bmove(struct vc_data *vc, struct fb_info *info, int sy,
349 int sx, int dy, int dx, int height, int width)
351 struct splash_data *sd;
352 struct fb_copyarea area;
354 if (!oops_in_progress
355 && (console_blanked || info->splash_data->splash_dosilent))
358 sd = info->splash_data;
360 area.sx = sx * vc->vc_font.width;
361 area.sy = sy * vc->vc_font.height;
362 area.dx = dx * vc->vc_font.width;
363 area.dy = dy * vc->vc_font.height;
364 area.sx += sd->imgd->splash_text_xo;
365 area.sy += sd->imgd->splash_text_yo;
366 area.dx += sd->imgd->splash_text_xo;
367 area.dy += sd->imgd->splash_text_yo;
368 area.height = height * vc->vc_font.height;
369 area.width = width * vc->vc_font.width;
371 info->fbops->fb_copyarea(info, &area);
374 void splash_clear_margins(struct vc_data *vc, struct fb_info *info,
377 struct splash_data *sd;
378 unsigned int tw = vc->vc_cols*vc->vc_font.width;
379 unsigned int th = vc->vc_rows*vc->vc_font.height;
382 if (!oops_in_progress
383 && (console_blanked || info->splash_data->splash_dosilent))
386 sd = info->splash_data;
393 sd->imgd->splash_text_yo,
397 sd->imgd->splash_text_yo,
400 sd->imgd->splash_text_xo);
403 sd->imgd->splash_text_yo,
404 sd->imgd->splash_text_xo + tw,
406 info->var.xres - sd->imgd->splash_text_xo - tw);
409 sd->imgd->splash_text_yo + th,
411 info->var.yres - sd->imgd->splash_text_yo - th,
415 int splash_cursor(struct fb_info *info, struct fb_cursor *cursor)
417 struct splash_data *sd;
419 unsigned int dsize, s_pitch;
421 if (info->state != FBINFO_STATE_RUNNING)
424 sd = info->splash_data;
426 s_pitch = (cursor->image.width + 7) >> 3;
427 dsize = s_pitch * cursor->image.height;
428 if (cursor->enable) {
429 switch (cursor->rop) {
431 for (i = 0; i < dsize; i++)
432 info->fb_cursordata[i] = cursor->image.data[i]
437 for (i = 0; i < dsize; i++)
438 info->fb_cursordata[i] = cursor->image.data[i]
442 } else if (info->fb_cursordata != cursor->image.data)
443 memcpy(info->fb_cursordata, cursor->image.data, dsize);
444 cursor->image.data = info->fb_cursordata;
445 splash_renderc(info, cursor->image.fg_color, cursor->image.bg_color,
446 (u8 *)info->fb_cursordata,
447 cursor->image.dy + sd->imgd->splash_text_yo,
448 cursor->image.dx + sd->imgd->splash_text_xo,
449 cursor->image.height,
450 cursor->image.width);
454 void splash_bmove_redraw(struct vc_data *vc, struct fb_info *info,
455 int y, int sx, int dx, int width)
457 struct splash_data *sd;
458 unsigned short *d = (unsigned short *) (vc->vc_origin
459 + vc->vc_size_row * y
461 unsigned short *s = d + (dx - sx);
462 unsigned short *start = d;
463 unsigned short *ls = d;
464 unsigned short *le = d + width;
467 unsigned short attr = 1;
469 if (console_blanked || info->splash_data->splash_dosilent)
472 sd = info->splash_data;
476 if (attr != (c & 0xff00)) {
479 splash_putcs(vc, info, start, d - start, y, x);
484 if (s >= ls && s < le && c == scr_readw(s)) {
486 splash_putcs(vc, info, start, d - start, y, x);
498 splash_putcs(vc, info, start, d - start, y, x);
501 void splash_blank(struct vc_data *vc, struct fb_info *info, int blank)
506 splashset((u8 *)info->screen_base,
507 info->var.yres, info->var.xres,
508 info->fix.line_length,
510 (info->var.bits_per_pixel + 1) >> 3);
511 splash_sync_region(info, 0, 0, info->var.xres, info->var.yres);
513 /* splash_prepare(vc, info); *//* do we really need this? */
514 splash_clear_margins(vc, info, 0);
515 /* no longer needed, done in fbcon_blank */
516 /* update_screen(vc->vc_num); */