docs: add STEP-094 generic render segment task
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled

This commit is contained in:
tei
2026-09-25 11:47:18 +09:00
parent 7eaff6e123
commit 8fbb892a12

View File

@@ -0,0 +1,599 @@
# STEP-094 通用 Render Segment 分段渲染与 Style 分类诊断 — Codex 任务 v1
## 0. 任务目标
从已冻结的 Particle V12 `Bottom Retained / Continuous / Top Retained` 单 Continuous Range 模型,演进到最终通用模型:
```text
Style Z-order
↓
连续 layerIndex
↓
若干连续 Render Segment
↓
每个 Segment 的执行策略仅为:
CONTINUOUS 或 RETAINED
```
Style 顺序继续是唯一 Z-order 事实来源。Renderer 不理解 LOW / MEDIUM / HIGH,也不理解 AIS、Route、地图、Weather 等业务语义。
本 STEP 同时必须建立新的 pull-based Segment Diagnostics,能够取回“当前 Style → Segment → Layer”的真实分类快照,供后续人工判断 Segment 划分是否合理。
## 1. 当前冻结基线
工作目录:`/Users/tei/dev/MapLibreParticleLab`
目标分支:`particle/main`
当前已知 V12 冻结基线:
- HEAD:`7eaff6e12360e26591dceb5e011129eeab7ba4c7`
- Commit:`release: finalize unified particle.12`
- Tag:`maplibre-particle/rn/13.4.1-particle.12`
- `HEAD == origin/particle/main`
- 工作区 clean
开始前必须重新执行 fetch/status/HEAD 检查,以实际仓库为准。禁止 reset/clean,禁止回退、移动、覆盖 V12 Tag。STEP-094 是 V12 之后的新开发,不修改 V12 已发布事实。
必须先读取:
- 根目录 `AGENTS.md`
- `ARCHITECTURE.md`
- STEP-092 / STEP-093 任务、Step 记录与完成报告
- V12 当前 Continuous Range、Retained Cache、Fast Path、Android/iOS/RN bridge 实现
- 当前 `RendererRuntime.ts`、`types.ts`、`NativeWeatherRuntimeBridge.ts`
## 2. 最终架构原则
1. Style Layer 顺序是唯一 Z-order 真相。
2. 整个 Style 必须按连续 layerIndex 被完整划分为 1..N 个 Render Segment。
3. 每个 Segment 只声明 `RETAINED` 或 `CONTINUOUS`。
4. 允许多个 RETAINED、多个 CONTINUOUS,且可按 Style 顺序任意交错。
5. 相邻同策略 Segment 不得自动合并。
6. 每个 RETAINED Segment 独立拥有 cache / revision / invalidation / rebuild / GPU resource。
7. CONTINUOUS Segment 不创建 retained texture/FBO/compositor。
8. Renderer 不自动分析 Layer 更新频率,不自动调整 Z-order。
9. App 通过 Style 顺序 + Segment boundary 表达分类。
10. 不建立 LOW/MEDIUM/HIGH 第二套业务分类。
11. 不硬编码 NavSea Layer ID。
12. 不增加空白 Anchor / Marker Layer。
V12 三明治只是本模型的一个特例:`RETAINED → CONTINUOUS → RETAINED`。
## 3. 命名约束
MapLibre 现有代码已经大量使用 shader/bucket 的 `Segment` / `SegmentVector`。本任务禁止新增裸名称 `Segment` 造成语义冲突。
新模型命名必须明确属于 Renderer execution topology,例如:
- `RenderSegmentStrategy`
- `RenderSegmentDefinition`
- `RenderSegmentPlan`
- `ResolvedRenderSegment`
- `RenderSegmentDiagnostics`
- `RetainedSegmentCache`
具体文件名可按当前代码结构调整,但必须避免与 geometry/shader Segment 混淆。
## 4. Segment Plan 公共语义
推荐公共模型:
```text
RenderSegmentDefinition
strategy: RETAINED | CONTINUOUS
startLayerId?: string
```
规则:
- definitions 至少 1 个。
- 第 0 个 Segment 从 Style index 0 开始,`startLayerId` 必须省略/为空。
- 第 1..N-1 个 Segment 必须提供非空 `startLayerId`。
- startLayerId 必须引用当前 Style 中已经存在的普通 Layer。
- Native 根据当前 Style 解析真实 layerIndex。
- App/RN 不传数字 index。
例如:
```text
[
{ strategy: RETAINED },
{ strategy: CONTINUOUS, startLayerId: "rn-weather-color" },
{ strategy: RETAINED, startLayerId: "land-area" },
{ strategy: RETAINED, startLayerId: "ais-layer" }
]
```
解析后:
- Segment 0 = `[0, index(rn-weather-color))`
- Segment 1 = `[index(rn-weather-color), index(land-area))`
- Segment 2 = `[index(land-area), index(ais-layer))`
- Segment 3 = `[index(ais-layer), layerCount)`
Segment 2/3 虽然都是 RETAINED,也必须保持两个独立 cache,不得合并。
这种定义保证整个 Style 完整覆盖;插入普通 Layer 后依据 Style 位置自然进入对应 Segment;最顶端新增 Layer自动属于最后一个 Segment。
## 5. Plan 合法性与 resolve
有效计划必须满足:
- Style ready;
- 所有 boundary Layer 存在;
- boundary index 严格递增;
- 无重复 boundary;
- 每个 resolved Segment 非空;
- 最终覆盖 `[0, layerCount)`;
- 不重叠、不留 gap。
hidden / visibility=none 的 boundary Layer 仍参与 topology。Visibility 变化不得改变 Segment membership。
以下情况 plan invalid:
- boundary missing;
- boundary 顺序反转或重复;
- Style 未 ready;
- 空 definitions;
- 非法 strategy;
- JSON/schema 非法。
invalid 时不得 crash、不得猜 boundary、不得复用 stale cache。必须释放/隔离失效 topology 的 retained resource,安全走 full renderer,并在 diagnostics 给出明确 reason。Style 后续恢复合法时允许自动重新 resolve。
必须有 monotonic `configRevision`。Style add/remove/reorder 后重新 resolve;实际 begin/end 变化时推进 `topologyRevision`。Visibility 变化不得推进 topologyRevision。
## 6. Renderer 执行模型
Resolved Segment 按 Style 顺序执行:
```text
for segment in resolvedSegments:
RETAINED -> build/reuse cache -> composite
CONTINUOUS -> direct render
```
逻辑上按 Segment 顺序组合,但实际实现必须继续满足 MapLibre 原有 RenderPass 语义。
必须保持:
- 全 Style 原始 global layerIndex;
- 原始 ordinal;
- `parameters.currentLayer`;
- `depthRangeSize`;
- Opaque reverse traversal;
- Translucent forward traversal。
禁止每个 Segment 从 0 重新编号,禁止为了 Segment 模型重新排序 Style Layer。
## 7. RETAINED Segment 独立 Cache
每个 RETAINED Segment 必须拥有独立:
- cache state;
- content revision;
- build/reuse/invalidation count;
- last invalidation reason;
- texture/compositor create count;
- resource release count。
GPU resource 必须 lazy 创建。CONTINUOUS Segment 绝不能因为占位而创建 retained texture。
Plan/topology 改变后,不能证明安全复用的旧 cache 必须释放并重建;stale segment cache 绝不能错误 composite。本 STEP 不要求复杂 cache migration,correctness-first。
## 8. Invalidation 粒度
目标是 Segment 级 invalidation。
能够明确定位影响 Segment 时,只 invalidate 受影响 RETAINED Segment;其他 RETAINED Segment 保持 valid/reuse。
LayerMutation 若明确属于某 Segment,应只使该 Segment dirty。Source/Tile mutation 若能从现有 RenderLayer/Source 关系安全确定影响的多个 Segment,应 invalidate 对应集合。
若无法可靠确定影响范围,允许保守 invalidate 全部 RETAINED Segment。本 STEP 不建立复杂通用 dependency graph。
camera/transform/viewport/resize/pixel ratio、style reload、image/sprite/glyph、placement/symbol fade/transition、context reset、debug options、unsupported 3D、resource/compositor failure 等无法证明局部安全时可 invalidate 全部 retained。
完成报告必须区分“已实现的 segment-local invalidation”和“仍采用全 retained invalidation 的原因”。
## 9. Cache ON/OFF
现有 Cache ON/OFF 总开关继续有效。
Cache OFF:
- Segment Plan 仍然 resolve;
- Diagnostics 仍能看到 Style/Segment/Layer 分类;
- RETAINED Segment 不错误复用 retained GPU cache;
- Renderer 安全走非 retained 路径。
Cache ON:
- 每个 RETAINED Segment 独立 build/reuse;
- CONTINUOUS Segment 直接绘制。
关闭所有 CONTINUOUS Layer 的 visibility 不得删除 Segment topology。
## 10. V12 兼容入口
不得破坏现有:
- `setRetainedUnderlayEnabled()`
- `setContinuousLayerRange(startLayerId,endLayerId)`
- `getRetainedUnderlayDiagnostics()`
新内部实现应尽量只有一套 Segment topology。
`setContinuousLayerRange(start,end)` 应作为 compatibility adapter,转换成等价 RenderSegmentPlan:
- start 前存在 → RETAINED
- start..end → CONTINUOUS
- end 后存在 → RETAINED
自然退化成 V12 原有 1/2/3 Range。
旧 API 与新 Segment Plan 不得同时形成两套 Renderer topology。最后一次显式 topology 配置必须只有一个 active plan,并从 diagnostics 可见 `configSource`。
旧 `getRetainedUnderlayDiagnostics()` 保留兼容摘要;新的多 Segment 事实以新 Diagnostics API 为准。
## 11. 新 RN / Native API
新增稳定公共语义:
```text
RendererRuntime.setRenderSegmentPlan(reactTag, plan)
RendererRuntime.getRenderSegmentDiagnostics(reactTag)
```
建议 TS:
```text
RenderSegmentStrategy = "RETAINED" | "CONTINUOUS"
RenderSegmentDefinition = {
strategy: RenderSegmentStrategy
startLayerId?: string
}
RenderSegmentPlan = {
schemaVersion: 1
segments: readonly RenderSegmentDefinition[]
}
```
RN public API 必须是 typed object。TurboModule ABI 可使用 JSON string 作为 plan/snapshot 内部传输,避免可扩展嵌套数组变成脆弱 parallel arrays。若采用 JSON,必须有 schemaVersion 与严格校验;public TS 不暴露 raw JSON。
必须沿当前真实链路扩展:
`RendererRuntime → NativeWeatherRuntimeBridge/TurboModule → Android/iOS package bridge → MapLibre platform API → Core Renderer state`。
不得新建第二套独立 RN bridge。
## 12. Segment Diagnostics — 强制要求
这是 STEP-094 的强制验收项,不是附加日志。
新增 pull-based `getRenderSegmentDiagnostics()`,必须能够取回当前真实 Style 的:
1. Style 全 Layer 顺序;
2. 当前 resolved Segment 顺序;
3. 每个 Segment 的 strategy;
4. 每个 Segment 的 begin/end;
5. 每个 Segment 内实际包含的 Layer;
6. 每个 RETAINED Segment 的 cache 状态与统计。
Diagnostics 只能按需读取。禁止 per-frame 打印完整 Style/Segment/Layer,禁止每帧构造大 JSON/大字符串。
## 13. Diagnostics Snapshot 最低字段
顶层至少:
```text
schemaVersion
enabled
configured
valid
configSource
configRevision
topologyRevision
styleLayerCount
segmentCount
retainedSegmentCount
continuousSegmentCount
coverageComplete
fallback
lastReason
fastPathEligible
fastPathActive
fastPathFallbackReason
fastPathHit
fastPathMiss
fullCpuFrame
```
`configSource` 至少区分:
- `explicit-render-segment-plan`
- `continuous-range-compat`
- `unconfigured/legacy`(若仍存在)
必须提供完整 ordered `styleLayers[]`,用于 plan invalid 时仍可人工分析 Style。
## 14. Style Layer Diagnostics
每个 `styleLayers[]` / Segment 内 `layers[]` 至少返回:
```text
layerIndex
layerId
layerType
visible
```
如当前 Style/Core 可低成本稳定取得,还应返回:
- `sourceId`
- `sourceLayer`
不适用时可为空/null,禁止伪造。Layer Diagnostics 只描述通用 Style 信息,禁止加入 AIS/Route/Wind 等业务判断。
## 15. 每个 Segment Diagnostics
每个 Segment 至少:
```text
segmentIndex
strategy
configuredStartLayerId
beginIndex
endExclusive
resolvedStartLayerId
resolvedEndLayerId
layerCount
layers[]
```
如果 `strategy=RETAINED`,还必须有:
```text
cacheState
contentRevision
build
reuse
invalidation
lastInvalidationReason
textureCreate
compositeCreate
resourceRelease
```
如果 `strategy=CONTINUOUS`,不得伪装成 disabled retained cache。retained-only 字段应为 null/not-applicable,或由 TS discriminated union 排除。
## 16. Diagnostics 一致性
当 plan valid:
- `styleLayers.length == styleLayerCount`
- Segment 按 segmentIndex/beginIndex 严格递增
- 所有 `segment.layers[]` 拼接后必须与 `styleLayers[]` 完全一致
- 每个 Style Layer 必须且只能属于一个 Segment
- `segment.layerCount == segment.layers.length`
- `coverageComplete=true`
当 plan invalid:
- 仍尽可能返回当前 ordered styleLayers
- segments 可为空或只返回已安全解析部分,但必须 `valid=false`
- 禁止把猜测结果标成 valid
## 17. DEBUG 使用目标
必须能取回类似:
```text
Segment 0 RETAINED [0..18)
background
water
coastline
Segment 1 CONTINUOUS [18..20)
rn-weather-color
rn-weather-particles
Segment 2 RETAINED [20..27)
land-area
navigation-marks
route
Segment 3 RETAINED [27..30)
ais
radar
alarm
```
此信息只用于人工分析 Style 分类是否合理。Renderer 不根据 Debug 结果自动重新分类。
设计文档必须给出至少一个完整 JSON/TS snapshot 示例。
## 18. Particle Fast Path
V12 已有 Particle Fast Path 不得无声退化。
至少保证:
- 对“恰好一个 CONTINUOUS Segment + 其余为 RETAINED”的 V12 等价拓扑,且 Continuous 内容满足现有支持条件时,现有 Fast Path 能继续工作。
- 不存在某个 retained cache 时不得成为 miss 原因。
对于多个 CONTINUOUS Segment,若当前 Fast Path 无法安全支持,允许 fail closed:
- `fastPathActive=false`
- 明确 fallback reason
- 正常 full CPU frame
- Segment topology / retained cache / Z-order 仍正确
禁止为了 STEP-094 一次性重写整个 RenderGraph 或实现所有 N-Continuous Fast Path 优化。
## 19. Style Mutation
必须验证:
- Segment 内新增/删除/reorder Layer
- boundary 前后插入 Layer
- boundary Layer hidden
- boundary Layer 删除/重新出现
- boundary reorder 导致 plan invalid
- plan 更新后恢复
普通 Layer 插入 Segment 内后应自然成为该 Segment 成员,不要求 App 给每个 Layer 单独注册频率 metadata。
相邻 RETAINED Segment 即使策略相同,也必须依靠显式 boundary 保持独立。
## 20. GPU 生命周期
实际 retained GPU resource 数量应与当前 resolved plan 中 RETAINED Segment 数量一致,允许 lazy 未创建状态,但不得为 CONTINUOUS Segment 分配 retained target。
Plan topology 变化后 stale resource 必须正确 release。稳定帧不得重复创建 retained texture/FBO/compositor。OpenGL 与 Metal 行为必须一致。
## 21. Native Directed Tests(不加入 Jest)
本任务明确不加入 Jest。
至少覆盖:
1. 单 RETAINED Segment 覆盖全 Style
2. 单 CONTINUOUS Segment 覆盖全 Style
3. V12 等价 R-C-R
4. C-R-R
5. R-R-C
6. R-C-R-C-R 多段交错
7. 相邻 R-R 不自动 merge
8. hidden boundary 不改变 topology
9. boundary missing / duplicate / 顺序非法
10. Style 内插入 Layer 后 membership 正确
11. boundary 删除后 fail safe、恢复后重新 resolve
12. retained resource 数量匹配 RETAINED Segment 数
13. CONTINUOUS 无 retained resource
14. Cache OFF 时 topology diagnostics 仍完整
15. V12 `setContinuousLayerRange` 兼容映射
16. global layerIndex / Opaque / Translucent 语义不变
17. 多 CONTINUOUS Fast Path 安全 fallback
Diagnostics tests 额外验证:
- styleLayers 顺序精确
- segments 顺序精确
- 每个 Segment 的 layers 成员精确
- 拼接 segment.layers == styleLayers
- layerIndex 不重编号
- layerId/layerType/visible 正确
- sourceId/sourceLayer(若实现)正确
- invalid plan 仍能取得 ordered styleLayers
- snapshot pull 不产生 per-frame 日志
## 22. 平台与 RN 验证
Core/C++:
- 执行规定的 Mac 原生精确编译与 Native tests
- OpenGL / Metal
- 编译输出遵循全局 build-output-throttle
Android:
- 完成源码、JNI/Kotlin/Java/RN bridge 修改
- Android Gradle 编译由用户手工执行,不由 Codex 运行
- 报告列明“未执行 Android 编译/实体机”直到用户验证
iOS:
- 只面向 iPhone/iPad arm64 真机架构
- 不要求 Simulator slice
- 可执行当前工程已有的 Mac/iOS arm64 精确编译验证
- 不伪造实体机运行 PASS
## 23. 最小 Debug/Validation 入口
在当前已有 Particle validation/Test Host 体系中补一个最小 pull 入口:
- Fetch Segment Diagnostics
- 展示或输出一次完整 snapshot
- 能看到 Segment 列表和每个 Segment 的 Layer 列表
不得增加持续轮询,不得把大 snapshot 每帧写日志。若现有 UI 已有 diagnostics panel,优先复用。
## 24. 性能要求
Segment topology/style diagnostic 数据只在 config/style topology 或相关 debug metadata 变化时更新,或在显式 diagnostics pull 时做必要轻量组装。
禁止因为 Particle 30/60fps:
- 每帧扫描/复制完整 Style Layer 字符串
- 每帧 JSON stringify
- 每帧创建 Segment diagnostics 大对象
- 每帧 Logger 输出 topology
高频 render path 只消费预解析的轻量 segment ranges/cache state。
## 25. 明确不做
本 STEP 不做:
- LOW/MEDIUM/HIGH 枚举或自动频率分类
- Renderer 识别 NavSea 业务 Layer
- 自动调整 Style Z-order
- Anchor/Marker Layer
- 复杂通用业务 dependency graph
- Weather provider / Route ETA / AIS 专项 renderer
- PBF 重生成
- 通用 RenderGraph 重写
- 自动合并同策略 Segment
- 多 Continuous 的高级 Fast Path 优化
- per-frame Segment debug log
- Jest
如发现必须突破这些边界才能保证 correctness,停止扩大范围并在报告明确 BLOCKED/PARTIAL。
## 26. 必做文档
新增:
- `docs/30_设计/STEP-094_通用RenderSegment模型与Style分类Diagnostics设计_v1.md`
- `docs/50_Step记录/STEP-094_通用RenderSegment分段渲染与Style分类诊断_v1.md`
- `docs/报告/STEP-094_通用RenderSegment分段渲染与Style分类诊断_Codex完成报告_v1.md`
追加:
- `粒子开发记录.md`
同主题已有文件则递增版本,不覆盖历史。所有文档中文。
设计文档必须包含最终 Segment 数据模型、config/resolve 生命周期、V12 compatibility mapping、cache ownership、invalidation、Fast Path 边界、Android/iOS/RN API、Diagnostics schema、完整 Style→Segment→Layer snapshot 示例。
## 27. 完成报告必须记录
- 起始 HEAD / 最终 HEAD
- 修改文件清单
- RenderSegment config API
- boundary Layer ID → layerIndex 解析
- N Segment 遍历
- retained cache ownership/resource lifecycle
- segment-local 与 global invalidation
- V12 compatibility / Fast Path
- Diagnostics schema
- styleLayers / segment.layers 验证
- RN/Android/iOS bridge
- OpenGL / Metal
- Native test 数量与结果
- 未执行 Android/实体机项目
- known limitations
- commit SHA/message
- push result / remote branch
- origin/particle/main Final HEAD
- 最终 `git status --short`
## 28. Git 规则
仅 scoped staging。禁止 `git add -A`、`git add .`、`git reset --hard`、`git clean`,不得删除/覆盖无关 dirty/untracked。
结束前必须:
1. `git diff --check`
2. 核对 diff
3. 只 stage 本任务文件
4. scoped commit
5. push `origin particle/main`
6. fetch/确认远端
最终要求:
```text
HEAD == origin/particle/main
git status --short 无本任务残留
```
push 失败不得声称完成。
## 29. PASS Gate
只有以下全部成立才可判 STEP-094 PASS:
- Style Z-order 仍唯一
- 1..N 连续 Segment 完整覆盖
- RETAINED/CONTINUOUS 可任意交错
- 相邻同策略 Segment 不自动合并
- 每个 RETAINED Segment 独立 cache/revision/invalidation/resource
- V12 Continuous Range 兼容
- V12 等价 Fast Path 不无声退化
- 新 Diagnostics 能真实返回 Style→Segment→Layer
- diagnostics pull-based、无 per-frame 大开销
- Android/iOS/RN API 完整
- Native directed tests 通过
- 规定编译验证完成
- 文档完成
- scoped commit/push 完成
- HEAD 与远端一致
关键项未完成必须明确 PARTIAL/BLOCKED,禁止伪造 PASS。