scrup/scrdown speedup patch (for 2.1.42)

Matija Nalis (mnalis@public.srce.hr)
Thu, 5 Jun 1997 02:17:16 +0200


but should work on other versions also...

problem is that scrolling up/down is very slow. When scrolling about 55
lines (slrn, newsreader using slang I'm using does that, with "^[[55L" and
"^[[55M" commands to console driver) it takes about 1.5 seconds to do the
scroll (that is intel pentium 133, completly unloaded). If I have something
playing in background, sound also dies for a second.

problem is strategy console drivers scrolls for 55 lines: it does a one line
scroll 55 times. Higly inefficient.

I'm not a kernel hacker, so I feared to touch anything below memcpyw (which
also looks highly inefficient), and changed only scrolling strategy. It now
does only one scrolling pass for whatever number of lines. Actully, for more
lines it needs to scroll, it will be faster (fewer lines to move in memory)

So, enough talk, here is the diff, works fine for me, hopefully someone else
would find it usuful, maybe even integrate it in The Kernel :-)

--- linux/drivers/char/console.c.org Mon Jun 2 00:50:18 1997
+++ linux/drivers/char/console.c Thu Jun 5 00:39:31 1997
@@ -497,14 +497,18 @@
__set_origin(__real_origin);
}

-static void scrup(int currcons, unsigned int t, unsigned int b)
+static void scrup(int currcons, unsigned int t, unsigned int b, unsigned int nr)
{
int hardscroll = hardscroll_enabled;

- if (b > video_num_lines || t >= b)
+ if (t+nr >= b)
+ nr = b - t - 1;
+ if (b > video_num_lines || t >= b || nr < 1)
return;
- if (t || b != video_num_lines)
+
+ if (t || b != video_num_lines || nr > 1)
hardscroll = 0;
+
if (hardscroll) {
origin += video_size_row;
pos += video_size_row;
@@ -544,31 +548,35 @@
set_origin(currcons);
} else {
unsigned short * d = (unsigned short *) (origin+video_size_row*t);
- unsigned short * s = (unsigned short *) (origin+video_size_row*(t+1));
+ unsigned short * s = (unsigned short *) (origin+video_size_row*(t+nr));

- memcpyw(d, s, (b-t-1) * video_size_row);
- memsetw(d + (b-t-1) * video_num_columns, video_erase_char, video_size_row);
+ memcpyw(d, s, (b-t-nr) * video_size_row);
+ memsetw(d + (b-t-nr) * video_num_columns, video_erase_char, video_size_row*nr);
}
}

static void
-scrdown(int currcons, unsigned int t, unsigned int b)
+scrdown(int currcons, unsigned int t, unsigned int b, unsigned int nr)
{
unsigned short *s;
unsigned int count;
+ unsigned int step;

- if (b > video_num_lines || t >= b)
+ if (t+nr >= b)
+ nr = b - t - 1;
+ if (b > video_num_lines || t >= b || nr < 1)
return;
- s = (unsigned short *) (origin+video_size_row*(b-2));
- if (b >= t + 1) {
- count = b - t - 1;
- while (count) {
- count--;
- memcpyw(s + video_num_columns, s, video_size_row);
- s -= video_num_columns;
- }
+ s = (unsigned short *) (origin+video_size_row*(b-nr-1));
+ step = video_num_columns * nr;
+ count = b - t - nr;
+ while (count--) {
+ memcpyw(s + step, s, video_size_row);
+ s -= video_num_columns;
+ }
+ while (nr--) {
+ s += video_num_columns;
+ memsetw(s, video_erase_char, video_size_row);
}
- memsetw(s + video_num_columns, video_erase_char, video_size_row);
has_scrolled = 1;
}

@@ -578,7 +586,7 @@
* if below scrolling region
*/
if (y+1 == bottom)
- scrup(currcons,top,bottom);
+ scrup(currcons,top,bottom,1);
else if (y < video_num_lines-1) {
y++;
pos += video_size_row;
@@ -592,7 +600,7 @@
* if above scrolling region
*/
if (y == top)
- scrdown(currcons,top,bottom);
+ scrdown(currcons,top,bottom,1);
else if (y > 0) {
y--;
pos -= video_size_row;
@@ -1117,9 +1125,9 @@
need_wrap = 0;
}

-static void insert_line(int currcons)
+static void insert_line(int currcons, unsigned int nr)
{
- scrdown(currcons,y,bottom);
+ scrdown(currcons,y,bottom,nr);
need_wrap = 0;
}

@@ -1136,9 +1144,9 @@
need_wrap = 0;
}

-static void delete_line(int currcons)
+static void delete_line(int currcons, unsigned int nr)
{
- scrup(currcons,y,bottom);
+ scrup(currcons,y,bottom,nr);
need_wrap = 0;
}

@@ -1158,8 +1166,7 @@
nr = video_num_lines;
else if (!nr)
nr = 1;
- while (nr--)
- insert_line(currcons);
+ insert_line(currcons, nr);
}

static void csi_P(int currcons, unsigned int nr)
@@ -1178,8 +1185,7 @@
nr = video_num_lines;
else if (!nr)
nr=1;
- while (nr--)
- delete_line(currcons);
+ delete_line(currcons, nr);
}

static void save_cur(int currcons)

-- 
Opinions above are GNU-copylefted.