优化
This commit is contained in:
+158
-9
@@ -348,15 +348,78 @@ ready_color.version 新于 front_color.version:
|
||||
paintEvent 流程:
|
||||
|
||||
```text
|
||||
try swap front_color, ready_color
|
||||
按 Plot_Buffer_Acquire_Mode 消费 ready_color
|
||||
mark front_color
|
||||
drawImage(front_color)
|
||||
unmark front_color
|
||||
```
|
||||
|
||||
paintEvent 只能使用 Try,不允许等待后台。
|
||||
Plot_Buffer_Acquire_Mode 有两种策略:
|
||||
|
||||
## 8. 调度版本
|
||||
```text
|
||||
Try:
|
||||
paintEvent 尝试交换 ready_color -> front_color。
|
||||
如果物理 buffer 正忙,立即放弃本次新帧消费。
|
||||
这是默认模式,GUI 线程不进入 atomic_wait。
|
||||
|
||||
Wait:
|
||||
paintEvent 等待参与交换或 front_color lease 可用。
|
||||
只适合调用方明确接受 GUI 线程短暂等待的场景。
|
||||
```
|
||||
|
||||
Color 发布侧仍然可以等待 Color_Render / Color_Ready,因为它运行在调度和后台渲染流程,不阻塞 Qt paintEvent。
|
||||
|
||||
## 8. 三缓冲获取策略
|
||||
|
||||
三缓冲获取策略不是单一全局开关,而是分层控制。
|
||||
|
||||
Plot 层:
|
||||
|
||||
```text
|
||||
Plot_Buffer_Acquire_Mode
|
||||
```
|
||||
|
||||
只控制 Qt paintEvent 消费 Color_Ready / Color_Front 的行为。
|
||||
|
||||
默认:
|
||||
|
||||
```text
|
||||
Try
|
||||
```
|
||||
|
||||
RenderAble 层:
|
||||
|
||||
```text
|
||||
Triple_Buffer_Mode
|
||||
```
|
||||
|
||||
控制单个 RenderAble 在后台 draw 阶段获取 State_Render lease 的行为。
|
||||
|
||||
默认:
|
||||
|
||||
```text
|
||||
Wait
|
||||
```
|
||||
|
||||
RenderAble 设置为 Try 后:
|
||||
|
||||
```text
|
||||
draw 阶段取不到 State_Render lease
|
||||
↓
|
||||
跳过该 RenderAble 本帧绘制
|
||||
```
|
||||
|
||||
State/Input 的编辑发布路径默认仍使用 Wait。
|
||||
|
||||
原因:
|
||||
|
||||
```text
|
||||
setter / giveData 当前多数是 void 语义。
|
||||
Try 失败后没有统一返回值表达本次修改是否被接受。
|
||||
在没有重新设计 API 返回语义前,不允许静默丢弃编辑和输入。
|
||||
```
|
||||
|
||||
## 9. 调度版本
|
||||
|
||||
渲染调度使用 RenderPipeline 的帧版本。
|
||||
|
||||
@@ -380,7 +443,45 @@ Input dirty 不递增 edit_state.version。
|
||||
|
||||
它保证流式输入不会导致 RenderState 全量复制。
|
||||
|
||||
## 9. prepareData 边界
|
||||
## 10. asio timer 和帧率
|
||||
|
||||
Plot 仍保留 asio steady_timer:
|
||||
|
||||
```text
|
||||
PlotPrivate::mRenderTimer
|
||||
PlotPrivate::mRefreshTimesPreSecond
|
||||
Plot::startRender(int refreshTimesPreSecond)
|
||||
Plot::scheduleRenderTimer()
|
||||
```
|
||||
|
||||
当前 timer 的语义:
|
||||
|
||||
```text
|
||||
按 mRefreshTimesPreSecond 周期触发 submitRender()
|
||||
作为渲染 heartbeat / 兜底轮询
|
||||
保持旧 startRender(int) 调用语义
|
||||
```
|
||||
|
||||
当前 timer 不是严格 FPS 上限。
|
||||
|
||||
原因:
|
||||
|
||||
```text
|
||||
State dirty 会立即 requestRender()
|
||||
Input dirty 会立即 requestRender()
|
||||
finishRender 发现还有新版本也会继续 submitRender()
|
||||
```
|
||||
|
||||
因此实际渲染触发是:
|
||||
|
||||
```text
|
||||
事件驱动为主
|
||||
timer 周期触发为辅
|
||||
```
|
||||
|
||||
如果后续需要严格限帧,应该增加独立的 render trigger 策略,而不是把 startRender(int) 继续解释成硬性 FPS cap。
|
||||
|
||||
## 11. prepareData 边界
|
||||
|
||||
prepareData 的标准流程:
|
||||
|
||||
@@ -413,7 +514,7 @@ prepareData 不应该触发 QWidget 绘制。
|
||||
|
||||
prepareData 不应该把 RenderCache 复制回 State。
|
||||
|
||||
## 10. draw 边界
|
||||
## 12. draw 边界
|
||||
|
||||
draw 的标准流程:
|
||||
|
||||
@@ -431,7 +532,7 @@ draw 不修改 ready_state。
|
||||
|
||||
draw 不做输入队列交换。
|
||||
|
||||
## 11. 数据分类规则
|
||||
## 13. 数据分类规则
|
||||
|
||||
判断一个字段应该放哪里:
|
||||
|
||||
@@ -459,7 +560,7 @@ draw 不做输入队列交换。
|
||||
把配置项放 InputData。
|
||||
```
|
||||
|
||||
## 12. 锁使用边界
|
||||
## 14. 锁使用边界
|
||||
|
||||
radio 渲染链路不允许使用 RenderData 对象级大锁。
|
||||
|
||||
@@ -475,12 +576,15 @@ RenderPipeline:
|
||||
只保护帧发布和 Qt update 请求合并。
|
||||
|
||||
Plot / TimerThread:
|
||||
mRenderEnabled / mDestroying / mActiveRenderTasks / pending render size 使用 atomic。
|
||||
mRenderEnabled / mDestroying / mActiveRenderTasks / pending render size / paint buffer acquire mode 使用 atomic。
|
||||
mRenderTaskMutex + mRenderTaskDone 只用于 Plot 析构等待已投递任务结束。
|
||||
TimerThread::postAndWait 的局部 mutex + condition_variable 只用于跨线程同步 shutdown/removePlot。
|
||||
|
||||
PerformanceShower:
|
||||
mMutex 只保护统计 map 和显示列表。
|
||||
计数使用 CPP_Core/Core/Statistics::Speed_Statistics。
|
||||
耗时使用 CPP_Core/Core/Statistics::Value_Statistics。
|
||||
Value_Statistics 提供 instant / smooth / variation。
|
||||
```
|
||||
|
||||
不允许重新引入:
|
||||
@@ -524,7 +628,52 @@ spdlog / asio / googlepinyin:
|
||||
|
||||
这些同步不能向 RenderData、prepareData、draw 路径扩散。
|
||||
|
||||
## 13. 最终规则
|
||||
## 15. 性能统计
|
||||
|
||||
性能测试框不再维护自己的耗时平滑算法。
|
||||
|
||||
计数类数据:
|
||||
|
||||
```text
|
||||
PerformanceShower::counterIncrease()
|
||||
↓
|
||||
Psc::Speed_Statistics::update(1)
|
||||
```
|
||||
|
||||
耗时类数据:
|
||||
|
||||
```text
|
||||
Cacl 析构
|
||||
↓
|
||||
Psc::Value_Statistics::update(useTime)
|
||||
```
|
||||
|
||||
Value_Statistics 的含义:
|
||||
|
||||
```text
|
||||
instant:
|
||||
本次采样值。
|
||||
|
||||
average:
|
||||
保留旧字段语义的 EWMA 平均值。
|
||||
|
||||
smooth:
|
||||
类似 SRTT 的平滑值。
|
||||
|
||||
variation:
|
||||
类似 RTTVAR 的波动估计。
|
||||
它不是严格方差或标准差,而是 instant 与 smooth 偏差的 EWMA。
|
||||
```
|
||||
|
||||
性能框显示耗时时使用:
|
||||
|
||||
```text
|
||||
instant
|
||||
SRTT
|
||||
RTTVAR
|
||||
```
|
||||
|
||||
## 16. 最终规则
|
||||
|
||||
```text
|
||||
State 负责配置快照。
|
||||
|
||||
Reference in New Issue
Block a user