From: Krzysztof Helt This patch replaces the current SCROLL_MOVE method with smarter method using the same logic as the SCROLL_REDRAW method. This brings these two methods much closer in performance and benefits all framebuffers which uses the SCROLL_MOVE method. Signed-off-by: Krzysztof Helt --- This version does not merge blits and does not uses ifdefs. The patch was diffed against linux-2.6.21-git11 Regards, Krzysztof diff -urp linux-2.6.21.orig/drivers/video/console/fbcon.c linux-2.6.21/drivers/video/console/fbcon.c --- linux-2.6.21.orig/drivers/video/console/fbcon.c 2007-05-09 16:56:07.936744076 +0200 +++ linux-2.6.21/drivers/video/console/fbcon.c 2007-05-10 21:00:22.685633709 +0200 @@ -1704,6 +1704,61 @@ static void fbcon_redraw_move(struct vc_ } } +static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info, + struct display *p, int line, int count, int ycount) +{ + int offset = ycount * vc->vc_cols; + unsigned short *d = (unsigned short *) + (vc->vc_origin + vc->vc_size_row * line); + unsigned short *s = d + offset; + struct fbcon_ops *ops = info->fbcon_par; + + while (count--) { + unsigned short *start = s; + unsigned short *le = advance_row(s, 1); + unsigned short c; + int x = 0; + unsigned short attr = 1; + + do { + c = scr_readw(s); + if (attr != (c & 0xff00)) { + attr = c & 0xff00; + if (s > start) { + ops->bmove(vc, info, line + ycount, x, line, x, 1, s-start); + x += s - start; + start = s; + } + } + if (c == scr_readw(d)) + if (s > start) { + ops->bmove(vc, info, line + ycount, x, line, x, 1, s-start); + x += s - start + 1; + start = s + 1; + } else { + x++; + start++; + } + + scr_writew(c, d); + console_conditional_schedule(); + s++; + d++; + } while (s < le); + if (s > start) + ops->bmove(vc, info, line + ycount, x, line, x, 1, s-start); + console_conditional_schedule(); + if (ycount > 0) + line++; + else { + line--; + /* NOTE: We subtract two lines from these pointers */ + s -= vc->vc_size_row; + d -= vc->vc_size_row; + } + } +} + static void fbcon_redraw(struct vc_data *vc, struct display *p, int line, int count, int offset) { @@ -1789,7 +1844,6 @@ static int fbcon_scroll(struct vc_data * { struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; struct display *p = &fb_display[vc->vc_num]; - struct fbcon_ops *ops = info->fbcon_par; int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK; if (fbcon_is_inactive(vc, info)) @@ -1813,10 +1867,15 @@ static int fbcon_scroll(struct vc_data * goto redraw_up; switch (p->scrollmode) { case SCROLL_MOVE: - ops->bmove(vc, info, t + count, 0, t, 0, - b - t - count, vc->vc_cols); - ops->clear(vc, info, b - count, 0, count, - vc->vc_cols); + fbcon_redraw_blit(vc, info, p, t, b - t - count, + count); + fbcon_clear(vc, b - count, 0, count, vc->vc_cols); + scr_memsetw((unsigned short *) (vc->vc_origin + + vc->vc_size_row * + (b - count)), + vc->vc_video_erase_char, + vc->vc_size_row * count); + return 1; break; case SCROLL_WRAP_MOVE: @@ -1899,9 +1958,15 @@ static int fbcon_scroll(struct vc_data * goto redraw_down; switch (p->scrollmode) { case SCROLL_MOVE: - ops->bmove(vc, info, t, 0, t + count, 0, - b - t - count, vc->vc_cols); - ops->clear(vc, info, t, 0, count, vc->vc_cols); + fbcon_redraw_blit(vc, info, p, b - 1, b - t - count, + -count); + fbcon_clear(vc, t, 0, count, vc->vc_cols); + scr_memsetw((unsigned short *) (vc->vc_origin + + vc->vc_size_row * + t), + vc->vc_video_erase_char, + vc->vc_size_row * count); + return 1; break; case SCROLL_WRAP_MOVE: ---------------------------------------------------- Morderstwa i krew ofiar na ścianach. Mroczne miasto pogrążone w chaosie. Sprawdź kto jest Przybywającym! Przybywający - thriller metafizyczny już w księgarniach. http://klik.wp.pl/?adr=http%3A%2F%2Fksiazki.wp.pl%2Fkatalog%2Fksiazki%2Fksiazka.html%3Fkw%3D10414&sid=1128