Files
2026-07-23 13:41:30 +08:00

157 lines
2.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# startRender(int fps) 作用流程 FAQ
## startRender(int fps) 做了什么
`startRender(int refreshTimesPreSecond)` 只做两件事:
```text
保存 mRefreshTimesPreSecond
调用 startRender()
```
对应代码流程:
```text
Plot::startRender(int fps)
d->mRefreshTimesPreSecond = fps
Plot::startRender()
```
## startRender() 做了什么
`startRender()` 的作用是启动 Plot 的渲染调度。
流程:
```text
检查 Plot 是否正在析构
mRenderEnabled = true
投递任务到 asio scheduler
取消旧 mRenderTimer
scheduleRenderTimer()
submitRender()
```
它会立即触发一次 `submitRender()`,不是等下一个 timer 周期。
## fps 参数现在是不是严格帧率上限
不是。
当前 `fps` 只决定 asio timer 的周期:
```text
interval = round(1000.0 / fps)
```
timer 到期后:
```text
submitRender()
scheduleRenderTimer()
```
所以它的真实语义是周期性 heartbeat / 兜底触发,不是硬性 FPS cap。
## 为什么不是严格限帧
因为当前渲染是事件驱动为主。
除了 timer 会触发 `submitRender()`,下面这些路径也会立即触发:
```text
RenderAble::markStateDirty()
Plot::markRenderStateDirty()
requestRender()
submitRender()
```
```text
RenderData::markInputDirty()
RenderAble::markRenderDirty()
requestRender()
submitRender()
```
```text
finishRender()
pipeline.hasNewState()
submitRender()
```
只要 State/Input 有新版本,系统可以绕过 timer 周期继续推进下一帧。
## asio 里面还有没有定时器
有。
相关成员和函数:
```text
PlotPrivate::mRenderTimer
PlotPrivate::mRefreshTimesPreSecond
Plot::scheduleRenderTimer()
RenderScheduler::initializePlotOnScheduler()
```
`RenderScheduler::initializePlotOnScheduler()` 为每个 Plot 创建 `asio::steady_timer`
`scheduleRenderTimer()` 使用 `mRefreshTimesPreSecond` 计算间隔并注册 `async_wait`
## timer 在当前架构里还有没有必要
当前仍然有必要保留。
原因:
```text
保持 startRender(int) 旧调用语义
保证没有显式 dirty 事件时仍有周期性检查
作为异常丢事件后的兜底触发
给性能测试框提供一个稳定的周期参考
```
但它不是渲染正确性的唯一入口。
当前正确性主要依赖:
```text
State dirty
Input dirty
finishRender 后续版本检查
```
## 如果以后要严格限帧应该怎么做
应该新增独立调度策略,而不是继续复用 `startRender(int)` 的现有语义。
建议拆成:
```text
Immediate
dirty 后立即 requestRender()
FixedRate
dirty 后只标记 pending,由 timer 周期统一 submitRender()
Throttle
dirty 后允许立即渲染,但两帧之间必须满足最小间隔
```
这样 `startRender(int)` 才能变成明确的帧率策略参数。