forked from Minki/linux
fbcon: smart blitter usage for scrolling
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. [adaplas] - remove unnecessary char attribute checking - whitespace cleanups and 80-column line fixes Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Antonino Daplas <adaplas@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
5d2b56c69c
commit
bad07ff74c
@ -1704,6 +1704,56 @@ static void fbcon_redraw_move(struct vc_data *vc, struct display *p,
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
do {
|
||||
c = scr_readw(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 +1839,6 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
|
||||
{
|
||||
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 +1862,15 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
|
||||
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 +1953,15 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
|
||||
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:
|
||||
|
Loading…
Reference in New Issue
Block a user