Files
MapLibreParticleLab/docs/报告/STEP-088_静态底图缓存PoC与Renderer观测_Codex完成报告_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

7.6 KiB
Raw Permalink Blame History

STEP-088 静态底图缓存 PoC 与 Renderer 观测 Codex 完成报告 v2

1. 执行结论

  • 状态:ANDROID TEST APP PASS / WAITING FOR NAVSEA VALIDATION
  • Android MapLibreAndroidTestApp 运行态验证:PASS。
  • STEP-088 overall:未关闭,不得写作 CLOSED/PASS。
  • NavSea 复杂真实 Style 尚未验证,因此不得进入 STEP-089/090。

2. Git 基线与提交

  • 机器:Mac mini,Darwin x86_64
  • 仓库:/Users/tei/dev/MapLibreParticleLab
  • 分支:particle/main
  • 本轮起始 HEAD:e7d109246a225eb1c1b2f177aa30e3c7fcdf658e
  • v1 实现提交:8b9ab303228c307612c47f7f3379ad06206ea14e
  • 本轮代码修正提交:1d1a7915e0886c46be40f4fc9a2eff13192f804b
  • 本轮代码提交信息:fix: scope retained underlay placement fallback
  • 代码 push:成功,e7d109246..1d1a7915e particle/main -> particle/main
  • 远端分支:origin/particle/main
  • v2 文档 closeout commit 与最终 Final HEAD 记录在最终响应中,避免 Git commit 自引用。

3. Android 首轮失败事实

较早 STEP-088 APK 在 fixed camera / only Particle 场景的代表数据为:

frame=1200 build=0 reuse=0 fallback=1199 invalidation=1199
staticDraw=0 dynamicDraw=0 particleAdvance=1199

cache 从未 build。审查确认 retained path 无条件受全局 placement transition、placementChanged 和 symbolFadeChange 约束,导致 static prefix 不含 placement 时仍每帧 fallback。

4. 实际修改文件

代码提交只包含:

  • src/mbgl/renderer/render_orchestrator.cpp
  • src/mbgl/renderer/render_orchestrator.hpp
  • src/mbgl/renderer/renderer_impl.cpp
  • platform/android/MapLibreAndroidTestApp/build.gradle.kts

文档提交只包含:

  • docs/50_Step记录/STEP-088_静态底图缓存PoC与Renderer观测_v2.md
  • docs/报告/STEP-088_静态底图缓存PoC与Renderer观测_Codex完成报告_v2.md

未修改或提交 AGENTS.md、submodule、iOS dirty 文件、STEP-082/083 untracked、既有 untracked STEP-088 task/规划文档或其他用户文件。

5. Renderer placement-scoping 修正

  • RenderOrchestrator::retainedUnderlayUsesPlacement(boundary) 只遍历 boundary 之前的 ordered layers,判断 retained static prefix 是否真正依赖 placement。
  • retainedUnderlayIsStable(...) 继续保护 light/static-layer transition;只有 static prefix 使用 placement 时才检查 placementController.hasTransitions(...)。
  • Renderer::Impl::render(...) 只有在 static prefix 使用 placement 时才要求 placementChanged == false 且 symbolFadeChange == 0。
  • fallback reason 拆分为 static-transition 与 static-placement,便于区分原因。
  • 无 boundary、empty prefix、style-not-loaded、3D、debug、legacy ordering、resource/compositor failure 等 STEP-088 fallback 未改变。

该修正只调整 retained static prefix 的 eligibility,没有实现 production 全量 invalidation,也没有改变动态 boundary、LayerGroup ordinal/depth、draw ordering、Host API 或 C-001。

6. Debug reason 日志

保留 debug-only ParticleRetained 周期日志中的:

reason=<lastInvalidationReason>

它复用 RetainedUnderlayCache::getLastInvalidationReason(),用于 Android 验证 first-frame、camera-or-boundary、style-not-loaded、static-transition 和 static-placement。日志仍位于 #ifndef NDEBUG,不改变 Release 行为,也不增加 Host API。

7. Android Validation strip property

MapLibreAndroidTestApp 增加:

maplibre.validation.stripNativeDebugSymbols=true

默认 Debug 构建继续 keepDebugSymbols += "**/*.so"。只有显式启用 Validation property 时才允许 strip native symbols,使 x86_64 Debug APK 从约 375 MB 降至约 57 MB。Debug counters 与 NDEBUG 语义不变。

8. RDC Mac 最终复验

  • cmake --build build-step088-opengl --target mbgl-test-runner -j3:PASS / no work to do;源码/object 时间戳已确认当前 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 本次收尾未执行任何新 build/test、Gradle、ADB、Xcode 或设备操作。

9. Android Test App 环境

  • 设备:192.168.200.139:5555,FZG1-2
  • Android:13
  • ABI:x86_64
  • 构建:MapLibreAndroidTestApp OpenGL Debug x86_64
  • Validation strip property:启用
  • build/install/ADB/Activity:成功

10. 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 保持不变。

Camera DATELINE

build 从 1 增至 2,staticDraw 从 2 增至 4;随后 reuse 恢复持续增长,原因为 camera-or-boundary。符合 camera transition 后安全 invalidation/fallback、稳定后单次 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。

11. 验收结论与边界

Android MapLibreAndroidTestApp 已证明:

  • static prefix 不使用 placement 时,全局 placement 状态不再错误阻塞 retained cache;
  • first build 后能够持续 reuse,static draw 不再随 Particle frame 增长;
  • camera 和 viewport 变化会安全 invalidation/rebuild;
  • GSI raster + WeatherColor + Particle、FPS 30、STATIC/ACTIVE 均可运行;
  • 未发现 crash、ANR、GL/EGL 或 OOM 异常。

但 Test App 不能替代 NavSea 复杂真实 Style。以下仍无法验证:

  • 真实产品 layer stack 的视觉与 ordering;
  • 大量 PBF/fill/line/symbol static prefix 的 staticDraw 行为;
  • Particle OFF/ON RenderThread、main、JS CPU 收益;
  • pan/zoom/resize/fallback 后是否始终无 stale underlay。

因此 STEP-088 overall 仍为 ANDROID TEST APP PASS / WAITING FOR NAVSEA VALIDATION,不是 CLOSED/PASS。

12. 范围与未完成事项

  • 未进入 STEP-089 production invalidation。
  • 未进入 STEP-090 animation-only fast path。
  • 未修改 NavSea、React、Host API 或 C-001。
  • NavSea 复杂真实 Style 验证完成前,不得进入 STEP-089/090。

13. Git 收尾

  • Renderer/Validation fix commit:1d1a7915e0886c46be40f4fc9a2eff13192f804b
  • Commit message:fix: scope retained underlay placement fallback
  • Push result:成功,e7d109246..1d1a7915e particle/main -> particle/main
  • Remote branch:origin/particle/main
  • v2 文档 closeout commit hash、message、push result 与最终 Final HEAD:由最终响应记录。