refactor(srp): let universal assets declare native backend keys

This commit is contained in:
2026-04-19 23:32:41 +08:00
parent 21b790c2f8
commit 9c8f2ae84c
9 changed files with 458 additions and 9 deletions

View File

@@ -0,0 +1,202 @@
# SRP Universal 原生后端 Key 接缝计划 2026-04-19
## 1. 阶段目标
上一阶段已经把 Mono managed SRP 的:
1. host renderer
2. stage recorder
收到了同一条 native backend ownership 上。
但当前仍然有一个关键问题没有解决:
`MonoManagedRenderPipelineAssetRuntime`
现在还是统一硬编码返回:
`BuiltinForwardPipelineAsset`
这意味着:
1. managed asset 自己并没有显式声明“我要哪个 native backend”
2. first-party `UniversalRenderPipelineAsset` 和普通 `ScriptableRenderPipelineAsset`
在 native backend 选择上没有语义区别
3. 未来想让不同 SRP/renderer data 走不同 native backend 时,
还会继续卡在 Mono runtime 的类型外部硬编码
本阶段目标就是把这件事改成:
`ScriptableRenderPipelineAsset`
-> 返回 native backend key
-> Mono runtime 解析 key
-> native factory 映射到 `RenderPipelineAsset`
先把“谁声明 backend”这件事正式落到 managed asset 自己身上。
---
## 2. 当前问题
### 2.1 Universal 虽然已经有 `rendererData`,但还没有 native backend 声明权
当前 `UniversalRenderPipelineAsset` 已经拥有:
1. `rendererData`
2. `CreatePipeline()`
3. `ConfigureCameraRenderRequest()`
这些都说明 managed package 侧已经在承担“渲染管线组织”责任。
但 native backend 选择仍然没有经过它,而是 Mono runtime 统一硬编码。
这不符合我们要的方向:
1. first-party Universal 应该先成为第一个显式声明 backend 的包
2. Mono runtime 只负责桥接,不负责替 asset 做产品决策
### 2.2 当前 `CreateNativeSceneRendererFromAsset(nullptr)` 语义不干净
上一阶段新补的:
`CreateNativeSceneRendererFromAsset(...)`
内部现在仍然会走:
`ResolveRenderPipelineAssetOrDefault(...)`
这对于“从一个明确 backend asset 创建 native scene renderer”这件事来说语义过重了。
如果传入 `nullptr`,它不该再去全局查询 configured render pipeline asset
更不该重新把当前 managed pipeline asset 自己绕回来。
这个点如果不修,后面 backend key seam 加上去以后,
scene recorder 的 fallback 仍然有可能偷偷回到全局 configured asset
会把 ownership 再次搞脏。
### 2.3 当前还缺一组“unknown backend key 也不会崩”的测试
我们不仅要验证:
1. Universal 显式声明 builtin forward key 能被解析
还要验证:
1. key 不存在时 runtime 返回空 asset
2. recorder 仍然能本地 fallback 到默认 native scene renderer
3. 不会因为 unknown key 让 managed stage graph 录制回归
---
## 3. 本阶段方案
### 方案核心
新增一条受控的 managed seam
`ScriptableRenderPipelineAsset`
-> `GetPipelineRendererAssetKey()`
-> Mono runtime
-> native factory key mapping
-> `RenderPipelineAsset`
### 第一阶段只落 first-party Universal
本阶段只让:
`UniversalRenderPipelineAsset`
显式返回:
`BuiltinForward`
也就是说:
1. Universal 成为第一个正式声明 native backend 的 managed package
2. 普通 `ScriptableRenderPipelineAsset` 先保持默认不声明
3. Mono runtime 对“未声明 key”的 asset 返回 `nullptr`
4. host / recorder 再按本地 fallback 兜底
### 这样做的原因
这样能同时保证两件事:
1. 我们正式建立了面向未来的 backend key seam
2. 又不会一次性把所有 custom SRP 公共 API 扩太大
---
## 4. 实施步骤
### Step 1给 managed asset 加 backend key seam
目标:
1.`ScriptableRenderPipelineAsset` 新增受保护虚方法
2. 默认返回空 key
3. `UniversalRenderPipelineAsset` override 返回 `BuiltinForward`
### Step 2补 native key -> asset 工厂映射
目标:
1. 在 native factory 层新增统一的 key 解析入口
2. 当前先支持 `BuiltinForward`
3. 保证未来增加更多 native backend 时,不需要把 if/switch 散落到 Mono runtime
### Step 3重构 Mono runtime 的 backend asset 解析
目标:
1. `MonoManagedRenderPipelineAssetRuntime::GetPipelineRendererAsset()`
不再硬编码 builtin forward
2. 改为调用 managed asset 的 backend key 方法
3. 按 key 去 native factory 解析 asset
4. 未声明或未知 key 时返回空 asset
### Step 4修正 recorder fallback 语义
目标:
1. `CreateNativeSceneRendererFromAsset(nullptr)` 不再回查全局 configured pipeline asset
2. recorder fallback 只在“本地 asset 解析失败”后回到默认 native scene renderer
3. 避免 native backend 选择再次绕回全局 configured managed asset
### Step 5补测试并完整验证
目标:
1. 增加 scripting tests验证 Universal backend key -> builtin forward asset
2. 增加 unknown key fallback 回归测试
3. 编译 `rendering_unit_tests``scripting_tests``XCEditor`
4. 旧版 editor 10s 冒烟
5. 归档 plan、提交、推送
---
## 5. 验收标准
本阶段完成后应满足:
1. native backend 的声明责任开始落到 managed asset 自己
2. first-party Universal 是第一个显式声明 native backend 的包
3. Mono runtime 不再统一硬编码 builtin forward backend
4. recorder fallback 不再回查全局 configured managed asset
5. unknown backend key 不会导致 managed stage recording 崩坏
---
## 6. 本阶段不做的事
本阶段明确不做:
1. 不开放完整用户自定义 backend key 注册系统
2. 不做 deferred
3. 不做 lightmap / baking
4. 不做 renderer data 到 native renderer asset 的复杂序列化桥
5. 不做 editor workflow 扩展
这一刀只建立:
`managed asset -> backend key -> native asset`
这条正式接缝。