Add prioritized render scheduling#2174
Conversation
|
I remeber pre-rendering cancellation existed from the very beginning. Invalidation mechanism seems over-complicated. Priority and user attention is all you need. |
I'll remove the invalidation-related command hooks and tests, and revise the PR description to focus on render priority rather than invalidation.🤔 |
…intainer review Based on stakira's feedback: - Remove GetRenderInvalidations() command hook (over-complicated, never used) - Remove RenderInvalidation.cs and RenderInvalidationTest.cs - Revert all command changes (NoteCommands, ExpCommands, PartCommands) - Revert DocManager, PlaybackManager, RenderEngine, Notifications changes Keep the existing RenderPriority and phrase ordering logic intact: - RenderPriority.cs (sorting rules) - OrderForPlayback / OrderForPreRender in RenderEngine - PreRenderNotification with focusPart/focusTick Update RenderPriorityTest: - Remove Overlaps tests (method doesn't exist in master) - Rename methods for consistency - Add PlaybackDistance coverage
|
本地审查完成,我这里没有发现阻塞问题。 这次改动范围比较小,方向也合理:playback/pre-render 的渲染顺序现在会优先处理当前播放位置或用户关注区域,而不是引入更复杂的 invalidation hook。新增的 helper 级测试覆盖了 bucket/distance 的排序规则。 非阻塞建议:后续如果方便,可以补一个覆盖 验证:CI 全绿;我本地也跑了 AGIC,GPT-5.5 |
本改动解决的问题是:当 OpenUtau 正在进行全工程预渲染时,如果用户修改了某个已经渲染过的片段,旧逻辑会按原来的工程顺序继续排队,用户需要等待前面大量 phrase 渲染完成后才能听到修改结果。现在系统会根据本次命令影
响的声图片段和 tick 范围,把相关 phrase 提前到预渲染队列前部,从而更快反馈用户刚刚编辑的内容。
改动逻辑
核心思路是把“哪些区域需要优先重新渲染”做成通用命令 hook,而不是写死在 DiffSinger 中。
流程如下:
命令执行、撤销、重做结束后,DocManager 收集本组命令的渲染失效范围。
命令通过 GetRenderInvalidations() 返回受影响的 UVoicePart + startTick/endTick。
DocManager 将这些范围合并成 PreRenderPriority,放入 PreRenderNotification。
PlaybackManager 收到预渲染通知后,把优先范围传给 RenderEngine。
RenderEngine 在构建 phrase 队列后,只调整渲染顺序:
renderer 本身不需要知道这个机制,DiffSinger、UTAU 等 renderer 的渲染实现未被修改。
本改动不改变音频生成逻辑、不改变 phrase hash、不改变缓存格式,也不添加 DiffSinger 专用逻辑。它只影响 RenderEngine 对待渲染 phrase 的排序。
修改文件
OpenUtau.Core/Commands/UCommand.cs
新增 GetRenderInvalidations() 虚方法,作为所有命令可选实现的通用 hook。
OpenUtau.Core/Commands/NoteCommands.cs
让音符类命令返回受影响音符范围,用于优先渲染对应 phrase。
OpenUtau.Core/Commands/PartCommands.cs
让声图片段相关命令返回整个 voice part 的影响范围。
OpenUtau.Core/Commands/ExpCommands.cs
让表达参数、pitch、curve 等编辑命令返回对应影响范围。曲线绘制合并后仍保留本次绘制的 tick 范围,用于排队优先级。
OpenUtau.Core/Commands/Notifications.cs
扩展 PreRenderNotification,新增 PreRenderPriority,允许预渲染通知携带优先范围。
OpenUtau.Core/DocManager.cs
在 EndUndoGroup()、Undo()、Redo() 中收集命令 invalidation,并生成带优先级的预渲染通知。
OpenUtau.Core/PlaybackManager.cs
将 PreRenderNotification 中的优先范围传入 RenderEngine。
OpenUtau.Core/Render/RenderEngine.cs
新增播放/预渲染的 phrase 排序逻辑。渲染结果不变,只改变队列顺序。
新增文件
OpenUtau.Core/Commands/RenderInvalidation.cs
定义命令返回的渲染失效范围:UVoicePart + startTick + endTick。
OpenUtau.Core/Render/RenderPriority.cs
封装 RenderEngine 使用的排序规则,便于测试和维护。
OpenUtau.Core/Properties/AssemblyInfo.cs
开放 internal 类型给 OpenUtau.Test,用于测试 RenderPriority。
OpenUtau.Test/Core/Commands/RenderInvalidationTest.cs
测试命令是否正确报告受影响的工程 tick 范围。
OpenUtau.Test/Core/Render/RenderPriorityTest.cs
测试播放和预渲染排序规则。