OS开发:如何高效向上偏移32位线性帧缓冲区内容?
解决32位线性帧缓冲区向上滚动的效率问题
原代码的核心问题
你的实现效率极低的原因有两个关键问题:
- 冗余至极的循环嵌套:中间的
j循环完全多余——每次k循环已经把整个帧缓冲区向上移动了1个像素,而j循环执行fb_width次,等于每滚动1行像素就重复做了fb_width次全缓冲区移动,直接导致时间复杂度爆炸。 - 逐像素复制的低效:用单个
uint32_t赋值逐像素移动,远不如libc提供的memmove/memcpy这类经过底层优化的内存操作函数,后者会以更大的内存块为单位复制,效率提升几个数量级。
高效实现方案
利用memmove(处理重叠内存区域安全)和memset,只需要两次内存操作就能完成滚动,完全不需要多层循环:
步骤说明
- 计算一行像素的字节数:因为是32位像素(每个像素4字节),所以一行字节数为
bootboot.fb_width * 4 - 计算需要滚动的像素行数:
scroll_pixel_lines = atoi(numLines) - 计算待复制内容的起始地址:从第
scroll_pixel_lines行开始的内容,地址为(uint8_t*)fb + scroll_pixel_lines * bootboot.fb_width * 4 - 计算需要复制的总字节数:剩余有效内容的行数(总高度 - 滚动行数)乘以一行字节数,即
(bootboot.fb_height - scroll_pixel_lines) * bootboot.fb_width * 4 - 用
memmove把待复制内容移动到帧缓冲区起始位置(源和目标地址重叠,memmove是安全的) - 用
memset清空最后scroll_pixel_lines行的内容(填充背景色,通常为0)
代码实现
uint32_t scroll_pixel_lines = atoi(numLines); // 一行像素的字节数(32位像素=4字节/像素) size_t line_bytes = bootboot.fb_width * sizeof(uint32_t); // 待复制内容的起始地址 uint8_t* src = (uint8_t*)fb + scroll_pixel_lines * line_bytes; // 需要复制的总字节数 size_t copy_size = (bootboot.fb_height - scroll_pixel_lines) * line_bytes; // 滚动:把下方内容移到上方 memmove(fb, src, copy_size); // 清空最后scroll_pixel_lines行 uint8_t* clear_start = (uint8_t*)fb + copy_size; memset(clear_start, 0, scroll_pixel_lines * line_bytes);
后续扩展(文本行数滚动)
如果后续要改为按文本行数滚动,只需要把scroll_pixel_lines替换为 text_lines * font_line_height(font_line_height是你使用的字体每行的像素高度),其余逻辑完全一致。
内容的提问来源于stack exchange,提问作者Techflash
相关产品推荐
相关产品推荐

