单Buffer的缺点与改进方法
文章目录
- 单Buffer的缺点与改进方法
- 一、 单Buffer的缺点
- 二、 使用多Buffer来改进
- 三、 内核驱动程序、APP互相配合使用多buffer
- 致谢
参考资料
-
内核自带的LCD驱动程序
- IMX6ULL驱动源码:
Linux-4.9.88\drivers\video\fbdev\mxsfb.c
- IMX6ULL驱动源码:
一、 单Buffer的缺点
-
如果APP速度很慢,可以看到它在LCD上缓慢绘制图案
-
即使APP速度很高,LCD控制器不断从Framebuffer中读取数据来显示,而APP不断把数据写入Framebuffer
-
假设APP想把LCD显示为整屏幕的蓝色、红色
-
很大几率出现这种情况:
- LCD控制器读取Framebuffer数据,读到一半时,在LCD上显示了半屏幕的蓝色
- 这是APP非常高效地把整个Framebuffer的数据都改为了红色
- LCD控制器继续读取数据,于是LCD上就会显示半屏幕蓝色、半屏幕红色
- 人眼就会感觉到屏幕闪烁、撕裂
-
二、 使用多Buffer来改进
上述两个缺点的根源是一致的:Framebuffer中的数据还没准备好整帧数据,就被LCD控制器使用了。
使用双buffer甚至多buffer可以解决这个问题:
- 假设有2个Framebuffer:FB0、FB1
- LCD控制器正在读取FB0
- APP写FB1
- 写好FB1后,让LCD控制器切换到FB1
- APP写FB0
- 写好FB0后,让LCD控制器切换到FB0
三、 内核驱动程序、APP互相配合使用多buffer
流程如下:
-
驱动:分配多个buffer
fb_info->fix.smem_len = SZ_32M; fbi->screen_base = dma_alloc_writecombine(fbi->device,fbi->fix.smem_len,(dma_addr_t *)&fbi->fix.smem_start,GFP_DMA | GFP_KERNEL);
-
驱动:保存buffer信息
fb_info->fix.smem_len // 含有总buffer大小 fb_info->var // 含有单个buffer信息
-
APP:读取buffer信息
ioctl(fd_fb, FBIOGET_FSCREENINFO, &fix); ioctl(fd_fb, FBIOGET_VSCREENINFO, &var);// 计算是否支持多buffer,有多少个buffer screen_size = var.xres * var.yres * var.bits_per_pixel / 8; nBuffers = fix.smem_len / screen_size;
-
APP:使能多buffer
var.yres_virtual = nBuffers * var.yres; ioctl(fd_fb, FBIOPUT_VSCREENINFO, &var);
-
APP:写buffer
fb_base = (unsigned char *)mmap(NULL , fix.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);/* get buffer */ pNextBuffer = fb_base + nNextBuffer * screen_size;/* set buffer */ lcd_draw_screen(pNextBuffer, colors[i]);
-
APP:开始切换buffer
/* switch buffer */ var.yoffset = nNextBuffer * var.yres; ioctl(fd_fb, FBIOPAN_DISPLAY, &var);
-
驱动:切换buffer
// fbmem.c fb_ioctldo_fb_ioctlfb_pan_display(info, &var);err = info->fbops->fb_pan_display(var, info) // 调用硬件相关的函数
-
APP:等待切换完成(在驱动程序中已经等待切换完成了,所以这个调用并无必要)
ret = 0; ioctl(fd_fb, FBIO_WAITFORVSYNC, &ret);
76953605941)]
-
APP:等待切换完成(在驱动程序中已经等待切换完成了,所以这个调用并无必要)
ret = 0; ioctl(fd_fb, FBIO_WAITFORVSYNC, &ret);
致谢
以上笔记源自
韦东山
老师的视频课程,感谢韦老师,韦老师是嵌入式培训界一股清流,为嵌入式linux开发点起的星星之火,也愿韦老师桃李满园。聚是一团火,散是满天星!
在这样一个速食的时代,坚持做自己,慢下来,潜心琢磨,心怀敬畏,领悟知识,才能向下扎到根,向上捅破天,背着世界往前行!
仅此向嵌入行业里的每一个认真做技术的从业者致敬!