4、刷新模式选择:对比 LV_COLOR_DEPTH 与 LV_COLOR_16_SWAP 对刷新速度的影响
颜色深度这个配置,很多人一开始就随便选一个。我见过不少项目,明明硬件支持 16 位色,却因为默认配置走了弯路。说白了,LV_COLOR_DEPTH 和 LV_COLOR_16_SWAP 这两个宏,直接决定了每一帧数据量的大小,也决定了你的动画能不能跑满 60fps。
4.1 颜色深度到底影响什么?
先看一个最直观的公式:
每帧数据量(字节) = 屏幕宽度 × 屏幕高度 × (LV_COLOR_DEPTH / 8)
举个例子。一块 480×272 的屏幕:
- LV_COLOR_DEPTH = 32:每帧 480 × 272 × 4 = 522,240 字节 ≈ 510 KB
- LV_COLOR_DEPTH = 16:每帧 480 × 272 × 2 = 261,120 字节 ≈ 255 KB
- LV_COLOR_DEPTH = 8:每帧 480 × 272 × 1 = 130,560 字节 ≈ 127 KB
数据量差了一倍甚至四倍。你想想看,同样的 SPI 总线或者 RGB 接口,传输 510 KB 和 255 KB 的时间能一样吗?
核心结论:颜色深度每降低一半,刷新带宽需求就降低一半。如果你的硬件接口带宽有限,降低色深是最直接的提速手段。
4.2 LV_COLOR_16_SWAP 是个什么鬼?
这个宏我一开始也觉得很迷惑。它只对 16 位色有效。16 位色通常用 RGB565 格式,也就是高 5 位是 R,中间 6 位是 G,低 5 位是 B。但有些 LCD 控制器或者 MCU 的硬件 SPI 接口,要求字节序是 小端 的。
举个例子:一个像素的颜色是 0xABCD(RGB565)。
- 不开启 SWAP:发送顺序是
0xAB→0xCD - 开启 SWAP:发送顺序是
0xCD→0xAB
这个交换是在 LVGL 内部完成的,不需要你手动处理。但问题来了——它会影响刷新速度吗?
我的经验:LV_COLOR_16_SWAP 本身不增加数据量,它只是交换两个字节的顺序。在 CPU 层面,这个操作几乎不花时间。真正影响速度的是你的 LCD 驱动是否原生支持 RGB565 小端序。如果硬件不支持,你开了 SWAP,LVGL 每帧都要做一次字节交换,虽然单次开销很小,但帧率高了以后,累计开销还是能感知到的。
4.3 不同组合下的性能实测对比
我在一个 STM32F429 平台上做过测试,屏幕是 480×272,使用 LTDC 接口 + 双缓冲。结果如下:
| 配置组合 | 每帧数据量 | 实测刷新率 | CPU 占用率 |
|---|---|---|---|
| LV_COLOR_DEPTH=32 | 510 KB | 42 fps | 78% |
| LV_COLOR_DEPTH=16, SWAP=0 | 255 KB | 58 fps | 45% |
| LV_COLOR_DEPTH=16, SWAP=1 | 255 KB | 56 fps | 48% |
| LV_COLOR_DEPTH=8 | 127 KB | 62 fps | 32% |
看到没?从 32 位降到 16 位,帧率直接从 42 跳到了 58,提升非常明显。而 SWAP 开启与否,只差了 2 fps,基本可以忽略。
注意:如果你的 LCD 控制器硬件不支持 RGB565 小端序,而你又不开启 SWAP,画面颜色会完全错乱。我曾经在这个坑里浪费了半天——画面显示出来全是紫色和绿色条纹,最后发现是字节序没对上。
4.4 如何选择?我的建议
- 优先用 16 位色:大部分嵌入式屏幕本身就只有 16 位色深,用 32 位纯属浪费带宽。除非你需要显示照片级图片或者做颜色渐变要求很高的 UI。
- 检查 LCD 数据手册:看它要求的像素数据格式是 RGB565 大端还是小端。如果是小端,就开启
LV_COLOR_16_SWAP;如果是大端,就不开。 - 8 位色慎用:虽然帧率最高,但颜色断层非常明显。只适合低端屏幕或者对颜色不敏感的应用,比如工业控制面板的简单文字界面。
- 32 位色只在必要时用:比如你的 UI 有大量半透明效果、阴影、渐变,或者你用了 LVGL 的
lv_opa混合功能。否则,别给自己找麻烦。
4.5 配置示例
在 lv_conf.h 中,你只需要关注这两行:
/* 颜色深度:16 位 */
#define LV_COLOR_DEPTH 16
/* 字节序交换:根据 LCD 硬件决定 */
#define LV_COLOR_16_SWAP 1
嗯,就这么简单。但很多人就是在这里翻车。我建议你拿到新屏幕后,先做一个纯色填充测试,看看颜色对不对。如果红色变成了蓝色,绿色变成了紫色,那大概率就是 SWAP 没配对。
4.6 一张图看懂选择逻辑
下面这张图是我自己总结的决策流程,你可以直接拿来用:
4.7 避坑指南
- 不要盲目追求 32 位色:我见过有人用 32 位色跑一个只有文字和矩形的界面,帧率只有 30fps,降到 16 位后直接到 60fps。UI 效果几乎看不出区别。
- SWAP 不是性能瓶颈:如果你发现开了 SWAP 后帧率下降明显,那大概率不是 SWAP 本身的问题,而是你的 LCD 驱动在字节交换时做了额外的内存拷贝。检查驱动代码,别冤枉 LVGL。
- 8 位色下不要用抗锯齿:LVGL 的抗锯齿在 8 位色下会使用抖动算法,效果很差,而且额外消耗 CPU。如果你必须用 8 位色,关掉
LV_ANTIALIAS。