完整的一版
This commit is contained in:
+136
-22
@@ -527,45 +527,159 @@ TimerThread
|
||||
|
||||
所有 Plot 共用一个 scheduler。
|
||||
|
||||
## 11. asio timer 和帧率
|
||||
## 11. 渲染管线和调度策略
|
||||
|
||||
Plot 仍保留 asio steady_timer:
|
||||
渲染拆成两层:
|
||||
|
||||
```text
|
||||
PlotPrivate::mRenderTimer
|
||||
PlotPrivate::mRefreshTimesPreSecond
|
||||
Plot::startRender(int refreshTimesPreSecond)
|
||||
Plot::scheduleRenderTimer()
|
||||
RenderPipeline:
|
||||
管 State/Input/Color 三缓冲、jobState、一次提交。
|
||||
|
||||
RenderSchedulePolicy:
|
||||
管什么时候触发一次提交。
|
||||
```
|
||||
|
||||
`mRenderTimer` 绑定到全局 RenderScheduler 的 asio::io_context。
|
||||
|
||||
当前 timer 的语义:
|
||||
核心边界:
|
||||
|
||||
```text
|
||||
按 mRefreshTimesPreSecond 周期触发 submitRender()
|
||||
作为渲染 heartbeat / 兜底轮询
|
||||
保持旧 startRender(int) 调用语义
|
||||
submitRenderOnce()
|
||||
```
|
||||
|
||||
当前 timer 不是严格 FPS 上限。
|
||||
|
||||
原因:
|
||||
只负责:
|
||||
|
||||
```text
|
||||
State dirty 会立即 requestRender()
|
||||
Input dirty 会立即 requestRender()
|
||||
finishRender 发现还有新版本也会继续 submitRender()
|
||||
当前是否可以提交一帧。
|
||||
如果可以,准备数据并投递 CPU render。
|
||||
成功返回 true。
|
||||
失败返回 false。
|
||||
```
|
||||
|
||||
因此实际渲染触发是:
|
||||
它不负责:
|
||||
|
||||
```text
|
||||
事件驱动为主
|
||||
timer 周期触发为辅
|
||||
限速
|
||||
是否追帧
|
||||
是否响应 timer
|
||||
finish 后是否继续
|
||||
```
|
||||
|
||||
如果后续需要严格限帧,应该增加独立的 render trigger 策略,而不是把 startRender(int) 继续解释成硬性 FPS cap。
|
||||
这些全部属于调度策略。
|
||||
|
||||
Plot 级调度模式:
|
||||
|
||||
```text
|
||||
Plot_Render_Schedule_Mode::Timer_Check
|
||||
Plot_Render_Schedule_Mode::Chase_Latest
|
||||
Plot_Render_Schedule_Mode::Max_Fps
|
||||
Plot_Render_Schedule_Mode::Manual
|
||||
```
|
||||
|
||||
语义:
|
||||
|
||||
```text
|
||||
Timer_Check:
|
||||
只响应 asio timer。
|
||||
dirty 只推进版本,不立即提交。
|
||||
|
||||
Chase_Latest:
|
||||
dirty、timer、finish、manual 都会尝试提交。
|
||||
finish 后如果仍有新状态,会继续追最新帧。
|
||||
|
||||
Max_Fps:
|
||||
dirty 不丢弃。
|
||||
如果没到下一帧允许提交时间,只记录 pending 并安排 mSubmitTimer。
|
||||
到点后只提交最新状态。
|
||||
|
||||
Manual:
|
||||
只响应 Render_Request_Source::Manual。
|
||||
```
|
||||
|
||||
请求来源:
|
||||
|
||||
```text
|
||||
Render_Request_Source::Timer
|
||||
Render_Request_Source::Dirty
|
||||
Render_Request_Source::Finish
|
||||
Render_Request_Source::Manual
|
||||
```
|
||||
|
||||
`startRender(int fps)` 的语义改成:
|
||||
|
||||
```text
|
||||
启动渲染调度。
|
||||
设置 timer 检查频率。
|
||||
是否按这个 fps 限制实际 render,由 Plot_Render_Schedule_Mode 决定。
|
||||
```
|
||||
|
||||
严格限帧使用:
|
||||
|
||||
```text
|
||||
Plot_Render_Schedule_Mode::Max_Fps
|
||||
Plot::setMaxRenderFps()
|
||||
```
|
||||
|
||||
asio timer 分成两个:
|
||||
|
||||
```text
|
||||
mRenderTimer:
|
||||
周期性产生 Render_Request_Source::Timer。
|
||||
|
||||
mSubmitTimer:
|
||||
Max_Fps 或 RenderAble 局部 Max_Fps 的延迟提交唤醒。
|
||||
```
|
||||
|
||||
RenderAble 级策略:
|
||||
|
||||
```text
|
||||
RenderAble_Render_Schedule_Mode::Inherit
|
||||
RenderAble_Render_Schedule_Mode::Chase_Latest
|
||||
RenderAble_Render_Schedule_Mode::Max_Fps
|
||||
RenderAble_Render_Schedule_Mode::On_Dirty
|
||||
RenderAble_Render_Schedule_Mode::Manual
|
||||
```
|
||||
|
||||
RenderAble 默认:
|
||||
|
||||
```text
|
||||
Inherit
|
||||
```
|
||||
|
||||
RenderAble 局部策略控制:
|
||||
|
||||
```text
|
||||
本轮是否把该 RenderAble 的 State/Input 推进到 render 侧。
|
||||
```
|
||||
|
||||
如果一个 RenderAble 没通过自己的策略闸门:
|
||||
|
||||
```text
|
||||
prepareData 不执行。
|
||||
render_state / RenderCache 保持上一帧。
|
||||
draw 仍读取上一帧已经发布的 render 侧数据。
|
||||
```
|
||||
|
||||
这样一个高频对象不会强迫静态对象每帧同步 State/Input。
|
||||
|
||||
独立像素缓存对象也走同一套 RenderAble 策略。
|
||||
|
||||
PerformanceShower 可以观测:
|
||||
|
||||
```text
|
||||
Pipeline.renderScheduleMode
|
||||
Pipeline.renderCheckFps
|
||||
Pipeline.maxRenderFps
|
||||
Pipeline.renderSubmitPending
|
||||
RenderAble.<name>.renderScheduleMode
|
||||
RenderAble.<name>.renderScheduleMaxFps
|
||||
```
|
||||
|
||||
右键菜单的 Plot 基础栏提供:
|
||||
|
||||
```text
|
||||
渲染策略下拉框
|
||||
渲染检查FPS
|
||||
最大渲染FPS
|
||||
```
|
||||
|
||||
## 12. prepareData 边界
|
||||
|
||||
|
||||
Reference in New Issue
Block a user