From 4d4b7f5599155c3a01c59de9ca306cb5e0a6beed Mon Sep 17 00:00:00 2001 From: wyc <1104749580@qq.com> Date: Thu, 23 Jul 2026 15:31:31 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=95=B4=E7=9A=84=E4=B8=80=E7=89=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/整体架构思路.md | 158 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 136 insertions(+), 22 deletions(-) diff --git a/doc/整体架构思路.md b/doc/整体架构思路.md index 12b543e..cbc7a09 100644 --- a/doc/整体架构思路.md +++ b/doc/整体架构思路.md @@ -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..renderScheduleMode +RenderAble..renderScheduleMaxFps +``` + +右键菜单的 Plot 基础栏提供: + +```text +渲染策略下拉框 +渲染检查FPS +最大渲染FPS +``` ## 12. prepareData 边界