147 lines
7.5 KiB
Markdown
147 lines
7.5 KiB
Markdown
# 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()` 现在不是单点驱动,而是同时被多条路径直接调用:
|
||
|
||
- [EditorWindow.cpp:612](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\EditorWindow.cpp#L612)
|
||
- [EditorWindow.cpp:654](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\EditorWindow.cpp#L654)
|
||
- [EditorWindowChromeController.cpp:431](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\EditorWindowChromeController.cpp#L431)
|
||
- [EditorWindowChromeController.cpp:912](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\EditorWindowChromeController.cpp#L912)
|
||
- [EditorWindowHostRuntime.cpp:237](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowHostRuntime.cpp#L237)
|
||
- [EditorWindowMessageDispatcher.cpp:62](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowMessageDispatcher.cpp#L62)
|
||
- [EditorWindowMessageDispatcher.cpp:402](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowMessageDispatcher.cpp#L402)
|
||
- [EditorWindowMessageDispatcher.cpp:411](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowMessageDispatcher.cpp#L411)
|
||
- [EditorWindowMessageDispatcher.cpp:419](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowMessageDispatcher.cpp#L419)
|
||
- [EditorWindowMessageDispatcher.cpp:439](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowMessageDispatcher.cpp#L439)
|
||
|
||
根本问题不是“调用次数多”,而是“帧驱动权不唯一”:
|
||
|
||
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
|
||
|
||
窗口销毁收尾现在仍然散落在多处:
|
||
|
||
- [EditorWindowHostRuntime.cpp:172](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowHostRuntime.cpp#L172)
|
||
- [EditorWindowHostRuntime.cpp:194](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowHostRuntime.cpp#L194)
|
||
- [EditorWindowHostRuntime.cpp:262](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowHostRuntime.cpp#L262)
|
||
- [EditorWindowMessageDispatcher.cpp:428](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowMessageDispatcher.cpp#L428)
|
||
- [EditorWindowMessageDispatcher.cpp:452](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowMessageDispatcher.cpp#L452)
|
||
- [EditorWindowWorkspaceCoordinator.cpp:221](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowWorkspaceCoordinator.cpp#L221)
|
||
- [EditorWindowWorkspaceCoordinator.cpp:267](D:\Xuanchi\Main\XCEngine\new_editor\app\Platform\Win32\WindowManager\EditorWindowWorkspaceCoordinator.cpp#L267)
|
||
|
||
当前重复动作包括:
|
||
|
||
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](D:\Xuanchi\Main\XCEngine\new_editor\app\Composition\EditorShellRuntime.cpp#L549)
|
||
开始的 `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 内还存在多次会话同步与定义重建:
|
||
|
||
- [EditorShellRuntime.cpp:580](D:\Xuanchi\Main\XCEngine\new_editor\app\Composition\EditorShellRuntime.cpp#L580)
|
||
- [EditorShellRuntime.cpp:582](D:\Xuanchi\Main\XCEngine\new_editor\app\Composition\EditorShellRuntime.cpp#L582)
|
||
- [EditorShellRuntime.cpp:605](D:\Xuanchi\Main\XCEngine\new_editor\app\Composition\EditorShellRuntime.cpp#L605)
|
||
- [EditorShellRuntime.cpp:607](D:\Xuanchi\Main\XCEngine\new_editor\app\Composition\EditorShellRuntime.cpp#L607)
|
||
- [EditorShellRuntime.cpp:629](D:\Xuanchi\Main\XCEngine\new_editor\app\Composition\EditorShellRuntime.cpp#L629)
|
||
- [EditorShellRuntime.cpp:672](D:\Xuanchi\Main\XCEngine\new_editor\app\Composition\EditorShellRuntime.cpp#L672)
|
||
|
||
这不是“旧链路残留”,但它是当前最明显的未拆分核心耦合点。它会导致:
|
||
|
||
1. 任意一个 panel / dock / viewport 变更都容易影响整帧更新流程。
|
||
2. 输入问题、状态问题、布局问题、面板问题很难局部定位。
|
||
3. 后续继续做性能/交互优化时,改动面会被这个 god-object 放大。
|
||
|
||
## 4. Non-Findings
|
||
|
||
以下命中已确认不是这轮要处理的“旧代码/临时方案”问题:
|
||
|
||
1. 普通 `fallback` 参数或默认值。
|
||
2. `DirectWrite` 在 `D3D12UiTextSystem` 中的文本栅格化使用。
|
||
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。
|