refactor(srp): add managed lifecycle cleanup seams

Invoke managed pipeline disposal and asset runtime cleanup from the native bridge lifecycle. Add Universal renderer and feature cleanup hooks plus regression probes to verify runtime cache teardown semantics.
This commit is contained in:
2026-04-20 01:14:37 +08:00
parent beaf5809d5
commit 58dde75d3d
10 changed files with 900 additions and 0 deletions

View File

@@ -0,0 +1,132 @@
# SRP Managed生命周期清理接缝计划 2026-04-20
## 1. 阶段目标
当前 managed SRP/URP 主线里,`RenderPipelineAsset -> active pipeline instance` 的 ownership 已经成立,但生命周期还缺最后一环:
1. managed `ScriptableRenderPipeline` 没有正式的 dispose/cleanup 接缝
2. `ScriptableRenderer` / `ScriptableRendererFeature` 也没有 cleanup 语义
3. `ScriptableRendererData` 虽然缓存了 renderer instance但没有正式释放路径
4. native 在释放 managed pipeline handle 时,只是销毁 GC handle没有先走 managed cleanup
这一阶段的目标,就是把这条生命周期链补齐,避免后续做资源化 renderer、更多 renderer feature、甚至真正的 SRP 资源对象时继续堆积隐式状态。
---
## 2. 当前问题
### 2.1 active pipeline 能建立,但不能正式销毁
现在 `MonoManagedRenderPipelineAssetRuntime` 会缓存并持有 shared managed pipeline instance。
但 release 时只是:
1. native 侧直接销毁 external managed object handle
2. managed pipeline 本身没有机会执行 cleanup
这意味着“创建”已经像 Unity 了,“释放”还没有。
### 2.2 renderer/feature 没有正式生命周期
现在 `ScriptableRenderer` 负责:
1. 持有 feature 列表
2. 构建 active pass queue
3. 执行 stage record
但它没有:
1. renderer cleanup hook
2. feature cleanup hook
3. renderer data 缓存失效/释放 hook
后面一旦 renderer 或 feature 开始持有真正的资源对象,这里就会成为脏状态积累点。
### 2.3 Universal 现在缺少“pipeline dispose -> renderer cache release”这一跳
当前 `UniversalRenderPipelineAsset` 已经正式持有:
1. renderer data 列表
2. 默认 renderer 选择
`ScriptableRendererData` 也已经正式缓存 renderer instance。
那就意味着 pipeline 销毁时,应该有一条明确链路把对应 renderer instance cache 收掉;否则 asset/runtime 生命周期和 renderer cache 生命周期仍然不闭合。
---
## 3. 本阶段方案
### 方案核心
建立一条完整的 managed 生命周期链:
1. native release managed pipeline 前,先调用 pipeline dispose
2. `ScriptableRenderPipeline` 提供正式 dispose seam
3. `UniversalRenderPipeline` 在 dispose 时回收 asset 上缓存的 renderer instance
4. `ScriptableRendererData` 提供释放 renderer cache 的内部入口
5. `ScriptableRenderer` 负责释放 feature 和自身队列状态
6. `ScriptableRendererFeature` 提供正式 dispose seam
### 预期结果
阶段完成后,生命周期关系会变成:
`ManagedAssetRuntime -> managed pipeline dispose -> pipeline asset cleanup -> renderer data release -> renderer dispose -> feature dispose`
---
## 4. 实施步骤
### Step 1补 managed core 生命周期 API
目标:
1.`ScriptableRenderPipeline` 增加内部 dispose 入口和受保护 cleanup seam
2.`ScriptableRenderer` 增加内部 dispose 入口和 feature release
3.`ScriptableRendererFeature` 增加受保护 dispose seam
4.`ScriptableRendererData` 增加 renderer cache release 入口
### Step 2把 Universal 链接到 cleanup
目标:
1.`ScriptableRenderPipelineAsset` 提供内部 pipeline-resource release seam
2.`UniversalRenderPipelineAsset` override 回收 rendererDataList 中的 renderer caches
3.`UniversalRenderPipeline` 在 dispose 时调用 asset cleanup
### Step 3native release 前调用 managed dispose
目标:
1. `MonoManagedRenderPipelineAssetRuntime` 在释放 shared pipeline handle 前先调用 managed pipeline dispose
2. 保持 runtime ownership 不回退、不重新散乱到 recorder
### Step 4补生命周期回归测试
目标:
1. 验证 runtime release 时 managed pipeline dispose 被调用
2. 验证 Universal renderer/feature cleanup 会沿 dispose 链执行
3. 保持现有 SRP/URP 创建、复用、录制能力不回归
### Step 5完整验证与收口
目标:
1. 编译 `rendering_unit_tests``scripting_tests``XCEditor`
2. 运行测试
3. 运行旧版 `XCEditor` 10 秒冒烟并验证新 `SceneReady`
4. 归档 plan提交并推送
---
## 5. 验收标准
本阶段完成后应满足:
1. managed pipeline release 前会先执行正式 dispose
2. `ScriptableRenderer` / `ScriptableRendererFeature` 不再只有创建,没有 cleanup
3. `ScriptableRendererData` 缓存的 renderer instance 有明确释放路径
4. `UniversalRenderPipeline` 生命周期能闭合到 renderer cache
5. 现有 SRP/URP 主线测试与 editor 冒烟全部通过