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

6.2 KiB
Raw Permalink Blame History

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:

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:

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

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 验证。