修正板端性能测试误判并加速 framebuffer 提交

板端测试发现轻量 Demo 在未优化 ARM 构建下只有十几帧,但 Release 构建后可达到约 76 FPS。问题主要来自单配置 CMake 构建未默认启用 Release,以及 fb0 提交路径逐像素通用转换成本过高。

本次变更将单配置生成器默认构建类型设为 Release,避免 ARM/fb0 性能测试误用未优化构建;同时为 FBDisplay 增加 RGB565、ARGB8888/XRGB8888、RGBA8888 连续内存等常见格式快速路径。Demo 临时移除旋转正方体,保留 2D sprite、tilemap、FPS 和 Frame/Present 耗时显示,用于定位板端 framebuffer 提交瓶颈。

Constraint: IMX6U framebuffer 性能结论必须基于 Release 构建
Constraint: 核心代码保持 C++11 兼容,不引入新依赖
Rejected: 直接判断板子性能不足 | 未优化构建会严重放大逐像素循环成本
Rejected: 继续优化 3D 正方体路径 | 当前瓶颈已由 Frame/Present 计时证明主要在 fb0 present
Confidence: high
Scope-risk: moderate
Directive: 后续板端性能测试先确认 CMAKE_BUILD_TYPE=Release,再分析算法瓶颈
Directive: 2D-only 场景不要使用会清 depth buffer 的 DrawContext::clear()
Tested: cmake --build build-win --config Release
Tested: wsl bash -lc "cd /mnt/d/source/IMX6U-Game && cmake --build build-arm-fb"
Not-tested: 实机 framebuffer 像素格式以外的非常见 fb0 layout
This commit is contained in:
SepComet
2026-06-07 14:24:32 +08:00
parent a9bc9a59fb
commit d92b890528
13 changed files with 156 additions and 211 deletions
+20 -1
View File
@@ -115,6 +115,8 @@ cmake -B build-arm-fb \
cmake --build build-arm-fb
```
说明:单配置生成器(Makefile/Ninja)默认使用 `Release` 构建;ARM / framebuffer 性能测试必须确认 `CMAKE_BUILD_TYPE=Release`,否则逐像素绘制和 `/dev/fb0` 提交会因未优化构建出现数量级偏差。
构建(SDL2 后端,要求工具链/sysroot 可找到目标板 SDL2 开发库):
```bash
cmake -B build-arm-sdl \
@@ -277,6 +279,21 @@ IMX6U-Game/
- **FBDisplay**:`/dev/fb0` 对照后端,用于极简显示通路验证
- **ITimeSource / SteadyTimeSource**:独立时间源接口与单调时钟实现;Linux/IMX6U 使用 `clock_gettime(CLOCK_MONOTONIC)`,Windows 使用 `std::chrono::steady_clock`,Display 不再承担计时职责
### Framebuffer 性能说明
`FBDisplay` 是直接写 `/dev/fb0` 的对照后端。当前实现会从 CPU 侧 `FrameBuffer` 提交到系统 framebuffer,并针对常见像素格式提供快速路径:
- RGB565:使用专用 RGBA -> RGB565 转换;
- ARGB8888 / XRGB8888 类 32bpp:使用专用通道重排;
- RGBA8888 且行宽连续时:整块 `memcpy`。
板端性能测试必须使用 Release 构建。一次测试中,未优化 ARM 构建曾导致 `Frame:81ms / Present:69ms`,开启 Release 后同一轻量 2D demo 可达到约 76 FPS。该结果说明 `/dev/fb0` 整屏提交仍是关键热点,但构建类型会极大影响结论。后续优化优先级:
1. 直接使用与目标 fb0 一致的 backbuffer 像素格式,例如 RGB565,减少提交时转换;
2. 2D 场景使用 dirty rect / 局部提交,避免每帧整屏写入;
3. 避免无 3D 内容时清理 depth buffer;
4. 对 tile/sprite 增加不透明行拷贝、预转换资源或专用批处理路径。
## 当前状态与后续
**已完成:**
@@ -284,13 +301,15 @@ IMX6U-Game/
- 双平台显示后端(SDL2 / Framebuffer)
- 离线资源转换工具:PNG sprite -> C++ 头文件,像素字体 -> bitmap atlas/header
- 基础 2D sprite、SpriteRegion、bitmap font 文本绘制和 tilemap 视口绘制,当前 demo 显示 FPS 文本、测试 sprite 和小型滚动 tilemap
- 当前板端性能 demo 已临时移除旋转正方体,只保留 2D sprite/tilemap/FPS 与 `Frame/Present` 耗时显示,用于测量 framebuffer 提交瓶颈
- Gfx 目录规范化,代码收敛到 `src/Gfx/`
- `Gfx::DrawContext` 统一绘制入口,封装现有绘制能力
- `DrawContext::clear_color()` 支持只清颜色缓冲,避免 2D-only demo 每帧无意义清 depth buffer
- C++11 兼容代码
- CMake 跨平台构建
**待完成(按优先级):**
1. FrameBuffer 性能优化(`memset` 清屏、去掉 `at()`、定点数/NEON)
1. FrameBuffer / FBDisplay 性能优化(目标像素格式 backbuffer、dirty rect、专用 tile/sprite 快路径、NEON)
2. 应用层拆分(Launcher / GameA / GameB / Shared)和统一 `IApp` 主循环
3. SDL2 输入抽象(键盘/触摸/按键状态快照)
4. Gfx 基础 2D 绘制接口(矩形、四边形、继续完善 Sprite/Text/Tilemap 的批处理和专用快路径)