Files
XCEngine/docs/plan/NewEditor_SystemAudit_2026-04-22.md

7.5 KiB
Raw Blame History

NewEditor System Audit

Date: 2026-04-22

1. Scope

本次审计目标不是继续“猜一个点然后修一个点”,而是重新检查 new_editor 当前还残留哪些:

  1. 旧代码或旧语义残留
  2. 冗余控制路径
  3. 临时性/补丁式结构
  4. 边界没有收口干净的模块职责

审计重点覆盖:

  • app/Platform/Win32
  • app/Rendering/D3D12
  • app/Rendering/Viewport
  • app/Composition
  • WindowManager

2. Confirmed Closed Items

这轮审计先确认了已经真正收掉的历史链路,避免把已经解决的问题重复列为风险:

  1. new_editor 中已无活跃的 D2D / Direct2D / D3D11On12 / NativeRenderer / WindowInterop 主窗口链路。
  2. D3D12UiRenderer 已不再保留活跃的 legacy/indexed 双路径 UI geometry 提交。
  3. 启动截图策略已经不再由旧的渲染层壳子控制,Rendering/Native 活 include 路径已清空。

这说明上一轮 D3D12 / 截图职责收口本身是有效的。

3. Primary Findings

3.1 High: frame execution still has multiple live owners

RenderFrame() 现在不是单点驱动,而是同时被多条路径直接调用:

根本问题不是“调用次数多”,而是“帧驱动权不唯一”:

  1. 主循环在主动渲染。
  2. WM_PAINT 在同步渲染。
  3. WM_SIZE / WM_DPICHANGED / WM_EXITSIZEMOVE 在消息里同步渲染。
  4. EditorWindowChromeController 在窗口过渡操作里直接同步渲染。

这会导致:

  1. 帧生成/Present 时机不再只有一个真实来源。
  2. EditorWindowFrameTransferRequests 的处理顺序在不同入口下不一致。
  3. resize / maximize / drag-restore 时Chrome 层直接拥有渲染副作用。
  4. 输入、布局、Present、窗口消息之间很难建立稳定时序。

这不是局部实现细节,而是当前 new_editor 最明显的未收口架构问题。

3.2 High: window destruction lifecycle still has multiple owners

窗口销毁收尾现在仍然散落在多处:

当前重复动作包括:

  1. window.Shutdown()
  2. DestroyWindow(hwnd)
  3. window.MarkDestroyed()
  4. m_windows 中 erase

根本问题是native window death、runtime shutdown、workspace removal、host container erase 没有一个唯一所有者。

这会导致:

  1. 生命周期语义只能靠“现在碰巧没炸”维持,而不是靠明确边界维持。
  2. 工具窗口、弹出窗口、独立面板窗口的关闭行为仍然容易反复回归。
  3. WorkspaceCoordinator 直接复制 host runtime 的 destroy 逻辑,说明边界没有收口。

这条问题和之前的“关子窗口把主窗口带走”属于同一类根因:生命周期控制权分裂。

3.3 Medium: EditorShellRuntime is still a monolithic per-frame god-object

EditorShellRuntime.cpp:549 开始的 EditorShellRuntime::Update(...) 仍然在一个单元里同时承担:

  1. shell definition 构建
  2. workspace/session 同步
  3. dock host interaction 更新
  4. viewport request / frame 应用
  5. hosted panel input 分发
  6. hierarchy / project / color picker / inspector / console 更新
  7. status / command focus / trace 同步

同一个 update 内还存在多次会话同步与定义重建:

这不是“旧链路残留”,但它是当前最明显的未拆分核心耦合点。它会导致:

  1. 任意一个 panel / dock / viewport 变更都容易影响整帧更新流程。
  2. 输入问题、状态问题、布局问题、面板问题很难局部定位。
  3. 后续继续做性能/交互优化时,改动面会被这个 god-object 放大。

4. Non-Findings

以下命中已确认不是这轮要处理的“旧代码/临时方案”问题:

  1. 普通 fallback 参数或默认值。
  2. DirectWriteD3D12UiTextSystem 中的文本栅格化使用。
  3. 视口 pass 中的 fallbackState,它表示材质渲染状态默认值,不是旧主窗口链路。

5. Audit Conclusion

截至本次审计,new_editor 不是“还有一堆 D2D 遗留没删干净”,那条主线已经基本收掉了。

当前剩余最关键的两个系统级问题是:

  1. 帧驱动权没有单点收口。
  2. 窗口销毁权没有单点收口。

如果后续继续做系统级收口,优先级应该是:

  1. 先把 frame scheduling / present / transfer request 统一到一个唯一驱动源。
  2. 再把 window close / destroy / shutdown / erase 统一到一个唯一生命周期所有者。
  3. 最后再拆 EditorShellRuntime 这个 per-frame god-object。