diff options
author | Krzysztof Helt <krzysztof.h1@wp.pl> | 2007-07-17 07:05:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-07-17 13:23:11 -0400 |
commit | bad07ff74c32829defce8c83d7ff6ea69c329441 (patch) | |
tree | 95f9b2e86dc6dd53ec517389972057efa381e284 /drivers/video/console | |
parent | 5d2b56c69c400dfc1a878966efa2b4a4a797a855 (diff) |
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>
Diffstat (limited to 'drivers/video/console')
-rw-r--r-- | drivers/video/console/fbcon.c | 76 |
1 files changed, 68 insertions, 8 deletions
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 73813c60d03a..7888e319f9e1 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -1704,6 +1704,56 @@ static void fbcon_redraw_move(struct vc_data *vc, struct display *p, | |||
1704 | } | 1704 | } |
1705 | } | 1705 | } |
1706 | 1706 | ||
1707 | static void fbcon_redraw_blit(struct vc_data *vc, struct fb_info *info, | ||
1708 | struct display *p, int line, int count, int ycount) | ||
1709 | { | ||
1710 | int offset = ycount * vc->vc_cols; | ||
1711 | unsigned short *d = (unsigned short *) | ||
1712 | (vc->vc_origin + vc->vc_size_row * line); | ||
1713 | unsigned short *s = d + offset; | ||
1714 | struct fbcon_ops *ops = info->fbcon_par; | ||
1715 | |||
1716 | while (count--) { | ||
1717 | unsigned short *start = s; | ||
1718 | unsigned short *le = advance_row(s, 1); | ||
1719 | unsigned short c; | ||
1720 | int x = 0; | ||
1721 | |||
1722 | do { | ||
1723 | c = scr_readw(s); | ||
1724 | |||
1725 | if (c == scr_readw(d)) { | ||
1726 | if (s > start) { | ||
1727 | ops->bmove(vc, info, line + ycount, x, | ||
1728 | line, x, 1, s-start); | ||
1729 | x += s - start + 1; | ||
1730 | start = s + 1; | ||
1731 | } else { | ||
1732 | x++; | ||
1733 | start++; | ||
1734 | } | ||
1735 | } | ||
1736 | |||
1737 | scr_writew(c, d); | ||
1738 | console_conditional_schedule(); | ||
1739 | s++; | ||
1740 | d++; | ||
1741 | } while (s < le); | ||
1742 | if (s > start) | ||
1743 | ops->bmove(vc, info, line + ycount, x, line, x, 1, | ||
1744 | s-start); | ||
1745 | console_conditional_schedule(); | ||
1746 | if (ycount > 0) | ||
1747 | line++; | ||
1748 | else { | ||
1749 | line--; | ||
1750 | /* NOTE: We subtract two lines from these pointers */ | ||
1751 | s -= vc->vc_size_row; | ||
1752 | d -= vc->vc_size_row; | ||
1753 | } | ||
1754 | } | ||
1755 | } | ||
1756 | |||
1707 | static void fbcon_redraw(struct vc_data *vc, struct display *p, | 1757 | static void fbcon_redraw(struct vc_data *vc, struct display *p, |
1708 | int line, int count, int offset) | 1758 | int line, int count, int offset) |
1709 | { | 1759 | { |
@@ -1789,7 +1839,6 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, | |||
1789 | { | 1839 | { |
1790 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; | 1840 | struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; |
1791 | struct display *p = &fb_display[vc->vc_num]; | 1841 | struct display *p = &fb_display[vc->vc_num]; |
1792 | struct fbcon_ops *ops = info->fbcon_par; | ||
1793 | int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK; | 1842 | int scroll_partial = info->flags & FBINFO_PARTIAL_PAN_OK; |
1794 | 1843 | ||
1795 | if (fbcon_is_inactive(vc, info)) | 1844 | if (fbcon_is_inactive(vc, info)) |
@@ -1813,10 +1862,15 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, | |||
1813 | goto redraw_up; | 1862 | goto redraw_up; |
1814 | switch (p->scrollmode) { | 1863 | switch (p->scrollmode) { |
1815 | case SCROLL_MOVE: | 1864 | case SCROLL_MOVE: |
1816 | ops->bmove(vc, info, t + count, 0, t, 0, | 1865 | fbcon_redraw_blit(vc, info, p, t, b - t - count, |
1817 | b - t - count, vc->vc_cols); | 1866 | count); |
1818 | ops->clear(vc, info, b - count, 0, count, | 1867 | fbcon_clear(vc, b - count, 0, count, vc->vc_cols); |
1819 | vc->vc_cols); | 1868 | scr_memsetw((unsigned short *) (vc->vc_origin + |
1869 | vc->vc_size_row * | ||
1870 | (b - count)), | ||
1871 | vc->vc_video_erase_char, | ||
1872 | vc->vc_size_row * count); | ||
1873 | return 1; | ||
1820 | break; | 1874 | break; |
1821 | 1875 | ||
1822 | case SCROLL_WRAP_MOVE: | 1876 | case SCROLL_WRAP_MOVE: |
@@ -1899,9 +1953,15 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir, | |||
1899 | goto redraw_down; | 1953 | goto redraw_down; |
1900 | switch (p->scrollmode) { | 1954 | switch (p->scrollmode) { |
1901 | case SCROLL_MOVE: | 1955 | case SCROLL_MOVE: |
1902 | ops->bmove(vc, info, t, 0, t + count, 0, | 1956 | fbcon_redraw_blit(vc, info, p, b - 1, b - t - count, |
1903 | b - t - count, vc->vc_cols); | 1957 | -count); |
1904 | ops->clear(vc, info, t, 0, count, vc->vc_cols); | 1958 | fbcon_clear(vc, t, 0, count, vc->vc_cols); |
1959 | scr_memsetw((unsigned short *) (vc->vc_origin + | ||
1960 | vc->vc_size_row * | ||
1961 | t), | ||
1962 | vc->vc_video_erase_char, | ||
1963 | vc->vc_size_row * count); | ||
1964 | return 1; | ||
1905 | break; | 1965 | break; |
1906 | 1966 | ||
1907 | case SCROLL_WRAP_MOVE: | 1967 | case SCROLL_WRAP_MOVE: |