1、双缓冲基础概念:什么是屏幕撕裂、单缓冲的痛点、双缓冲核心思想

屏幕撕裂——你肯定见过,只是不知道它叫啥

先问个问题:你玩手机或看视频时,有没有遇到过屏幕中间出现一条“错位线”?上半张画面还在滚动,下半张已经切到下一帧了。像一张纸被撕开再拼回去,对不上。

这就是屏幕撕裂(Tearing)。我最早在嵌入式项目里遇到它,还以为是屏坏了。后来才发现,是显存和屏幕刷新不同步搞的鬼。

屏幕撕裂怎么发生的?说白了:

  • 屏幕每秒刷新 60 次(60Hz),每次刷新从显存读一帧数据。
  • CPU/GPU 也在往显存写新帧。
  • 如果屏幕读到一半,显存里的数据被新帧覆盖了——好了,上半截是旧帧,下半截是新帧。

你想想看,这就像你在黑板上写字,有人一边擦一边写,你抄到一半,内容变了。抄下来的东西能不乱吗?

核心结论:屏幕撕裂的根本原因是——一个显存区域同时被写入和读取,没有隔离。

单缓冲——最直接的方案,也是最痛的方案

早期嵌入式系统怎么做显示?就一块显存(Frame Buffer),CPU 直接往上画,LCD 控制器直接从里面读。这叫单缓冲。

单缓冲的流程很简单:

  1. CPU 清空显存。
  2. CPU 绘制新画面。
  3. LCD 控制器读取显存并显示。
  4. 回到第 1 步。

听起来没毛病?我在项目里踩过这个坑。单缓冲有三个硬伤:

痛点 表现 后果
屏幕撕裂 CPU 绘制中,LCD 开始读 画面错位、闪烁
绘制延迟 CPU 画完前,屏幕只能显示旧帧或残影 操作卡顿、跟手性差
帧率受限 绘制和刷新串行执行 帧率上不去,动画不流畅

我曾经在一个 240×320 的小屏上做菜单动画,单缓冲下帧率只有 15fps。翻页时画面撕裂得像碎纸机吐出来的。用户反馈说“这设备反应好慢”。嗯,其实不是慢,是显存打架。

避坑指南:单缓冲在低分辨率、静态界面下还能凑合。一旦涉及动画、滑动、视频播放,必出问题。我建议你从一开始就别在交互类产品上用单缓冲。

双缓冲核心思想——给显存加个“后台”

双缓冲的思路其实很朴素:准备两块显存区域。

  • 前台缓冲(Front Buffer):LCD 控制器正在读的那块,负责显示。
  • 后台缓冲(Back Buffer):CPU/GPU 正在画的那块,负责绘制。

绘制和显示不再抢同一块内存。CPU 在后台画完了,通过一个叫“交换(Swap)”的动作,把前后台角色互换。LCD 读新的前台,CPU 画新的后台。

你想想看,这就像厨房里两个厨师:一个在备菜(后台),一个在出菜(前台)。备好了喊一声“换”,前台把菜端出去,后台继续备下一道。互不干扰。

个人经验:我习惯把双缓冲比作“乒乓缓冲”。两块 buffer 像乒乓球一样来回切换。你打过去,我打回来,永远有一块是稳定的显示画面。

双缓冲解决了什么?

双缓冲直接干掉了两个核心痛点:

  • 消除屏幕撕裂:LCD 始终读完整的前台缓冲,不会被后台绘制打断。
  • 提升绘制效率:CPU 不用等屏幕刷新,画完就切,切完继续画下一帧。

但双缓冲不是免费的。代价是:

  • 内存翻倍:需要两倍的显存空间。
  • 交换时机敏感:如果交换发生在屏幕刷新中间,还是会出现撕裂——所以需要配合“垂直同步(VSync)”。

我记得第一次在 STM32 上实现双缓冲时,显存从 64KB 涨到 128KB,MCU 内部 RAM 直接爆了。后来换成外部 SRAM 才搞定。嗯,这里要注意:选型时就要算好显存预算。

一张图看懂单缓冲 vs 双缓冲

下面这张 SVG 图展示了两种方案的流程对比。我建议你仔细看箭头走向,能直观理解“为什么双缓冲不撕裂”。

单缓冲 vs 双缓冲流程对比 单缓冲 vs 双缓冲流程对比 单缓冲(有撕裂) CPU 开始绘制新帧 LCD 同时读取显存 显存数据被覆盖 屏幕显示撕裂画面 ⚠ 绘制和读取共用同一块显存 必然产生竞争,导致撕裂 双缓冲(无撕裂) 前台缓冲(显示中) LCD 读取前台缓冲 后台缓冲(绘制中) CPU 绘制到后台缓冲 ↔ 绘制完成后交换前后台角色 ✅ 绘制和显示互不干扰 LCD 始终读取完整的帧

双缓冲的两种交换策略

双缓冲不是“有两块 buffer 就完事了”。交换时机很关键。我归纳了两种主流策略:

策略 做法 优点 缺点
立即交换 后台画完立刻切换前台 响应快,延迟低 可能撕裂(需 VSync 配合)
垂直同步交换 等屏幕消隐期(VBlank)再交换 彻底消除撕裂 增加 1 帧延迟

我个人习惯在触摸交互场景用“立即交换 + VSync”。为什么?因为触摸要求低延迟,VSync 保证不撕裂,两者结合最稳。纯显示场景(比如播放视频)用垂直同步交换就够了。

一句话总结:双缓冲的核心就是“读写分离,整帧交换”。两块 buffer 各司其职,通过交换动作完成角色切换。这是所有现代图形系统的基础。

本章小结

  • 屏幕撕裂:显存同时被读写导致的画面错位。
  • 单缓冲痛点:撕裂、延迟、帧率低,不适合交互场景。
  • 双缓冲核心:前台显示 + 后台绘制,交换角色实现无撕裂渲染。
  • 交换策略:立即交换 vs 垂直同步交换,按场景选型。