30天自制操作系统:第十天 叠加处理

1 内存管理(续)(harib07a)

memman_allocmemman_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_backsht_mouse,还准备了两个缓冲区buf_backbuf_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当然没那么快乐,希望能熬过去,加油

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

nepu_bin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值