feat(lcd): add boundary performance test
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
# LCD 边界测试动画
|
||||
|
||||
## 测试资源
|
||||
|
||||
测试动画包含 16 张 320×240 PNG,对应当前单次播放请求允许的最大帧序列长度。
|
||||
|
||||
文件名为:
|
||||
|
||||
```text
|
||||
lcdtest00.png
|
||||
lcdtest01.png
|
||||
...
|
||||
lcdtest15.png
|
||||
```
|
||||
|
||||
每帧包含以下测试元素:
|
||||
|
||||
- 1 像素外边框和四色角标,用于检查裁切、偏移和方向;
|
||||
- RGB565 基础色条,用于检查 RGB/BGR 色序和颜色异常;
|
||||
- 连续移动的竖直白线和水平黄线,用于观察撕裂和跳帧;
|
||||
- 旋转红色指针和移动方块,用于观察运动连续性;
|
||||
- `F00`~`F15` 帧号,用于识别乱序和重复帧;
|
||||
- 16 格进度条,用于识别丢帧;
|
||||
- 4 位红绿二进制标记,用于辅助确认帧编号。
|
||||
|
||||
第 15 帧播放完后可以平滑回到第 0 帧。
|
||||
|
||||
## 真机触发
|
||||
|
||||
固件需要启用 Factory CLI。通过 UART0 发送:
|
||||
|
||||
```text
|
||||
lcd_test
|
||||
```
|
||||
|
||||
设备返回:
|
||||
|
||||
```text
|
||||
OK
|
||||
```
|
||||
|
||||
测试动画会:
|
||||
|
||||
- 立即打断当前普通动画;
|
||||
- 先循环播放 `00 → 05`,再按 `00 → 15` 顺序循环;
|
||||
- 每次全屏绘制后只等待 1 ms;
|
||||
- 两个性能阶段各运行约 5 秒,总计约 10 秒(不含预热时间);
|
||||
- 完成后自动返回待机动画。
|
||||
|
||||
1 ms 是额外等待时间,不代表 1000 FPS。实际帧率由 PNG 读取和解码、RGB565 转换、缓存命中情况以及 40 MHz SPI 全屏传输共同决定。
|
||||
|
||||
## 性能日志
|
||||
|
||||
测试会输出两条性能汇总日志,不会逐帧打印性能日志并干扰测试:
|
||||
|
||||
```text
|
||||
LCD sequence perf asset=lcd_boundary_test mode=cache_hit working_set=6 cache_capacity=6 frames=120 elapsed_ms=5010 fps=23.95 draw_us_avg=40680 draw_us_min=39520 draw_us_max=48760 hold_ms=1
|
||||
LCD sequence perf asset=lcd_boundary_test mode=cache_thrash working_set=16 cache_capacity=6 frames=38 elapsed_ms=5020 fps=7.56 draw_us_avg=131960 draw_us_min=108305 draw_us_max=343547 hold_ms=1
|
||||
```
|
||||
|
||||
`cache_hit` 阶段开始计时前会把第 0~5 帧解码并装入 6 帧缓存,计时期间直接从缓存读取 RGB565 数据。`cache_thrash` 阶段开始计时前会把第 10~15 帧装入缓存,使第 0 帧开始的 16 帧顺序播放持续发生缓存淘汰和重新解码。预热耗时不计入两个阶段的 FPS。
|
||||
|
||||
为避免时钟、充电和低电量图标占用同一组图片缓存槽位,边界测试帧不绘制这些运行时叠加层。普通动画的叠加层行为不受影响。
|
||||
|
||||
字段含义:
|
||||
|
||||
| 字段 | 含义 |
|
||||
| --- | --- |
|
||||
| `mode` | `cache_hit` 表示缓存命中;`cache_thrash` 表示工作集超过缓存容量 |
|
||||
| `working_set` | 当前阶段循环使用的不同图片数量 |
|
||||
| `cache_capacity` | 编译时配置的图片缓存槽位数量 |
|
||||
| `frames` | 已经完成 SPI 传输的全屏帧数 |
|
||||
| `elapsed_ms` | 整段测试的实际墙钟时间 |
|
||||
| `fps` | `frames ÷ elapsed_ms` 得到的真实平均帧率 |
|
||||
| `draw_us_avg` | 平均每帧读取、解码、转换和 SPI 传输耗时 |
|
||||
| `draw_us_min` | 最快一帧的绘制耗时 |
|
||||
| `draw_us_max` | 最慢一帧的绘制耗时 |
|
||||
| `hold_ms` | 每帧绘制完成后的配置等待时间 |
|
||||
|
||||
示例数值仅用于说明日志格式,必须以真机输出为准。
|
||||
|
||||
两组结果的用途不同:
|
||||
|
||||
- `cache_hit` 更接近 RGB565 帧已经在内存中时,LCD 合成与 SPI 全屏传输的速度上限;
|
||||
- `cache_thrash` 代表长动画超过缓存容量后,Flash 读取、PNG 解码、RGB565 转换和 SPI 传输叠加的实际速度。
|
||||
|
||||
## 观察方法
|
||||
|
||||
重点观察:
|
||||
|
||||
1. 帧号是否严格按 `F00` 到 `F15` 循环。
|
||||
2. 白色竖线和黄色横线是否连续移动。
|
||||
3. 指针是否匀速旋转,是否出现明显停顿或倒退。
|
||||
4. 屏幕边框和四角标记是否完整可见。
|
||||
5. 顶部色条颜色是否正确。
|
||||
6. 快速运动过程中是否出现上下区域属于不同帧的撕裂。
|
||||
7. 串口日志中是否出现 PNG 解码失败、资源缺失或 LCD 传输错误。
|
||||
|
||||
## 重新生成测试帧
|
||||
|
||||
测试帧由确定性脚本生成:
|
||||
|
||||
```bash
|
||||
python tools/generate_lcd_boundary_frames.py
|
||||
python tools/optimize_lcd_assets.py generate
|
||||
python tools/optimize_lcd_assets.py verify
|
||||
idf.py build
|
||||
```
|
||||
|
||||
生成脚本需要 Pillow。普通固件构建仍然不需要 Pillow。
|
||||
Reference in New Issue
Block a user