拆分时间源以稳定 IMX6U 固定步长主循环
将计时职责从显示后端中移出,新增 Platform::ITimeSource 和 Core::Timer,使主循环基于单调整数毫秒生成固定步长 tick。 这样 SDL2/fb0 只负责显示和输入,游戏逻辑不再通过 Display 获取时间,也避免用 float 秒作为核心时间源。 同时增加 30/45/60 FPS 命令行档位,并用整数余数累计生成 33/33/34、22/22/22/22/23、16/17/17 这类毫秒节奏,便于在 IMX6U 上按性能预算选择目标帧率。 Constraint: IMX6U 运行时应避免核心逻辑依赖 float deltaSeconds Constraint: SDL2 只能作为显示/输入适配层,不能扩散到核心时间逻辑 Rejected: 继续让 IDisplay::get_time_ms 提供时间 | 显示后端职责过宽,SDL/fb0 切换会影响时间语义 Rejected: 直接固定 33ms 实现 30 FPS | 长时间运行会产生节拍漂移 Confidence: high Scope-risk: narrow Directive: 后续 Launcher/GameA/GameB 应通过 ITimeSource + Timer 获取 fixed_delta_ms,不要重新引入 Display 计时 Tested: cmake --build build-win --config Release Not-tested: IMX6U 实机 clock_gettime(CLOCK_MONOTONIC) 帧时间稳定性
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
|
||||
- **Windows 编译**:开发主力机通常是 Windows,有 IDE 调试、有图形窗口,渲染算法对不对一眼就能看到。这个阶段完全不关心嵌入式细节。
|
||||
- **Linux x86 编译**:验证代码在 GCC/Clang 下有无警告、CMake 配置是否跨平台、系统 SDL2 依赖是否正确。很多嵌入式工具链的问题在 x86 Linux 上就能提前暴露。
|
||||
- **ARM 交叉编译**:最终在 IMX6U 上跑。若目标板使用 SDL2,则 SDL2 仅作为显示/输入/计时适配层,核心渲染仍按 CPU framebuffer + 一次性提交设计;如需极简依赖,也保留 `/dev/fb0` 后端作为对照。
|
||||
- **ARM 交叉编译**:最终在 IMX6U 上跑。若目标板使用 SDL2,则 SDL2 仅作为显示/输入适配层,时间由独立 `Platform::ITimeSource` 提供,核心渲染仍按 CPU framebuffer + 一次性提交设计;如需极简依赖,也保留 `/dev/fb0` 后端作为对照。
|
||||
|
||||
|
||||
## 开发规范与性能红线
|
||||
@@ -28,14 +28,14 @@ IMX6U 运行时性能预算较紧,后续开发必须遵守 `docs/DEVELOPMENT_G
|
||||
- 核心逻辑和热路径默认不新增 `float` / `double`,需要小数时使用项目统一定点数;只在显示、调试、导入导出等边界层转换成浮点。
|
||||
- 主循环、每对象、每三角形/顶点/像素级代码中不得频繁创建 `std::vector` / `std::string` 等动态分配容器,应复用缓冲或使用固定容量结构。
|
||||
- PC/SDL 版本用于调试验证,不能把调试便利写法扩散到 ARM release 核心路径。
|
||||
- SDL2 后端只做显示、输入、计时和最终 framebuffer 提交,不在核心渲染/游戏逻辑中直接调用 SDL API。
|
||||
- SDL2 后端只做显示、输入和最终 framebuffer 提交;时间源独立于显示后端,不在核心渲染/游戏逻辑中直接调用 SDL API。
|
||||
- 新增核心代码前按规范文档中的检查清单自查。
|
||||
|
||||
## 应用层与图形库拆分
|
||||
|
||||
项目后续按“两个游戏 + 一个启动器 + 一套底层图形库”组织,详细边界见 `docs/APP_AND_GFX_ARCHITECTURE.md`:
|
||||
|
||||
- `Gfx` / 底层图形库:只提供 framebuffer、SDL2/fb0 平台适配、输入/时间源、基础绘制能力,例如点、线、矩形、四边形、sprite、bitmap font、tilemap。
|
||||
- `Gfx` / 底层图形库:只提供 framebuffer、SDL2/fb0 平台适配、独立时间源、基础绘制能力,例如点、线、矩形、四边形、sprite、bitmap font、tilemap。
|
||||
- `Apps/Launcher`:负责游戏选择、全局设置和启动流程。
|
||||
- `Apps/GameA`、`Apps/GameB`:分别维护自己的游戏规则、状态、资源和渲染调用。
|
||||
- `Shared`:只放应用层共享但不属于底层图形库的 UI、存档、配置、资源索引等。
|
||||
@@ -66,6 +66,15 @@ cmake --build build-win --config Release
|
||||
./build-win/Release/IMX6U-Game.exe
|
||||
```
|
||||
|
||||
可选帧率档位:
|
||||
```bash
|
||||
./build-win/Release/IMX6U-Game.exe --fps 30
|
||||
./build-win/Release/IMX6U-Game.exe --fps 45
|
||||
./build-win/Release/IMX6U-Game.exe --fps 60
|
||||
```
|
||||
|
||||
当前只接受 `30`、`45`、`60` 三档。主循环从 `Platform::ITimeSource` 读取单调整数毫秒时间,由 `Core::Timer` 生成固定步长 tick,并通过 `33/33/34`、`22/22/22/22/23`、`16/17/17` 这类整数节奏逼近对应目标帧率,避免核心时间源依赖 `float` 秒。
|
||||
|
||||
### Linux x86_64(Ubuntu / WSL2)
|
||||
|
||||
需要系统 SDL2:
|
||||
@@ -95,7 +104,7 @@ sudo apt-get install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf
|
||||
|
||||
本项目 ARM 端保留两类后端:
|
||||
|
||||
- **SDL2 后端**:目标是后续游戏主路径;SDL2 负责显示、输入、计时和最终 framebuffer 提交。
|
||||
- **SDL2 后端**:目标是后续游戏主路径;SDL2 负责显示、输入和最终 framebuffer 提交,时间源使用独立的 `Platform::ITimeSource`。
|
||||
- **Framebuffer 后端**:作为极简依赖和显示通路对照测试。
|
||||
|
||||
构建(Framebuffer 对照后端):
|
||||
@@ -196,7 +205,8 @@ assets/font/font_atlas.h
|
||||
│ Gfx:DrawContext、FrameBuffer、Draw2D、Math │
|
||||
├──────────────────────────────────────────────┤
|
||||
│ Platform::IDisplay │
|
||||
│ - SDLDisplay : SDL2 显示/输入/计时适配 │
|
||||
│ - SDLDisplay : SDL2 显示/输入适配 │
|
||||
│ - ITimeSource: 单调整数毫秒时间源 │
|
||||
│ - FBDisplay : /dev/fb0 对照后端 │
|
||||
└──────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -228,7 +238,7 @@ IMX6U-Game/
|
||||
│ │ ├─ RenderData/ # Color、Triangle 等数据结构
|
||||
│ │ ├─ Scene/ # Camera、Transform、Mesh
|
||||
│ │ ├─ Shading/ # 着色器(预留)
|
||||
│ │ ├─ Platform/ # IDisplay、SDLDisplay、FBDisplay
|
||||
│ │ ├─ Platform/ # IDisplay、SDLDisplay、FBDisplay、ITimeSource
|
||||
│ │ └─ Asset/ # ObjLoader 等资源加载
|
||||
│ ├─ Apps/
|
||||
│ │ └─ Demo/ # 当前 3D 立方体 demo 入口
|
||||
@@ -251,6 +261,7 @@ IMX6U-Game/
|
||||
### Core
|
||||
- **FrameBuffer**:CPU 侧颜色缓冲,渲染结果先写在这里
|
||||
- **DepthBuffer**:深度测试用 Z-buffer
|
||||
- **Timer**:整数毫秒固定步长 tick 生成器,支持 30/45/60 FPS 档位和每帧剩余时间计算
|
||||
|
||||
### Math
|
||||
- 通用数学类型:`Vector2/3/4`、`Matrix4x4`
|
||||
@@ -264,6 +275,7 @@ IMX6U-Game/
|
||||
- **IDisplay**:显示后端抽象,解耦渲染与输出
|
||||
- **SDLDisplay**:SDL2 后端,PC 调试和 IMX6U SDL2 目标路径共用这一类适配思想
|
||||
- **FBDisplay**:`/dev/fb0` 对照后端,用于极简显示通路验证
|
||||
- **ITimeSource / SteadyTimeSource**:独立时间源接口与单调时钟实现;Linux/IMX6U 使用 `clock_gettime(CLOCK_MONOTONIC)`,Windows 使用 `std::chrono::steady_clock`,Display 不再承担计时职责
|
||||
|
||||
## 当前状态与后续
|
||||
|
||||
|
||||
Reference in New Issue
Block a user