diff --git a/docs/40_任务/STEP-092_ContinuousRange可退化分段RetainedCache_Codex任务_v1.md b/docs/40_任务/STEP-092_ContinuousRange可退化分段RetainedCache_Codex任务_v1.md new file mode 100644 index 000000000..f1314342e --- /dev/null +++ b/docs/40_任务/STEP-092_ContinuousRange可退化分段RetainedCache_Codex任务_v1.md @@ -0,0 +1,249 @@ +# 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。 diff --git a/docs/50_Step记录/STEP-092_ContinuousRange可退化分段RetainedCache_v1.md b/docs/50_Step记录/STEP-092_ContinuousRange可退化分段RetainedCache_v1.md new file mode 100644 index 000000000..a9a84891a --- /dev/null +++ b/docs/50_Step记录/STEP-092_ContinuousRange可退化分段RetainedCache_v1.md @@ -0,0 +1,80 @@ +# STEP-092 Continuous Range 可退化分段 Retained Cache v1 + +## 状态 + +**进行中:Codex 实现完成,等待 RDC 独立编译与运行验证** + +## 目标与基线 + +- 分支:`particle/main` +- 起始 HEAD:`b29e564944197072a0effaec36ca95c48fe0649b` +- 起始 `origin/particle/main`:`b29e564944197072a0effaec36ca95c48fe0649b` +- Implementation commit:`a9eaec6b65cc26aa70e03002bdc1326c46cad245`(`feat: add continuous retained render ranges`),已 push 至 `origin/particle/main`。 +- Style Layer 顺序是唯一 Z-order;App 只提交现有 `startLayerId` / `endLayerId` 闭区间。 +- 保留未配置 explicit range 时的 `startsRetainedDynamicRange()` legacy underlay 行为。 + +## 实现结构 + +- `RetainedUnderlayRuntimeState` 是 map-scoped range config 所有者;使用 mutex 保护 ID/config/resolution,config revision 单调递增。 +- `RenderOrchestrator::createRenderTree()` 基于完整 `orderedLayers`(包含 hidden layer)把 ID 解析为 Style index;不存在、倒序或 Style 未 ready 均 fail closed,不保留旧 index。 +- 内部统一使用 `[continuousBegin, continuousEndExclusive)`:Bottom、Continuous、Top 均由 Style index 自然退化。 +- 现有 cache 泛化为带 `begin/endExclusive` 与 Bottom/Top role 的 retained range cache;两个 cache 对象不等于两个 GPU cache,texture/render target/compositor 只在对应 range 实际存在时 lazy 创建。 +- explicit valid 时完全忽略 legacy boundary;explicit invalid 时不用 legacy 猜测,走完整 Renderer。 + +## 四种结构 + +| Style 结构 | Render Range | Retained GPU cache | +|---|---:|---:| +| Bottom + Continuous + Top | 3 | 2 | +| Bottom + Continuous | 2 | 1(Bottom) | +| Continuous + Top | 2 | 1(Top) | +| Continuous only | 1 | 0 | + +`startLayerId == endLayerId` 是合法 single-layer Continuous。hidden endpoint 仍决定 topology;range 是否存在只看 Style index 区间,不看当前 drawable/group 是否为空。 + +## 绘制与 global index + +- cache build 的 opaque 使用区间 reverse traversal,translucent 使用 forward traversal。 +- callback ordinal 来自完整 `layerGroupsByLayerIndex`,`parameters.currentLayer` 与 `depthRangeSize` 沿用全 Style 语义,不对子区间重新编号。 +- main 顺序固定为:Bottom composite(若有)→ Continuous opaque/translucent → Top composite(若有)。 +- Top 与 Bottom 均使用透明 RGBA offscreen、现有 direct sample compositor 和 premultiplied alpha blend;未新增 land-mask 或业务判断。 + +## Invalidation 与 fallback + +- camera/viewport/pixel ratio/style/layer/source/tile/image/glyph/placement/context/debug/3D 等继续进入 STEP-089 的 content/topology/static revision 模型。 +- range config revision、continuous begin/end、Bottom/Top topology 纳入 revision;配置变化会释放实际存在 cache 并使 prepared tree/fast gate 失配。 +- endpoint 删除、missing、倒序与 Style 未 ready:diagnostics 给出原因,cache key 变空并释放资源,full renderer 安全 fallback;后续 Style 恢复会重新解析。 +- correctness-first:无法只归因 Bottom 或 Top 时,两侧实际存在 cache 可同时失效。 + +## Particle-only CPU Fast Path + +- gate 只要求实际存在的 retained cache valid;Bottom/Top 不存在时为 vacuous success,不产生 cache-missing miss。 +- fast frame 仅遍历 Continuous 区间,仍使用全局 ordinal。 +- explicit Continuous 中只允许 Renderer 已知的 WeatherColor/RasterParticle dynamic candidate;出现未知 Layer 时 fail closed 到 full CPU frame,但 range cache/Z-order 仍保持。 +- Continuous-only 可进入 0-cache fast gate;是否最终命中仍需满足 Particle、revision、placement、scene 等既有条件。 + +## API 与 diagnostics + +- C++/Android/iOS/RN 增加 `setContinuousLayerRange(..., startLayerId, endLayerId)`;空 ID 拒绝,相同 ID 接受。 +- 保留 `setRetainedUnderlayEnabled()` 与 `getRetainedUnderlayDiagnostics()`。 +- pull diagnostics 增加 configured/valid、IDs/index、Bottom/Top present/build/reuse/invalidation;保留 aggregate fallback 与 `lastReason`,无 per-frame Release 日志。 + +## Directed tests + +已新增源码覆盖:single/multi layer、missing/reversed、hidden endpoint、reorder/delete、四种 topology、0/1/2 cache decision、无 cache 的 fast gate、config revision 与 explicit/legacy 排他。 + +## 待 RDC 执行 + +```bash +cmake --build build-step088-opengl --target mbgl-test-runner -j3 +build-step088-opengl/mbgl-test-runner \ + --gtest_filter='ContinuousLayerRange.*:RetainedDynamicBoundary.*:RetainedLayerGroupRange.*:RetainedUnderlayCache.*:RetainedUnderlayRevision.*:ParticleFastPath.*' +cmake --build build-ios --target ios-sdk-static -- -quiet +git diff --check +``` + +RDC 还需独立核验 OpenGL/Metal 透明 Top composite、0/1/2 texture/FBO 生命周期和 stable frame 复用。Android Gradle/APK/ADB/设备项未由 Codex 执行。 + +## 当前结论 + +源码与 directed test 已实现并完成 scoped implementation push;在 RDC 返回 OpenGL、Metal、Native test 实际结果前,本 Step 不判 PASS。 diff --git a/docs/报告/STEP-092_ContinuousRange可退化分段RetainedCache_Codex完成报告_v1.md b/docs/报告/STEP-092_ContinuousRange可退化分段RetainedCache_Codex完成报告_v1.md new file mode 100644 index 000000000..2d017761a --- /dev/null +++ b/docs/报告/STEP-092_ContinuousRange可退化分段RetainedCache_Codex完成报告_v1.md @@ -0,0 +1,157 @@ +# STEP-092 Continuous Range 可退化分段 Retained Cache Codex 完成报告 v1 + +## 1. 执行结论 + +**PARTIAL:实现完成,等待 RDC 独立编译、Native directed test、OpenGL/Metal 验证。** + +未把静态审计写成编译通过,也未把 Android 项写成已执行;因此当前不满足任务的最终 PASS Gate。 + +## 2. Git 基线 + +- 机器:`Mac-mini-tei.lan`,Darwin x86_64。 +- 仓库:`/Users/tei/dev/MapLibreParticleLab`。 +- branch:`particle/main`。 +- Starting HEAD:`b29e564944197072a0effaec36ca95c48fe0649b`。 +- 起始 `origin/particle/main`:`b29e564944197072a0effaec36ca95c48fe0649b`。 +- 起始 dirty:仅用户提供的 untracked STEP-092 任务书;已保留并纳入本任务文档范围。 +- Implementation commit:`a9eaec6b65cc26aa70e03002bdc1326c46cad245`。 +- Implementation message:`feat: add continuous retained render ranges`。 +- Implementation push:SUCCESS,`b29e56494..a9eaec6b6 HEAD -> particle/main`。 +- 文档提交无法在自身内容中自指其最终 SHA;closeout SHA、最终本地/远端 HEAD 与最终 status 由提交后回读写入最终交付响应。 + +## 3. 修改文件 + +### C++ Renderer / Map + +- `include/mbgl/map/map.hpp` +- `include/mbgl/renderer/retained_underlay.hpp` +- `src/mbgl/map/map.cpp` +- `src/mbgl/renderer/continuous_layer_range.hpp`(新增) +- `src/mbgl/renderer/render_orchestrator.cpp/.hpp` +- `src/mbgl/renderer/renderer_impl.cpp/.hpp` +- `src/mbgl/renderer/retained_underlay_cache.cpp/.hpp` +- `src/mbgl/renderer/retained_underlay_runtime_state.hpp` + +### Android API / bridge + +- `platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/MapLibreMap.java` +- `platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/NativeMap.java` +- `platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/NativeMapView.java` +- `platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/RetainedUnderlayDiagnostics.java` +- `platform/android/MapLibreAndroid/src/cpp/native_map_view.cpp/.hpp` + +### iOS API / bridge + +- `platform/ios/src/MLNMapView.h/.mm` +- `packages/maplibre-particle-rn/ios/WeatherRuntimeBridge.mm` + +### RN API + +- `packages/maplibre-particle-rn/src/NativeWeatherRuntimeBridge.ts` +- `packages/maplibre-particle-rn/src/RendererRuntime.ts` +- `packages/maplibre-particle-rn/src/types.ts` +- `packages/maplibre-particle-rn/android/src/main/java/org/navsea/maplibre/particle/weather/WeatherRuntimeBridgeModule.kt` + +### Tests / docs + +- `test/renderer/retained_underlay_cache.test.cpp` +- `docs/40_任务/STEP-092_ContinuousRange可退化分段RetainedCache_Codex任务_v1.md` +- `docs/50_Step记录/STEP-092_ContinuousRange可退化分段RetainedCache_v1.md` +- 本报告 +- `粒子开发记录.md` + +## 4. Range config 所有者与解析 + +- map-scoped owner:`Map::Impl::retainedUnderlayState`。 +- thread safety:atomic control/counters + mutex-protected ID/config/resolution。 +- revision:每次实际 ID pair 变化单调递增;重复相同配置不前进。 +- ID→index:`RenderOrchestrator::createRenderTree()` 在完整 `orderedLayers` 上解析,visibility 不参与。 +- explicit valid 时只使用 `[startIndex, endIndex + 1)`;不读取 legacy boundary。 +- explicit invalid 时 index 置 `-1`、资源/prepared gate 失效并 full fallback;不按 Particle/Weather 类型纠正。 + +## 5. 1/2/3 Render Range 与 0/1/2 cache + +- single-layer Continuous 正式支持。 +- Bottom+Continuous+Top / Bottom+Continuous / Continuous+Top / Continuous-only 全部由同一 plan 表达。 +- 两个 cache holder 分别代表 Bottom/Top capability;只有 range present 才建立 key 并 lazy 创建 RGBA texture/render target/compositor。 +- empty drawable content 不会把 Style 中实际存在的 Bottom/Top topology 偷偷消掉;可构建透明 retained texture。 + +## 6. Renderer、Z-order 与 Top 正确性 + +- Bottom build/reuse/composite → Continuous render → Top build/reuse/composite。 +- Opaque reverse、Translucent forward 保持;original ordinal、`currentLayer`、`depthRangeSize` 按全 Style 计算。 +- Top 使用透明 clear、RGBA offscreen、direct sample shader 与 alpha-blended premultiplied composite,可覆盖 Continuous Particle。 +- 未增加 LandMask RT、业务 Layer ID、Anchor/Marker 或第二套 metadata Z-order。 + +## 7. Invalidation / legacy / Fast Path + +- STEP-089 content/topology/static revision 继续作为 conservative invalidation 基础;range config/end index/Top topology 已纳入。 +- 未配置 explicit range:保持 legacy retained-underlay。 +- explicit valid:legacy `startsRetainedDynamicRange()` 只可用于 fast-safety 类型证明,不参与 topology/boundary。 +- fast gate 对不存在 cache 不要求 valid;实际存在 Bottom/Top 都必须 valid/buildRevision 匹配。 +- unknown Continuous layer 不能证明 particle-only 安全时 full CPU fallback;正常 full range render/cache 不受影响。 + +## 8. Diagnostics + +已增加并跨 C++/Android/iOS/RN 暴露: + +- `rangeConfigured`, `rangeValid` +- `startLayerId`, `endLayerId`, `startIndex`, `endIndex` +- `bottomPresent`, `bottomBuild`, `bottomReuse`, `bottomInvalidation` +- `topPresent`, `topBuild`, `topReuse`, `topInvalidation` +- 保留 aggregate `fallback`, `lastReason` 与原有 enabled/build/reuse/invalidation。 + +Continuous-only 的 Bottom/Top present 均为 false,仍可为 rangeValid=true。 + +## 9. Native tests + +测试源码新增覆盖: + +- `start == end`、`start < end`、`start > end` +- start/end missing +- hidden endpoint ID 仍参与完整 ordered list +- reorder、endpoint 删除后重新解析 +- 四种 topology 与 0/1/2 cache decision +- Bottom/Top 不存在不造成 fast cache miss +- config empty-ID/revision/same-ID +- explicit valid/invalid 均不混用 legacy boundary + +实际 test runner 尚未由 Codex 执行,等待 RDC。 + +## 10. OpenGL / Metal / Android + +- OpenGL:源码实现完成;未执行 build/runtime,等待 RDC。 +- Metal:共用 range/cache topology 与既有 Metal compositor;源码实现完成;未执行 `ios-sdk-static`,等待 RDC。 +- Native directed tests:未执行,等待 RDC。 +- Android 项:**未执行 Android Gradle、AAR/APK、ADB、安装、设备视觉或生命周期验证**。 +- Jest:按任务要求未新增、未执行。 + +## 11. 静态检查与验证命令 + +Codex 已执行 `git diff --check`;最终提交前再次执行并回读。 + +RDC 精确命令: + +```bash +cmake --build build-step088-opengl --target mbgl-test-runner -j3 +build-step088-opengl/mbgl-test-runner \ + --gtest_filter='ContinuousLayerRange.*:RetainedDynamicBoundary.*:RetainedLayerGroupRange.*:RetainedUnderlayCache.*:RetainedUnderlayRevision.*:ParticleFastPath.*' +cmake --build build-ios --target ios-sdk-static -- -quiet +git diff --check +``` + +## 12. Known limitations / 未完成 + +- 尚无 RDC 编译结果,桥接/codegen/ObjC++/C++ 编译结论不得写 PASS。 +- 尚无 OpenGL/Metal frame capture 或资源计数运行证据。 +- 尚无 Android lifecycle/style mutation/视觉验收。 +- 本任务只支持一个 explicit Continuous Range;无 clear API、多个 Range 或 N Segment Planner。 + +## 13. Git 收尾 + +- scoped staging:只纳入本任务上列源码、测试与文档。 +- 禁止项:未使用 `git add -A`、`git add .`、reset、clean 或 force push。 +- Implementation commit SHA/message:`a9eaec6b65cc26aa70e03002bdc1326c46cad245` / `feat: add continuous retained render ranges`。 +- Implementation push result:SUCCESS。 +- Remote branch:`origin/particle/main`。 +- Final HEAD / `origin/particle/main` / `git status --short`:待提交与 push 后外部回读;在两者一致前不声明 Git 完成。 diff --git a/粒子开发记录.md b/粒子开发记录.md index 909051186..12de200bf 100644 --- a/粒子开发记录.md +++ b/粒子开发记录.md @@ -890,3 +890,12 @@ Android V3-08 单次综合验收已完成并关闭。Native `13.4.1-particle.2` - 下一次既有 State/Trail pass 复用 shader initial-seed,在新 `respawnBounds` 内全量播种并清除旧小视野 Trail;不做 simulation reset、Field resubmit、Timeline reset 或 GPU resource rebuild。fallback 请求当场消费并单次记录,不会在后续 Pan 延迟触发。 - Zoom In、Pan、Rotate/Pitch、epsilon 抖动均不触发;原生 directed test 8/8、Renderer 与 gtest 精确 object 编译、`git diff --check` PASS。未改 shader/UBO/API、STEP-089/090 fast path、WeatherColor 或 Runtime Field Window;Android APK/ADB/Jest 未执行,实机视觉与 fast-hit 恢复交由 RDC。 - implementation commit:`4286c16a53d4f49001f3b41ed4638d3c6edc95b3`(`fix: reseed particles after zoom out`)。 + +### 2026-09-24 STEP-092 Continuous Range 可退化分段 Retained Cache + +- 新增 map-scoped explicit `startLayerId` / `endLayerId` 闭区间;Native 基于完整 Style `orderedLayers` 解析 index,hidden endpoint 不改变 topology,single-layer Continuous 合法。 +- Renderer 把 legacy 单 underlay 能力泛化为 Bottom/Top retained range cache;按 Style 位置自然形成 1/2/3 个 Render Range 与 0/1/2 个 lazy GPU cache。Continuous-only 不分配 retained texture/FBO/compositor。 +- Bottom composite → Continuous global-ordinal opaque/translucent → Top premultiplied-alpha composite;未硬编码 NavSea Layer ID,未增加 Anchor/Marker、land-mask 或第二套 Z-order。 +- explicit valid 与 legacy boundary 排他;missing/reversed/style-not-ready 会清除 stale resolution/cache/fast prepared gate并 full fallback,后续 Style 恢复可重新解析。 +- RN、Android、iOS 增加 `setContinuousLayerRange`,pull diagnostics 增加 range/index 与 Bottom/Top build/reuse/invalidation;保留旧 retained API。 +- Native directed test 源码覆盖 single/multi、missing/reversed、hidden/reorder/delete、四种 topology、0/1/2 cache、no-cache fast gate 与 config revision。Implementation commit `a9eaec6b65cc26aa70e03002bdc1326c46cad245` 已 push;Codex 未执行编译/测试/Android 项,等待 RDC 独立验证,当前状态 PARTIAL,不判 PASS。