Files
MapLibreParticleLab/docs/50_Step记录/STEP-088_静态底图缓存PoC与Renderer观测_v2.md
tei 9ad2fe5d58
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
docs: record STEP-088 Android validation
2026-09-22 10:24:14 +09:00

140 lines
6.2 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-088 静态底图缓存 PoC 与 Renderer 观测 v2
## 状态
进行中
`ANDROID TEST APP PASS / WAITING FOR NAVSEA VALIDATION`
STEP-088 尚未关闭,也不得据此进入 STEP-089/090。
## 本版目的
本文在 v1 实现记录基础上,记录 Android MapLibreAndroidTestApp 实机发现的 placement fallback 问题、Renderer 修正、Mac 最终复验和 Android Test App 运行态验收。v1 中的 retained underlay 架构、范围和 PoC 限制继续有效。
## 基线
- 仓库:`/Users/tei/dev/MapLibreParticleLab`
- 分支:`particle/main`
- v1 实现提交:`8b9ab303228c307612c47f7f3379ad06206ea14e`
- debug counters 日志提交:`e7d109246a225eb1c1b2f177aa30e3c7fcdf658e`
- Android placement-scoping 修正提交:`1d1a7915e0886c46be40f4fc9a2eff13192f804b`
- 当前版本坐标:`13.4.1-particle.10`
## Android 首轮问题
较早安装的 STEP-088 APK 在 fixed camera / only Particle 场景持续 full-render fallback:
```text
frame=1200 build=0 reuse=0 fallback=1199 invalidation=1199
staticDraw=0 dynamicDraw=0 particleAdvance=1199
```
根因是 retained eligibility 无条件受全局 placement transition、`placementChanged` 和 `symbolFadeChange` 约束。即使 retained static prefix 没有 symbol/placement layer,动态范围或全局 placement 状态也会阻止 cache build/reuse。
## Renderer 修正
- `RenderOrchestrator::retainedUnderlayUsesPlacement(boundary)` 只检查 boundary 之前的 retained static prefix。
- static prefix 不使用 placement 时,全局 placement transition、`placementChanged` 和 `symbolFadeChange` 不再阻止 retained cache。
- static prefix 真正使用 placement 时,上述 placement stability 保护仍然生效并安全 fallback。
- 原有 3D、debug、legacy ordering、style-not-loaded、static transition、resource/compositor failure 等 fallback 不变。
- debug-only `ParticleRetained` 周期日志保留 `reason=<lastInvalidationReason>`,用于区分 `first-frame`、`camera-or-boundary`、`style-not-loaded`、`static-transition`、`static-placement` 等原因;Release/NDEBUG 语义不变。
## Android Validation 构建辅助
`platform/android/MapLibreAndroidTestApp/build.gradle.kts` 新增测试专用 property:
```text
maplibre.validation.stripNativeDebugSymbols=true
```
默认 Debug 行为不变,仍保留 native debug symbols。只有 Validation 构建显式启用该 property 时才允许 strip native symbols;x86_64 Debug APK 由约 375 MB 降至约 57 MB。该改动不改变 Renderer、debug counters 或 `NDEBUG` 语义。
## RDC Mac 最终复验
- `cmake --build build-step088-opengl --target mbgl-test-runner -j3`:PASS / no work to do;RDC 已确认当前 placement-scoping 源码已编入 object。
- STEP-088 定向测试:4/4 PASS:
- `RetainedDynamicBoundary.SelectsFirstCandidate`
- `RetainedLayerGroupRange.PreservesForwardReverseOriginalOrdinals`
- `RetainedUnderlayCache.BuildReuseAndInvalidation`
- `RetainedUnderlayCache.UnsupportedAndResourceFailureFallBackSafely`
- `cmake --build build-ios --config Debug --target mbgl-core -j3`:`BUILD SUCCEEDED`。
- `git diff --check`:PASS。
上述命令均由 RDC 执行;Codex 文档与 Git 收尾阶段未重新执行 build/test。
## Android Test App 环境
- 设备:`192.168.200.139:5555`
- 设备标识:FZG1-2
- 系统:Android 13
- ABI:x86_64
- App:MapLibreAndroidTestApp OpenGL Debug x86_64
- Validation strip property:启用
- 构建、安装、ADB 与 Activity 启动:均成功
## Android Test App 运行态结果
### Fixed camera / only Particle
```text
frame=840 build=1 reuse=836 fallback=2 invalidation=3
reason=first-frame staticDraw=2 dynamicDraw=5022 particleAdvance=839
```
后续 `reuse` 持续增长,`staticDraw` 保持不变,证明 retained static prefix 首次 build 后被复用。
### Camera DATELINE
- 变化前:`build=1`、`staticDraw=2`。
- camera transition 后:`build=2`、`staticDraw=4`。
- 随后 `reuse` 重新持续增长。
- 观测原因:`reason=camera-or-boundary`。
结果符合 camera change → transition 期间安全 fallback/invalidate → 稳定后 rebuild 一次 → reuse。
### REAL WEATHER
- `REAL_WEATHER_INITIAL_WINDOW_READY` 正常。
- `WEATHER_COLOR_FIELD_READY` 正常。
- GSI raster + WeatherColor + Particle 正常进入 retained path。
- 代表数据:`frame=6960 build=3 reuse=6907 fallback=49 invalidation=52 staticDraw=6 particleAdvance=6959`。
- fixed camera 后 `reuse` 持续增长,`staticDraw` 保持 6。
- `TARGET_FPS_CHANGED target=FPS_30` 成功,缓存继续 reuse。
### Resize / rotation
viewport 完成 `1280x680 → 800x1160 → 1280x680`。过渡期间出现安全的 `style-not-loaded` fallback;稳定后 rebuild 并继续 reuse。设备最终恢复 `accelerometer_rotation=1`、`user_rotation=0`。
### STATIC / ACTIVE
- STATIC 时 RenderThread 约 0%。
- ACTIVE 后恢复 continuous render,retained reuse 继续增长且 `staticDraw` 保持不变。
- 旧 Test App 设备上 ACTIVE RenderThread 约 96%~107%,仅作为 Test App 对照,不代表 NavSea 最终性能。
### 异常扫描
未发现 `FATAL EXCEPTION`、`SIGSEGV`、`SIGABRT`、ANR、`GL_INVALID`、`EGL_BAD` 或 OOM。
## 当前验收边界
Android MapLibreAndroidTestApp 运行态验证为 PASS,但它不能替代 NavSea 复杂真实 Style 的最终验证。以下仍待 NavSea 完成:
1. 真实复杂 Style 的视觉与 layer ordering。
2. 大量 PBF/fill/line/symbol 下 retained static prefix 的 `staticDraw` 稳定性。
3. Particle OFF/ON 的 RenderThread、main、JS CPU 对比。
4. pan/zoom/resize/fallback 后无 stale underlay。
5. only Particle 与 WeatherColor + Particle 在真实产品 layer stack 中的一致性。
## PoC 边界
- 未实现 STEP-089 production 全量 invalidation。
- 未实现 STEP-090 animation-only CPU fast path。
- 未修改 NavSea、React、Host API 或 C-001。
- Android Test App PASS 不构成 STEP-088 overall CLOSED/PASS。
- NavSea 验证完成前不得进入 STEP-089/090。
## 当前结论
placement-scoping 修正解决了 Android 上 static prefix 不含 placement 时的每帧 fallback。Mac OpenGL/Metal、Native 定向测试及 Android Test App 运行态均已通过;STEP-088 当前唯一剩余 Gate 是 NavSea 复杂真实 Style 验证。