1 内存管理(续)(harib07a)
memman_alloc 和 memman_free 函数能够以1字节为单位进行内存管理,这种方式虽然不错,但是有一点不足:在反复进行内存分配和内存释放之后,内存中就会出现很多不连续的小段未使用空间,这样就会把man->frees(该属性指示了空闲空间块的总个数)消耗殆尽。
因此,作者编写了一些总是以0x1000字节为单位进行内存分配和释放的函数,它们会把指定的内存大小按0x1000字节(4KB)为单位向上舍入,选择0x1000这个数值非常精妙,我们慢慢来理解这个“精妙之处”。
刚看程序,有点懵,但是后面作者给出了对向上向下取整详细的解释:
这里都是作者解释如何完成向上向下取整的操作,非常通俗易懂。
拓展阅读
作者深度解释了使用0x1000字节作为单位的高明之处。
2 叠加处理(harib07b)
之后的这几个小节中包含了非常多的程序代码,笔者就给出一些理解吧,刚学确实有点懵懂。
结构体中的内容比较多,首先 SHEET 表示“透明图层”的意思。
- buf用来记录图层上所描画内容的地址(buffer)
- bxsize * bysize可以表示图层的整体大小
- vx0、vy0是表示图层在画面上的位置坐标(v是VRAM的略语)
- col_inv表示透明色色号,它是 color(颜色) 和 invisible(透明)的组合略语
- height 表示图层高度
- flags用于存放有关图层的各种设定信息
只有一个图层是不能实现叠加处理的,所以必须创建一个管理多重图层信息的结构。
结构体SHTCTL(sheet control,图层管理):
- MAX_SHEETS是能够管理的最大图层数,这里设置为256
- vram、xsize、ysize代表VRAM的地址和画面的大小,每次从BOOTINFO查询太麻烦了,在这里预先对它们进行赋值操作。
- top表示最上面图层的高度
- sheet0这个结构体数组用于存放我们准备的256个图层的信息
- sheets是用于记录地址变量的一个指针数组(类型为struct SHEET,可以写成 (struct SHEET*) sheets[ MAX_SHEETS ]; ),作用:由于sheets0中的图层顺序混乱,所以将它们按照高度进行升序排序,然后将地址写入到sheets中,这样就方便多了。
理解SHTCTL结构体中的内容:
接下来就是程序部分了。
程序做了些什么?
首先使用 memman_alloc_4k来分配用于记忆图层控制变量的内存空间,这时必须指定该变量所占空间的大小,不过可以使用 sizeof运算符,让编译器自动计算。接着,给控制变量赋值,给其下的所有图层变量都加上“未使用”标签。
sheet_alloc函数
函数对所有图层进行遍历,找出第一个 flags 等于 0(未使用) 的图层,将其标记更改为 “正在使用”,设置 height 属性为 - 1, 表示隐藏,最后再返回这个图层的地址即可;如果没有找到符合条件(未使用)的图层,那么返回0表示所有的SHEET都处于正在使用的状态。
设定图层内容的sheet_setbuf函数
用于设定图层的缓冲区大小和透明色的函数,函数中只完成了一些简单的赋值。
设定底板高度的 sheet_updown函数
程序中包含了比较多的注释,只能慢慢看程序一次又一次去理解了。
从下往上描述图层的sheet_refresh函数
对于已经设定了高度的所有图层而言,要从下往上,将透明以外的所有像素都恢复到VRAM中。由于是从下开始复制,所以最后最上面的内容就留在了画面上。
sheet_slide函数
不改变图层高度而只上下左右移动图层的函数。
释放已使用图层内存的sheet_free函数
HariMain函数
主函数负责调用这些函数完成实际功能,这部分需要仔细琢磨。
这里有两个图层,分别是sht_back和sht_mouse,还准备了两个缓冲区buf_back和buf_mouse,用于在其中描绘图形,以前我们指定为 binfo->vram的部分,现在有很多都改成了 buf_back。而且每次修改缓冲区之后都要刷新。
3 提高叠加处理速度(1)(harib07c)
鼠标指针虽然最多只有16 x 16 = 256个像素,但是上一章节里卖的程序,只要它稍一移动,程序就会对整个画面进行刷新,也就是重新绘制320 x 200 = 64000个像素。而实际上,只重新描绘移动相关的部分,也就是移动前后的部分就可以了,即 256 x 2 = 512个像素,这只是原来64000像素的0.8%而已,根据这个思路改写一下程序。
sheet.c节选
函数几乎和sheet_refresh一样,唯一的不同点在于它能使用vx0 ~ vy1指定刷新的范围,而我们之追加了一个if语句就实现了这个新功能。
现在用这个 refreshsub函数来提高sheet_slide的运行速度。
这段程序所做的是:首先记住移动前的显示位置,再设定新的显示位置,最后只需要重新描绘移动前和移动后的地方就可以了。
移动鼠标的时候,由于要在画面上显示坐标等信息,结果又执行了sheet_refresh程序,所以还是很慢, 必须解决一下图层内文字显示的问题。
这里所说的在图层上显示文字,实际上不是改写图层的全部内容,假设我们写了20个字,那么8 x 16 x 20 = 2560,也就仅仅重写2560个像素的内容就足够了,但现在每次都要重写64000个像素的内容,所以速度才会那么慢。
所谓指定范围,并不是直接指定画面内的坐标,而是以缓冲区的坐标来表示。这样一来,HariMain就可以 不考虑图层在画面中的位置了。
4 提高叠加处理速度(2)(harib07d)
感受
中秋节快乐呀,今天的内容看的还是有点懵懂,大体上好似明白,但是一旦细节一点的内容有点绕不过去,现在的窘境就是函数太多了,有些地方没有完全吃透,有一些小疑问还需要解决(这些必须慢慢理解慢慢消化)。已经第十天了,每天一篇博客确实挺耗费时间的,相比做其他实验做OS当然没那么快乐,希望能熬过去,加油