# STEP-092 Continuous Range 可退化分段 Retained Cache — Codex 任务 v1 ## 0. 目标 在当前 MapLibreParticleLab / Particle V11 Renderer 上实现一个 explicit Continuous Range。 正式架构定义: App 用正常 Style 定义唯一 Z-order,并指定两个现有 Style Layer ID 作为闭区间 Continuous Range; Renderer 将两个 ID 解析为连续 layerIndex,根据 Continuous Range 在 Style 中的位置自然形成 0~2 个 Retained Range Cache; 最终可以是 1、2 或 3 个 Render Range,绝不是固定“三层三明治”。 本任务只支持一个 Continuous Range,不做多个 Range 或任意 N Segment Planner。 ## 1. 环境与起始确认 工作目录:/Users/tei/dev/MapLibreParticleLab 目标分支:particle/main 历史参考 HEAD:b29e564944197072a0effaec36ca95c48fe0649b,但不得据此强制回退。 修改前必须: 1. git fetch origin 2. 确认当前分支、HEAD、origin/particle/main 3. 记录起始 HEAD 4. 检查 git status --short 5. 不覆盖、不删除、不 reset/clean、不提交无关 dirty/untracked 6. 若远端更新,以当前真实 origin/particle/main 为基线 ## 2. 唯一 Z-order 事实来源 Style Layer 顺序是唯一 Z-order 事实来源: App/RN 负责业务语义和 Style Layer 顺序; MapLibre Style 保存正式 Z-order; C++ Renderer 只消费最终连续 layerIndex。 Renderer 禁止硬编码 NavSea 业务 Layer ID(AIS/Alarm/Wind/Wave 等)。 禁止建立 BOTTOM/CONTINUOUS/TOP 第二套 metadata 分类表。 禁止增加 AnchorLayer、ContinuousStartLayer、ContinuousEndLayer、RenderAnchorLayer、空白 Marker Layer。 ## 3. Continuous Range API 语义 App 直接指定两个已有正常 Style Layer: startLayerId endLayerId 公开语义为闭区间 [startLayerId, endLayerId]。 Native 按当前 Style 解析成 startIndex/endIndex。 合法条件必须是 startIndex <= endIndex。 必须正式支持 startLayerId == endLayerId,单 Layer Continuous 完全合法。 App/RN 不传数字 index,RN 不计算 layerIndex。 内部建议转半开区间: continuousBegin = startIndex continuousEndExclusive = endIndex + 1 Bottom=[0,continuousBegin) Continuous=[continuousBegin,continuousEndExclusive) Top=[continuousEndExclusive,layerCount) Range 存在判断统一为 begin < endExclusive。 ## 4. 四种合法结构与 Cache 数量 必须支持: 1. Bottom + Continuous + Top → 2 retained caches 2. Bottom + Continuous → 1 Bottom cache 3. Continuous + Top → 1 Top cache 4. Continuous only → 0 retained caches Continuous only 当 startIndex==0 且 endIndex==layerCount-1,是完全合法状态,不是 error/fallback。 不存在的 Range: 不创建 cache; 不分配 texture; 不分配 framebuffer/render target; 不 build; 不 composite; 不参与 cache-valid gate。 当前 RetainedUnderlayCache 应合理泛化为可复用 retained range cache 能力。 具体命名服从当前源码,但不得固定创建 bottomCache+topCache 占位资源。 Bottom/Top GPU 资源必须 lazy 创建。 ## 5. Final Render 顺序 如果 Bottom 存在:build/reuse/composite Bottom 然后 render Continuous 如果 Top 存在:build/reuse/composite Top 顺序只能来自 Style,自然退化为 3/2/1 段。 ## 6. global layerIndex / pass 语义 分 Range 后仍必须保持整个 Style 的: 原始 layerIndex; 原始 ordinal; parameters.currentLayer; depthRangeSize。 不得给 Bottom/Continuous/Top 各自从 0 重新编号。 Opaque 继续 reverse traversal; Translucent 继续 forward traversal。 ## 7. Visibility Range topology 来自 Style/orderedLayers,不来自当前 visible/renderable Layers。 hidden start/end 仍必须参与 Range index 解析。 Layer ON/OFF 是内容变化,不是 Range topology 变化。 例如 start=10 hidden、11 visible、end=12 hidden,Range 仍是 10..12,不得缩成 11..11。 ## 8. Style mutation 必须支持正常 Style mutation。 Continuous 内新增/删除普通成员正常工作。 Bottom/Top 内增删使对应实际存在 cache invalid/rebuild。 同一 Range 内 reorder 使 cache 内容 invalid/rebuild。 Layer 跨 Range 移动:重新解析 start/end index → topology revision → invalidate affected caches → invalidate fast prepared state → rebuild。 startLayerId/endLayerId 自身删除:Range 立即 invalid,清除 stale cache/index/prepared state并安全 fallback。 Layer 后续重新出现且顺序合法时可恢复 explicit Range。 ## 9. Top Cache 正确性 Top retained texture 必须是透明 RGBA,并正确使用 premultiplied alpha。 目标支持 Particle 属于 Continuous、land-area 属于 Top Retained 时,Top texture 正确覆盖 Particle。 不得新增 LandMask RT、Wave/Tide mask system 或 Native land-mask 业务判断。 land-area 仍只是普通 Style Z-order。 ## 10. Legacy compatibility 当前 WeatherColor/RasterParticle 可能通过 startsRetainedDynamicRange() 参与 legacy boundary。 规则: explicit Continuous Range 已配置且有效 → STEP-092 Range 模式; 未配置 explicit Range → 保持当前 legacy retained-underlay 行为。 一旦 explicit Range 生效,startLayerId/endLayerId 是唯一 topology/boundary 来源。 禁止 explicit Range 与 startsRetainedDynamicRange() 混合生成第二套 boundary。 ## 11. RN / Native API 在现有 RendererRuntime 增加稳定入口,目标语义: setContinuousLayerRange(reactTag,startLayerId,endLayerId) 要求:ID 非空;允许相同;map-scoped;thread-safe;monotonic config revision; Range 修改触发 renderer update/invalidation。 Android/iOS bridge 不理解业务;C++ 按当前 Style 解析 index。 保留 setRetainedUnderlayEnabled() 与 getRetainedUnderlayDiagnostics() 兼容。 ## 12. Invalid / fallback 至少处理: start 不存在; end 不存在; startIndex > endIndex; Style 未 ready; 未配置 explicit range。 要求:不 crash;不猜 index;不复用 stale index/cache/prepared state; 不根据 Particle/WeatherColor 类型偷偷修正 explicit Range; 安全进入 legacy/full renderer; diagnostics 说明 fallback 原因。 Continuous-only 不是 invalid/fallback。 ## 13. Particle-only CPU Fast Path 现有 Particle-only CPU fast path 不得退化。 三段:Bottom reuse → Continuous render → Top reuse 只有 Bottom:Bottom reuse → Continuous render 只有 Top:Continuous render → Top reuse 0 cache:Continuous render 不存在的 cache 不能成为 Fast Path miss 原因。 Bottom 不存在时不得要求 bottomCache.valid=true;Top 同理。 Fast gate 只检查实际存在 retained ranges。 Continuous Range 本身必须通用,不依赖 RasterParticleLayer/Weather Layer ID。 若 Continuous 中存在当前 Fast Path 无法证明安全的未知 Layer:Fast Path fail closed,走正常 full CPU frame,Range Z-order/cache 仍正确。 不要为此重写整个 RenderGraph。 ## 14. Invalidation 继续 correctness-first、偏保守模型,至少覆盖: camera/transform/viewport/resize/pixel ratio/style reload; layer add/remove/reorder/property; source mutation/tile update/drawable update; image/sprite/glyph; placement/symbol fade/transition; context reset/debug options/unsupported 3D/legacy ordering/resource/compositor failure。 无法判断只影响 Bottom 还是 Top 时,可同时 invalidate 所有实际存在 retained caches。 本任务不做复杂 dependency graph。 topology 变化还要 invalid Range index resolution、retained prepared state、Particle fast prepared state。 ## 15. Symbol / Placement Top 可能包含 symbol/label/Navigation/AIS/Alarm。 correctness 优先。 placement/symbol fade/transition 无法证明 reuse 安全时,invalidate/full fallback,稳定后 rebuild。 不重写 Placement 系统。 ## 16. Diagnostics 至少增加/暴露: rangeConfigured, rangeValid, startLayerId,endLayerId,startIndex,endIndex, bottomPresent,bottomBuild,bottomReuse,bottomInvalidation, topPresent,topBuild,topReuse,topInvalidation, fallback,lastReason。 bottomPresent=false 且 topPresent=false 可以只是 Continuous-only,不能自动判 error。 Release 保持 pull-based,不增加 per-frame 高频日志。 ## 17. GPU 生命周期与双后端 实际 retained texture 数量必须严格等于实际存在 retained ranges: Continuous only=0; Bottom+Continuous=1; Continuous+Top=1; 三段=2。 稳定 Continuous frame 不得每帧重建 retained texture/framebuffer/compositor resources。 Mac 上完成当前工程允许的精确 Native 验证。 OpenGL 重点:Bottom/Top target 创建复用、Top RGBA/premultiplied alpha、0/1/2 cache 无空资源、Continuous-only、Fast Path。 Metal 重点:同等 Range/cache topology、透明 Top composite、0/1/2 cache 生命周期、explicit Range/fallback 与 OpenGL 一致。 不得用 Linux Core/OpenGL 构建替代 Mac 基线。 若 Android 实机/Gradle/ADB 项未执行,报告必须明确列为“未执行 Android 项”,不得伪造通过。 ## 18. Native directed tests(不加入 Jest) 至少覆盖: start==end; startend invalid; start missing; end missing; hidden start/end; Style reorder; start/end 删除; 四种 Range 结构; Bottom empty/Top empty/both empty; 不存在 Bottom 时不因 bottom cache missing 而 Fast Path miss; 不存在 Top 时不因 top cache missing 而 Fast Path miss。 还应验证: explicit Range 有效时不混用 legacy boundary; explicit Range invalid 不复用 stale cache; single-layer Continuous 正常; hidden endpoint 不改变 topology; reorder 后重新解析 index; endpoint 删除 fail safe; 0/1/2 retained cache resource 数量与 topology 一致; Opaque/Translucent traversal 保持 global layerIndex 语义。 ## 19. 明确不做 不做:任意 N Segment Planner、多个 Continuous Range、LOW/MEDIUM/HIGH 分类、 自动分析 Layer 更新频率、自动调整 Z-order、Anchor/Marker Layer、新 Style Layer 类型、 NavSea AIS 专项优化、Weather provider、Route ETA、Native land-mask 业务、 Wave/Tide 业务判断、第二套 Z-order、NavSea Layer ID 硬编码、 复杂 per-source dependency graph、PBF 重构/重生成、通用 RenderGraph、 Placement 重写、Particle 专属 Continuous 机制、Jest。 如发现必须突破边界才能继续,停止扩大范围并记录阻塞。 ## 20. 必做文档 生成: docs/50_Step记录/STEP-092_ContinuousRange可退化分段RetainedCache_v1.md docs/报告/STEP-092_ContinuousRange可退化分段RetainedCache_Codex完成报告_v1.md 追加:粒子开发记录.md 同主题已存在则递增版本,不覆盖旧文件;所有文档中文。 完成报告必须包含: 起始 HEAD、最终 HEAD、修改文件清单; C++ Renderer、RN API、Android API/bridge、iOS API/bridge; Range config 所有者、ID→layerIndex 解析位置机制; single-layer range、1/2/3 Render Range、0/1/2 retained cache; invalidation、legacy compatibility、Fast Path、diagnostics、GPU lifecycle; OpenGL、Metal、Native tests、未执行 Android 项、known limitations; commit SHA/message、push result、remote branch、origin/particle/main Final HEAD、最终 git status --short。 ## 21. Git 仅 scoped staging。 禁止 git add -A、git add .、git reset --hard、git clean。 不得触碰无关 dirty/untracked。 结束前:git diff --check;核对变更;只 stage 本任务文件;scoped commit;push origin particle/main。 push 后必须确认: git rev-parse HEAD git rev-parse origin/particle/main git status --short 要求 HEAD == origin/particle/main。 push 失败不得声明完成。 ## 22. PASS Gate 只有架构、四种 Range、0/1/2 cache、global layerIndex、Opaque/Translucent、Fast Path、 diagnostics、RN/Android/iOS API、Native directed tests、OpenGL/Metal 规定验证、 文档、scoped commit、push、远端 HEAD 一致全部满足,才可判 STEP-092 PASS。 关键项无法完成必须明确 PARTIAL/BLOCKED 和原因,禁止伪造 PASS。