Files
MapLibreParticleLab/docs/50_Step记录/STEP-099_RenderSource就绪与RenderSegment失效诊断_v1.md
tei c4b481fd2c
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
docs: close STEP-099 render source diagnostics
2026-10-06 15:33:12 +09:00

6.1 KiB
Raw Permalink Blame History

STEP-099 RenderSource 就绪与 RenderSegment 失效诊断

状态:CLOSED / PASS 日期:2026-10-06(JST)

基线

  • 仓库:/Users/tei/dev/MapLibreParticleLab-step099
  • 分支:step099-render-source-diagnostics
  • frozen release:maplibre-particle/rn/13.4.1-particle.17
  • frozen release commit:e8b451fe70054107773e82484c80e90df3889147
  • implementation commit:8a5214d92dd2f8899db76d2194da42999fa0c87d
  • Integration/NavSea:未修改。

本 Step 完成内容

  • Renderer readiness snapshot additive 暴露 style/image manager/render orchestrator/sprite readiness、fading、global content revision、per-source 状态和最近 mutation。
  • per-source diagnostics 暴露 sourceId/type/enabled/isLoaded;tile-backed source 提供 tileCount/incomplete/loaded/fading。
  • RenderSegment diagnostics 只读推导 dependentSourceIds / unknownDependencies;source-less layer 不制造 source dependency,共享 source 可出现在多个 segment。
  • mutation sequence/source/tile action/reason 只消费既有 renderer 事件;正式 revision 增长逻辑不变。
  • 正式 loaded 判定保持: renderTreeParameters->loaded = updateParameters->styleLoaded && isLoaded();
  • diagnostics snapshot 不进入正式 loaded/cache/fast path/segment execution。
  • RN 仅增加 diagnostics 类型字段;没有 NavSea 私有 API,没有改变业务 API。
  • Android Test App 提供 T1 STATIC、T2 GEOJSON_1HZ、T3 PERMANENT_UNREADY、T4 R-C-R。

Native 验证

Metal host RenderSegmentDiagnostics.*:

  • 6/6 PASS;
  • 新增 ReadinessSnapshotMapsSourcesToSegmentsWithoutSideEffects PASS;
  • 覆盖 source readiness、tile stats、source→segment、shared source、source-less 与重复 query 无副作用。

最终源码再次尝试 Metal configure 时当前 Mac 缺 libuv pkg-config,因此第二次 host rerun 未进入 build;不虚报 PASS。最终代码已经被 Android 全量 native build 成功编译并由 T1~T4 运行覆盖。

Vulkan:因当前 Mac 缺 libuv,NOT RUN tests。

Jest:NOT RUN,用户未要求。

Android 构建

首轮 Android NDK 暴露:

error: missing field 'tileCount' initializer
[-Werror,-Wmissing-designated-field-initializers]

只补全 RenderSourceReadinessStats 默认空字段显式初始化。

随后 native build 通过,但 strip 阶段因 Mac 磁盘仅剩约 2 GiB:

No space left on device

仅清理可再生 Gradle 9.5.1 cache / 失败中间产物后恢复约 12 GiB,再次增量构建:

  • BUILD SUCCESSFUL in 4m 54s
  • 86 actionable tasks:7 executed / 79 up-to-date
  • OpenGL Debug / x86_64
  • APK:61,923,024 bytes
  • libmaplibre.so:39,602,856 bytes
  • SHA-256: 5de73f0358b835a78d3ae7e2ac22f4efdb2a66775b8c63654a8bb7313957d90a

设备:

  • 192.168.200.139:5555
  • FZG1-2
  • Android 13 / API 33 / x86_64

T1~T4 结果

T1 STATIC

  • 1 个启动 false window;
  • avg/max = 204 ms;
  • 随后 global loaded 稳定为 true;
  • retained cache 可持续 reuse;
  • fast path 可进入 active。

T2 GEOJSON_1HZ

  • 两个 GeoJSON source 交错更新,总 update 122 次,约 61 次/源;
  • 10 个 loaded=false window;
  • avg 203 ms;
  • max 205 ms;
  • open 0;
  • 约 60 s 中 false 总时长约 2.03 s,约 3.4%。

结论:存在 readiness thrash,但不是“几乎永远 false”。

T3 PERMANENT_UNREADY

step099-unready-raster-array:

  • 无 layer;
  • enabled=false;
  • isLoaded=false;
  • 其他主要 source loaded。

结果:

  • global renderOrchestratorLoaded=false 持续;
  • 观察结束 open false window = 21,459 ms;
  • retained cache 持续 style-not-loaded fallback。

结论:单个与 segment 无关的 permanently unready source 足以拉低 V17 全局 loaded。

T4 R-C-R

  • R0 deps=[step099-static]
  • C deps=[particle-fixture]
  • R1 deps=[org.maplibre.annotations, step099-dynamic, step099-static]
  • dynamic update:61 次

结果:

  • loaded false windows:4
  • avg 203 ms
  • max 207 ms
  • contentRevision:1760 → 2540
  • diagnostics 对 dynamic source 正确给出 affected=[2]
  • R0 不依赖 dynamic source,但:
    • build 1 → 121
    • invalidation 20 → 200

结论:dependency diagnostics 已能表达 source-local 影响,但 V17 正式 content revision/cache invalidation 仍为 global。

Q1~Q7

  1. Q1:YES。permanently unloaded source 会造成全局 style-not-loaded。
  2. Q2:YES。1 Hz GeoJSON 会产生约 200 ms readiness false window;T2 avg 203 / max 205 ms。
  3. Q3:NO(本次观测)。双 1 Hz source 并未让 global loaded 几乎始终 false。
  4. Q4:YES。GeoJSON tile mutation 推进 global content revision,并使 retained cache 重建/失效。
  5. Q5:YES。不引用动态 GeoJSON 的 R0 仍受 global revision 影响;源码还确认 retainedRangeIsStable 全局检查所有 source fading。
  6. Q6:fast path 仍有 global update signature(sources/layers/images 等)、global content revision、global fade、pendingChanges、placement/light/non-particle transition/repaint、annotation mutation、retained revision/cache/topology/boundary,以及 singleContinuous gate。
  7. Q7 blocker:
    • runtime confirmed:PERMANENT_SOURCE_UNLOADED、DYNAMIC_SOURCE_READINESS_THRASH、GLOBAL_CONTENT_REVISION
    • source confirmed:GLOBAL_FADE、GLOBAL_UPDATE_SIGNATURE
    • OTHER:pending/placement/light/repaint/annotation/topology/boundary/singleContinuous。

证据

忽略目录:

artifacts/maplibre-particle/android-validation/

  • build-info.txt
  • build.log
  • MapLibreAndroidTestApp-validation-opengl-debug-x86_64.apk
  • step099-logcat.txt
  • step099-device-info.txt
  • step099-metal-gtest.log

STEP-099 log SHA-256:

0f15d75dde77e7dd2f4d98c46a4c1501a628205e8aae62130b0cb96db6b8482f

边界结论

本 Step 未修改:

  • retained cache 算法;
  • fast path gate;
  • singleContinuous / multi-continuous;
  • segment-local invalidation 正式语义;
  • RenderSegment execution;
  • NavSea;
  • Source isLoaded;
  • RN 业务 API。

下一阶段应拆分处理 global source readiness、source/segment-local content revision/invalidation,再独立处理 fast-path global gates。