3 提高窗口移动速度(3)(harib23c)
我们发现一次性写入4个字节这个办法可以有效地提高速度,既然如此,这个办法是不是也能用在sheet_refreshmap以外的函数中呢?于是我们首先想到了sheet_refreshsub,窗口移动的时候也调用了这个函数,因此通过修改它可以提高窗口移动的速度,此外其他一些地方也会调用这个函数,如果顺利的话,系统整体的绘图速度都会有所提升,真是令人兴奋呀。
本次的sheet.c节选
void sheet_refreshsub(struct SHTCTL *ctl, int vx0, int vy0, int vx1, int vy1, int h0, int h1)
{
int h, bx, by, vx, vy, bx0, by0, bx1, by1, bx2, sid4, i, i1, *p, *q, *r; /*这里!*/
(中略)
for (h = h0; h <= h1; h++) {
(中略)
if ((sht->vx0 & 3) == 0) { /*从此开始*/
/* 4字节型*/
i = (bx0 + 3) / 4; /* bx0除以4(小数进位)*/
i1 = bx1 / 4; /* bx1除以4(小数舍去)*/
i1 = i1 - i;
sid4 = sid | sid << 8 | sid << 16 | sid << 24;
for (by = by0; by < by1; by++) {
vy = sht->vy0 + by;
for (bx = bx0; bx < bx1 && (bx & 3) != 0; bx++) { /*前面被4除多余的部分逐个字节写入*/
vx = sht->vx0 + bx;
if (map[vy * ctl->xsize + vx] == sid) {
vram[vy * ctl->xsize + vx] = buf[by * sht->bxsize + bx];
}
}
vx = sht->vx0 + bx;
p = (int *) &map[vy * ctl->xsize + vx];
q = (int *) &vram[vy * ctl->xsize + vx];
r = (int *) &buf[by * sht->bxsize + bx];
for (i = 0; i < i1; i++) { /* 4的倍数部分*/
if (p[i] == sid4) {
q[i] = r[i]; /*估计大多数会是这种情况,因此速度会变快*/
} else {
bx2 = bx + i * 4;
vx = sht->vx0 + bx2;
if (map[vy * ctl->xsize + vx + 0] == sid) {
vram[vy * ctl->xsize + vx + 0] = buf[by * sht->bxsize + bx2 + 0];
}
if (map[vy * ctl->xsize + vx + 1] == sid) {
vram[vy * ctl->xsize + vx + 1] = buf[by * sht->bxsize + bx2 + 1];
}
if (map[vy * ctl->xsize + vx + 2] == sid) {
vram[vy * ctl->xsize + vx + 2] = buf[by * sht->bxsize + bx2 + 2];
}
if (map[vy * ctl->xsize + vx + 3] == sid) {
vram[vy * ctl->xsize + vx + 3] = buf[by * sht->bxsize + bx2 + 3];
}
}
}
for (bx += i1 * 4; bx < bx1; bx++) { /*后面被4除多余的部分逐个字节写入*/
vx = sht->vx0 + bx;
if (map[vy * ctl->xsize + vx] == sid) {
vram[vy * ctl->xsize + vx] = buf[by * sht->bxsize + bx];
}
}
}
} else {
/* 1字节型*/
for (by = by0; by < by1; by++) {
vy = sht->vy0 + by;
for (bx = bx0; bx < bx1; bx++) {
vx = sht->vx0 + bx;
if (map[vy * ctl->xsize + vx] == sid) {
vram[vy * ctl->xsize + vx] = buf[by * sht->bxsize + bx];
}
}
}
} /*到此结束*/
}
return;
}
这样一来,当窗口显示位置为4的倍数时速度就会变快。重绘画面时,重绘范围不一定为4的倍数,因此我们也考虑了这种情况的处理方法:当前面有余数时将余数部分逐个字节处理,后面有余数时也一样。不过,即便窗口本身没有透明色,当它和别的窗口或者鼠标重叠时我们也不能直接往相邻的内存地址中写入数据,因此for循环中用来判断map的值是否等于sid的if语句还是不能去掉的。
■■■■■
我们来“make run”吧。哦哦,好快!移动起来嗖嗖的,昨天我们还在忍受着龟速呢,现在想想就跟做梦似的,耶!
截图上看不出来,不过速度快了很多