Files
MapLibreParticleLab/docs/50_Step记录/STEP-093_ContinuousRange运行态综合验收_v1.md
tei 66690b460e
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
docs: hand off STEP-093 runtime validation
2026-09-24 14:42:25 +09:00

239 lines
15 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# STEP-093 Continuous Range 运行态综合验收 v1
## 1. 当前状态
**IMPLEMENTED / WAITING_RUNTIME_VALIDATION**
Codex 已完成 Android 运行态验收入口、跨平台 diagnostics 补强、Fast Path fail-closed 原因观测、定向 Native 测试源码和 RDC 操作手册。依照仓库职责分工与本轮用户指令,Codex 未执行 Android/iOS 长时间编译、安装、ADB、模拟器/真机操作或视觉验收。因此 Android 为 `WAITING_ANDROID_RUNTIME_VALIDATION`,iOS/Metal 为 `WAITING_IOS_RUNTIME_VALIDATION`;本版不能标记 `CLOSED / PASS`。
## 2. 起始 Git 基线
- Repository:`MapLibreParticleLab`
- 机器:`Mac-mini-tei.lan`
- 路径:`/Users/tei/dev/MapLibreParticleLab`
- Branch:`particle/main`
- Starting HEAD:`8a5d88008c142e2a80e0ff602d228e0e67de2d83`
- Starting `origin/particle/main`:`8a5d88008c142e2a80e0ff602d228e0e67de2d83`
- STEP-092 基线:`CLOSED / PASS(Mac Native 验证闭环)`
- STEP-093 implementation commit:`b3ec8edc87ece404b5f7b3706f5acf2a70de6862`
- 起始工作树差异:仅有本任务书 `docs/40_任务/STEP-093_ContinuousRange运行态综合验收_Codex任务_v1.md` 为 untracked;已保留并纳入本 Step 文档提交。
## 3. 实际调查到的测试入口
Android 已有入口为 `MapLibreAndroidTestApp` 的 `ParticleCoreLayerValidationActivity`。本 Step 复用该 Activity、既有 Host-submitted particle fixture、`weather-color` 和普通 Style layer,不建立新测试框架,也不引入特殊 layer type。
新增底部 `STEP 093` 菜单与常驻 diagnostics 区。入口支持:
- A:Bottom + Continuous + Top;
- B:Bottom + Continuous;
- C:Continuous + Top;
- D:Continuous only;
- E:Single-layer Continuous;
- Continuous/Bottom/Top add 与 reorder;
- 普通 layer 跨 Bottom/Continuous/Top 移动;
- start/end endpoint visibility、删除与恢复;
- missing start、missing end、reversed、style loading 期间配置、empty ID、恢复 valid;
- Camera preset 循环覆盖 pan/zoom/rotate/pitch;
- Continuous 内未知普通 layer 触发 Fast Path fail-closed;
- 1 秒一次的屏幕 pull diagnostics;仅用户点 `READ DIAGNOSTICS` 或场景切换时写一条日志,不制造逐帧日志风暴。
Android Activity 声明增加 `orientation|keyboardHidden|screenSize` config changes,使 RDC 可在不重建 Map/Style 的前提下用旋转或尺寸变化观察 viewport invalidation。
iOS 当前只有正式 `MLNMapView` diagnostics API 与 RN bridge 字段补齐,没有新增专用 STEP-093 iOS validation 页面。因此 iOS runtime 必须后续由 RDC 准备实际入口并执行,不能由 Android 结果推导。
## 4. 本轮新增/修改内容
### 4.1 Renderer diagnostics
在既有 map-scoped diagnostics 上追加,而非另造一套状态源:
- Range:`continuousBegin`、`continuousEndExclusive`、`rangeFallback`;
- Bottom/Top:`cacheState`、build/reuse/invalidation、last invalidation reason;
- 资源生命周期:texture create、composite create、resource release;
- Fast Path:eligible、active、fallback reason、hit、miss、full CPU frame;
- 未知 Continuous layer 的明确原因:`unsupported-continuous-layer`。
这些 counter 是 Map 生命周期内累计事件数,不是 GPU memory byte 数。它们用于证明 stable frame 不重复创建资源及 invalidation 后能重建/reuse;不能替代 profiler 或 GPU capture。
### 4.2 跨端暴露
- Android JNI/Java:diagnostics 字符串数组由 20 项扩为 39 项,Java 构造索引与 Native 顺序逐项一致;
- iOS ObjC++:`MLNRetainedUnderlayDiagnostics` 暴露同组字段;
- RN Android/iOS/TypeScript/Test Host:透传并显示同组字段;
- 原有 aggregate build/reuse/fallback/invalidation 字段保持,不删除兼容语义。
### 4.3 Android 可视场景
测试 Style 中仅使用普通 background/fill/line、已有 WeatherColor 与 RasterParticle:
- Bottom:深色 background + 青色 fill;
- Continuous:WeatherColor + Particle;
- Top:半透明黄色 fill、opaque 红色 fill、白色粗 line;
- fail-closed:在 Continuous 内加入普通 fill;
- cross-range:同一个普通 fill ID 分别位于 endpoint 前、endpoint 间、endpoint 后。
最终 Z-order 仍完全由 Style layer 数组顺序决定。App 只调用 `setContinuousLayerRange(startLayerId, endLayerId)`;没有 anchor/marker、业务 layer metadata 或 Renderer 业务 ID 硬编码。
### 4.4 定向测试源码
新增 `RetainedUnderlayCache.RuntimeValidationDiagnosticsExposeRangeResourcesAndFastPath`,覆盖 Continuous index、cache state、资源 counter、Fast Path counter;既有 Fast Path gate 测试增加 `UnsupportedContinuousLayer` 原因断言。
本轮未运行 test runner。STEP-092 既有 29/29 PASS 是历史基线,不能当作新增测试已通过;RDC 运行后预期相关 filter 共 30 项,但必须以实际 runner 输出为准。
## 5. 静态一致性审查
Codex 已完成:
- Native diagnostics 定义、runtime state、Android JNI/Java、iOS、RN 字段名与顺序逐项比对;
- 四种 topology 与 single-layer 的 Style layer 顺序/endpoint 位置审查;
- mutation、cross-range、endpoint、invalid、camera、fail-closed 菜单接线审查;
- absent Bottom/Top 仍沿用 STEP-092 `Disabled` / lazy resource 路径,没有新增固定 GPU 分配;
- Fast Path eligibility 与 decision counter 接入既有 gate,失败仍进入 full CPU frame;
- `xmllint --noout`:Android Manifest 与 layout PASS;
- `git diff --check`:PASS。
未执行:C++/Java/Kotlin/ObjC++/TypeScript 编译、Native tests、Gradle、APK、ADB、Android/iOS runtime。静态审查不等于运行态 PASS。
## 6. RDC Android 构建、安装与启动
在仓库根目录执行:
```bash
./tools/particle_android_validation/build_validation_apk.sh
adb devices
adb -s <serial> install -r artifacts/maplibre-particle/android-validation/MapLibreAndroidTestApp-validation-opengl-debug-x86_64.apk
adb -s <serial> shell am start -n org.maplibre.android.testapp/.activity.particle.ParticleCoreLayerValidationActivity
```
可选定向日志:
```bash
adb -s <serial> logcat -c
adb -s <serial> logcat -v threadtime ParticleValidation:I MapLibre:I '*:S'
```
若使用非 x86_64 真机,当前 validation script 的固定 ABI 不适用;RDC 应按项目现行 Android 构建规则选择相符 ABI,并在证据中记录实际 APK、commit、ABI、设备与 renderer backend。
## 7. RDC Native 精确回归命令
如 RDC 使用 STEP-092 的现有 OpenGL build tree:
```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.*'
```
必须记录真实 test 数与结果;不能直接抄写“30/30”。
## 8. Android 逐项运行手册
### 8.1 通用观察方法
启动 Activity 后点 `STEP 093`。每次切场景等待 Style READY,再观察屏幕 diagnostics;需要固化证据时点 `READ DIAGNOSTICS` 并保存日志/截图。稳定性判断建议至少间隔 10–30 秒采两次快照:
- Particle 持续运动;
- 对存在的 cache,build/texture/composite 不再增长,reuse 与 Fast hit 应增长;
- 不存在的 range 显示 `present=false`、`state=disabled`,对应资源创建数不因稳定帧增长;
- counter 为累计值,切场景时应比较增量,不要求绝对值归零。
### 8.2 Topology A–E
1. A:选 `A BOTTOM + CONTINUOUS + TOP`。预期 range valid、Bottom/Top present、cache count 2;opaque 红块完整盖住 Particle,黄色半透明区域正确混合,白线在最上层,无黑边/halo/错误变暗。
2. B:选 `B BOTTOM + CONTINUOUS`。预期 Bottom present、Top absent、cache count 1;Top state disabled,Top 资源不增长,Fast Path 不因 Top absent 被阻断。
3. C:选 `C CONTINUOUS + TOP`。预期 Bottom absent、Top present、cache count 1;Bottom state disabled;Top 仍正确覆盖 Particle。
4. D:选 `D CONTINUOUS ONLY`。预期 valid、Bottom/Top 均 absent、cache count 0、不是 fallback;Particle 正常运行,Fast Path 可命中。
5. E:选 `E SINGLE-LAYER CONTINUOUS`。预期 start ID 等于 end ID、startIndex 等于 endIndex、`continuousEndExclusive = startIndex + 1`,不 fallback。
### 8.3 Mutation 与跨边界
在 `MUTATION / FAST PATH` 子菜单依次执行:
- `CONTINUOUS ADD` → `CONTINUOUS REORDER` → `RESTORE DEFAULT`:恢复动作也等价验证非 endpoint layer 删除;
- `BOTTOM ADD` → `BOTTOM REORDER` → restore;
- `TOP ADD` → `TOP REORDER` → restore;
- `CROSS → BOTTOM` → `CROSS → CONTINUOUS` → `CROSS → TOP`。
每次检查 endpoint ID 重新解析出的 index、present topology、invalidation/build/reuse 增量及最终画面顺序;不得出现旧 index、旧 cache 或自动按 layer 类型修正 range。
### 8.4 Endpoint 与 visibility
在 `ENDPOINT / VISIBILITY` 子菜单:
- start visible ↔ hidden、end visible ↔ hidden:index 与 topology 不变,hidden endpoint 仍是 endpoint;
- `DELETE START`:range invalid、fallback、无 crash/stale cache;`RESTORE START` 后恢复 valid 并 rebuild/reuse;
- 对 end 执行同样步骤。
### 8.5 Invalid explicit range
在 `INVALID RANGE` 子菜单依次执行 missing start、missing end、reversed、configure while style loading、empty ID、restore valid:
- missing/reversed/style-not-ready:不得猜测 endpoint,不复用 stale cache,diagnostics 给出原因;
- empty ID:当前 API 应同步返回 `accepted=false`;
- restore 后无需重建 Map instance,应重新 valid、build、reuse。
### 8.6 Camera/viewport
连续点四次 `CAMERA NEXT`,覆盖 target/zoom/bearing/pitch 组合。每次检查 invalidation → build → reuse,topology 不变,无错位、黑屏或 Particle/地图不同步。
旋转设备或改变模拟器窗口尺寸,确认同一 Activity/Map 上产生 viewport invalidation;如设备支持可改变 display scale/pixel ratio,并单独记录是否实际触发。
### 8.7 Fast Path fail-closed
先恢复 A,稳定后确认 eligible/active 与 hit 增长。再选 `FAST FAIL-CLOSED`:
- Continuous Range 仍 valid;
- fallback reason 为 `unsupported-continuous-layer`;
- Fast Path 不 active,full CPU frame 增长;
- 普通未知 layer 不被跳过或移出 Continuous;
- Bottom/Top 与最终 Z-order 仍正确。
### 8.8 长时间运行
建议 RDC 在可用设备上连续运行 15–30 分钟,循环 topology、camera、mutation、endpoint、visibility、invalid/restore、再次稳定:观察 texture/composite create 与 release 增量、系统内存/GPU 工具可获得的数据、黑屏/闪屏/stale cache/偶发层序/Particle 恢复。若没有可靠 GPU byte 数,明确记录限制,不伪造内存数字。
## 9. PASS / FAIL 判定
- `PASS`:必须有实际设备/模拟器操作、画面确认与 diagnostics/log 证据,并满足该行预期。
- `FAIL`:实际结果违背预期;保留首个真实错误、场景、截图/日志和 commit。
- `WAITING_*`:入口已准备但平台尚未执行。
- 编译 PASS、静态检查 PASS、另一平台 PASS 均不能替代当前平台 runtime PASS。
## 10. 验收矩阵
| 类别 | 场景 | Android | iOS/Metal | 关键证据 | 结论 |
|---|---|---|---|---|---|
| Topology | Bottom+Continuous+Top | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | A 按钮、range/index、2 cache、画面截图待采集 | NOT RUN |
| Topology | Bottom+Continuous | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | B 按钮、Top disabled/资源增量待采集 | NOT RUN |
| Topology | Continuous+Top | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | C 按钮、Bottom disabled/资源增量待采集 | NOT RUN |
| Topology | Continuous-only | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | D 按钮、valid + 0 cache + 非 fallback 待采集 | NOT RUN |
| Range | Single-layer Continuous | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | E 按钮、start=end、endExclusive=start+1 待采集 | NOT RUN |
| Z-order | Top covers Particle | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | opaque/semi-transparent/line 视觉截图待采集 | NOT RUN |
| Cache | Stable reuse | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | 两次 counter 快照待采集 | NOT RUN |
| Invalidation | Pan/Zoom/Rotate/Pitch | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | camera preset 前后 invalid/build/reuse 待采集 | NOT RUN |
| Mutation | Continuous internal mutation | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | add/reorder/restore diagnostics 待采集 | NOT RUN |
| Mutation | Cross-range move | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | cross layer 三位置的 index/Z-order 待采集 | NOT RUN |
| Endpoint | start missing/recovery | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | invalid reason + restore valid 待采集 | NOT RUN |
| Endpoint | end missing/recovery | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | invalid reason + restore valid 待采集 | NOT RUN |
| Visibility | hidden endpoint topology | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | visible/hidden index 不变待采集 | NOT RUN |
| Invalid | missing/reversed range | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | fallback/lastReason/no stale cache 待采集 | NOT RUN |
| Fast Path | eligible | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | eligible/active/hit/full counter 待采集 | NOT RUN |
| Fast Path | unknown layer fail-closed | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | unsupported reason/full CPU frame 待采集 | NOT RUN |
| Alpha | Top premultiplied composite | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | transparent/opaque/semi/line 视觉证据待采集 | NOT RUN |
| Stability | repeated operations / long run | WAITING_ANDROID_RUNTIME_VALIDATION | WAITING_IOS_RUNTIME_VALIDATION | 长时间 counter/内存/画面记录待采集 | NOT RUN |
## 11. 问题、限制与未执行项
- 未发现需要修改 STEP-092 数学定义、Style 顺序、0/1/2 cache 或 Fast Path 核心模型的架构阻塞。
- diagnostics 是累计 counter,不是 per-scene reset;RDC 应使用前后增量。
- 资源 release counter 表示 holder 释放事件,不是释放字节数。
- Android 场景 Style reload 是可重复的测试手段;跨场景比较必须等待 READY。
- 当前 iOS 没有专用 STEP-093 面板,只有 diagnostics API/bridge;这是明确待办,不虚报 iOS runtime 能力完成。
- Android/iOS build、Native tests、APK、安装、ADB、真机/模拟器、视觉、长时间运行均 NOT RUN。
## 12. 下一步
1. RDC 对 implementation commit `b3ec8edc87ece404b5f7b3706f5acf2a70de6862` 执行 Native 精确回归与 Android build/runtime 矩阵。
2. 若 Android 核心矩阵全部实际通过,可更新为 `ANDROID CLOSED / PASS + IOS WAITING_RUNTIME_VALIDATION`。
3. 准备 iOS/Metal 对等 validation UI 或可重复操作入口,再独立执行 iOS 矩阵。
4. 只有任务书 24 节全部完成、Git 与文档闭环后,才能更新为 `CLOSED / PASS`。