垂直同步,VBlank,双缓存笔记

文章讲述了显示器的工作原理,包括逐行扫描、帧率和刷新率的概念,以及帧缓存如何影响画面显示。当帧率与刷新率不匹配时,可能导致画面撕裂问题。垂直同步是一种解决撕裂的方法,确保BufferSwap在显示器扫描点重置时进行,以保持画面流畅。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

现代显示器一般用逐行扫描,扫描点从右下角挪回到左上角的过程称为VBlank,帧数指的是显卡一秒钟渲染好了多少张画面发给显示器,刷新率指的是显示器逐行扫描画面的速度(60hz指的是显示器一秒钟逐行扫描了多少张画面),为了使一个波动的输出帧数匹配固定的屏幕刷新率,我们就需要使用帧缓存。
默认情况有两个帧缓存,FrontBuffer和BackBuffer,显卡先把后缓存填满,然后后缓存与前缓存交换(Buffer Swap),显示器显示前缓存内容。显示器正在显示过往画面A,并且正在逐行扫描前缓存中的画面B,显卡正在渲染画面C,假设显卡在显示器扫描完B之前渲染完了C,此时前后缓存交换,显示器扫描完B的一部分就开始扫描C画面,这就是画面撕裂(帧率高于刷新率)。
若刷新率高于帧率,则上述情况就变成了显示器早早扫描完了B画面,显卡还没渲染好,前缓存还是B,那显示器只能继续扫描B,还没扫完第二次B的时候显卡渲染好了,发生Buffer Swap,然后前缓存变成C,显示器开始接着画C,所以看到的就是第一帧是完好的B,第二帧一部分B一部分C,还是撕裂。

所以帧率与刷新率不匹配就会发生撕裂现象。

垂直同步:是解决撕裂的一种方法。它强制Buffer Swap发生在显示器的VBlank(扫描点重置阶段)。相当于变成了显卡要等显示器准备好了(扫描点在左上角)才做Buffer Swap。当显卡渲染帧率低于显示器刷新率的时候,就会发生显示器重复扫描前缓存画面的情况,画面就不流畅。
### 双缓冲模式下的 LCD 同步方法 双缓冲是一种常见的技术,用于减少屏幕刷新过程中的视觉伪影(如撕裂效应)。为了在双缓冲模式下实现 LCD 的同步,通常需要结合硬件特性和软件控制来完成。 #### 原理概述 双缓冲的核心思想是在内存中维护两个独立的缓冲区:前台缓冲区和后台缓冲区。前台缓冲区的内容被显示到屏幕上,而所有的绘图操作都在后台缓冲区内完成[^1]。当后台缓冲区绘制完成后,通过交换这两个缓冲区的角色或将后台缓冲区的数据复制到前台缓冲区的方式更新屏幕内容。 #### 实现步骤说明 以下是基于双缓冲机制实现 LCD 同步的关键点: 1. **初始化缓冲区** 需要分配两块大小相等的内存区域作为前后台缓冲区,并设置初始状态以便于后续切换。如果支持硬件级别的双缓冲,则可以直接利用显卡驱动程序提供的接口配置这两块缓冲区。 2. **数据写入后台缓冲区** 所有的图形渲染工作都应在后台缓冲区执行,这样可以避免直接修改正在显示的画面造成闪烁现象。此阶段可能涉及复杂的图像处理算法或者简单的像素填充操作。 3. **垂直同步信号检测(VSync)** 在大多数情况下,为了避免画面撕裂效果,在实际进行缓冲区交换之前应该等待显示器发出下一个垂直回扫周期开始的通知——这被称为“垂直同步”。许多现代 GPU API 提供了内置功能允许开发者启用 V-Sync 支持[^2]。 4. **缓冲区交换/复制** 当所有必要的绘制动作都已经完成并且接收到合适的时机(比如VBlank期间),就可以安全地将当前使用的前缓存指针指向原来的后缓存地址上;如果是软体实作的话则需调用 `memcpy` 函数把整个新画好的场景拷贝过去。 5. **调整帧缓冲偏移量**(可选) 如果希望进一步优化用户体验,例如实现平滑滚动等功能,还可以借助特定命令如 Linux 中 Framebuffer 接口所提供的 `FBIOPAN_DISPLAY` 来动态改变可见窗口的位置而不必每次都重新上传全部数据。 ```c // 示例代码展示如何使用 FBIOPAN_DISPLAY 进行动态位移 #include <fcntl.h> #include <linux/fb.h> int fbfd; struct fb_var_screeninfo vinfo; fbfd = open("/dev/fb0", O_RDWR); ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo); // 设置新的 X 和 Y 方向上的偏移值 vinfo.xoffset = newXOffset; vinfo.yoffset = newYOffset; ioctl(fbfd, FBIOPAN_DISPLAY, &vinfo); // 应用更改 close(fbfd); ``` 以上就是关于怎样在一个典型的双缓冲架构里达成与液晶显示屏之间的良好配合的一些基本指导原则和技术细节介绍。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值