docs: close STEP-099 render source diagnostics
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
This commit is contained in:
175
docs/50_Step记录/STEP-099_RenderSource就绪与RenderSegment失效诊断_v1.md
Normal file
175
docs/50_Step记录/STEP-099_RenderSource就绪与RenderSegment失效诊断_v1.md
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
# 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 暴露:
|
||||||
|
|
||||||
|
```text
|
||||||
|
error: missing field 'tileCount' initializer
|
||||||
|
[-Werror,-Wmissing-designated-field-initializers]
|
||||||
|
```
|
||||||
|
|
||||||
|
只补全 `RenderSourceReadinessStats` 默认空字段显式初始化。
|
||||||
|
|
||||||
|
随后 native build 通过,但 strip 阶段因 Mac 磁盘仅剩约 2 GiB:
|
||||||
|
|
||||||
|
```text
|
||||||
|
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。
|
||||||
@@ -0,0 +1,536 @@
|
|||||||
|
# STEP-099 RenderSource 就绪与 RenderSegment 失效诊断 — Codex 完成报告 v1
|
||||||
|
|
||||||
|
## 1. 执行结论
|
||||||
|
|
||||||
|
**CLOSED / PASS(诊断阶段完成)**。
|
||||||
|
|
||||||
|
STEP-099 按任务书保持“纯诊断、fail-closed、不优化正式语义”的范围完成。Renderer/Source/RenderSegment diagnostics、Android Test App T1~T4 场景、定向 native 测试和 Android 实机运行证据均已取得,Q1~Q7 可以据实回答。
|
||||||
|
|
||||||
|
本 Step **没有**修改 retained cache 算法、fast path gate、`singleContinuousSegment`、multi-continuous 行为、segment-local invalidation、RenderSegment 执行语义、NavSea、Source `isLoaded()` 定义或 RN 业务 API 语义。
|
||||||
|
|
||||||
|
## 2. 基线与 Git
|
||||||
|
|
||||||
|
- 仓库:`/Users/tei/dev/MapLibreParticleLab-step099`
|
||||||
|
- branch:`step099-render-source-diagnostics`
|
||||||
|
- frozen release tag:`maplibre-particle/rn/13.4.1-particle.17`
|
||||||
|
- frozen release commit / start base:`e8b451fe70054107773e82484c80e90df3889147`
|
||||||
|
- implementation commit:`8a5214d92dd2f8899db76d2194da42999fa0c87d`
|
||||||
|
- implementation message:`diagnostics: add STEP-099 render source readiness audit`
|
||||||
|
- Integration/NavSea:未修改。
|
||||||
|
- 文档 closeout commit、push result、`origin/particle/main` Final HEAD:Git 提交无法在自身内容中自指其最终 SHA,按项目既有规则由最终交付回读记录。
|
||||||
|
|
||||||
|
## 3. 实际修改范围
|
||||||
|
|
||||||
|
生产源码 / diagnostics:
|
||||||
|
|
||||||
|
- `include/mbgl/renderer/render_segment.hpp`
|
||||||
|
- `src/mbgl/renderer/render_orchestrator.cpp`
|
||||||
|
- `src/mbgl/renderer/render_orchestrator.hpp`
|
||||||
|
- `src/mbgl/renderer/render_segment_json.hpp`
|
||||||
|
- `src/mbgl/renderer/render_source.hpp`
|
||||||
|
- `src/mbgl/renderer/retained_underlay_runtime_state.hpp`
|
||||||
|
- `src/mbgl/renderer/sources/render_tile_source.cpp`
|
||||||
|
- `src/mbgl/renderer/sources/render_tile_source.hpp`
|
||||||
|
- `packages/maplibre-particle-rn/src/index.ts`
|
||||||
|
- `packages/maplibre-particle-rn/src/types.ts`
|
||||||
|
|
||||||
|
测试 / Test App:
|
||||||
|
|
||||||
|
- `test/renderer/retained_underlay_cache.test.cpp`
|
||||||
|
- `platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/particle/ParticleCoreLayerValidationActivity.kt`
|
||||||
|
- `platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/particle/Step099ReadinessFixture.kt`
|
||||||
|
|
||||||
|
项目记录:
|
||||||
|
|
||||||
|
- `docs/50_Step记录/STEP-099_RenderSource就绪与RenderSegment失效诊断_v1.md`
|
||||||
|
- `docs/报告/STEP-099_RenderSource就绪与RenderSegment失效诊断_Codex完成报告_v1.md`
|
||||||
|
- `粒子开发记录.md`
|
||||||
|
|
||||||
|
## 4. 诊断能力
|
||||||
|
|
||||||
|
### 4.1 全局 readiness
|
||||||
|
|
||||||
|
新增只读 snapshot:
|
||||||
|
|
||||||
|
- `styleLoaded`
|
||||||
|
- `imageManagerLoaded`
|
||||||
|
- `renderOrchestratorLoaded`
|
||||||
|
- `spriteLoaded`
|
||||||
|
- `hasFadingTiles`
|
||||||
|
- global retained `contentRevision`
|
||||||
|
- RenderSegment plan/config/topology 信息
|
||||||
|
- 最近 mutation sequence / reason / source / affected segment diagnostics
|
||||||
|
|
||||||
|
正式 loaded 路径保持原式:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
renderTreeParameters->loaded = updateParameters->styleLoaded && isLoaded();
|
||||||
|
```
|
||||||
|
|
||||||
|
diagnostics snapshot 在旁路采样,失败被 best-effort 隔离,不决定正式 loaded。
|
||||||
|
|
||||||
|
### 4.2 per-source readiness
|
||||||
|
|
||||||
|
每个 RenderSource additive 暴露:
|
||||||
|
|
||||||
|
- sourceId / sourceType
|
||||||
|
- enabled / isLoaded
|
||||||
|
- tileBacked
|
||||||
|
- tileCount / incompleteTileCount / loadedTileCount
|
||||||
|
- hasFadingTiles
|
||||||
|
- last source/tile mutation sequence
|
||||||
|
- last tile action / reason
|
||||||
|
|
||||||
|
默认非 tile source 返回完整显式初始化的空统计,Android NDK `-Werror` 下已验证通过;未改变任何 Source `isLoaded()` 实现。
|
||||||
|
|
||||||
|
### 4.3 RenderSegment 只读依赖
|
||||||
|
|
||||||
|
每个 segment additive 暴露:
|
||||||
|
|
||||||
|
- segmentIndex / strategy / beginIndex / endExclusive
|
||||||
|
- `dependentSourceIds`
|
||||||
|
- `unknownDependencies`
|
||||||
|
|
||||||
|
规则:
|
||||||
|
|
||||||
|
- 从实际 ordered layers 的 sourceId 推导;
|
||||||
|
- shared source 可出现在多个 segment;
|
||||||
|
- source-less background 不制造假依赖;
|
||||||
|
- symbol/custom 等无法仅靠 sourceId 完整表达的依赖标记为 unknown/global;
|
||||||
|
- 依赖图只用于诊断,不参与 cache/loaded/fast path/execution。
|
||||||
|
|
||||||
|
### 4.4 mutation 定位
|
||||||
|
|
||||||
|
Source/tile mutation 复用已有回调记录 sequence/source/reason/action。原 `retainedUnderlayContentRevision` 的增长次数与正式调用路径不变;diagnostics 不增加额外 revision。
|
||||||
|
|
||||||
|
query 路径不清理或修改 event history,重复 snapshot/JSON 查询保持无副作用。
|
||||||
|
|
||||||
|
## 5. Native 定向测试
|
||||||
|
|
||||||
|
### 5.1 Metal host 定向 GTest
|
||||||
|
|
||||||
|
实际执行:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cmake --preset macos-metal
|
||||||
|
cmake --build build-macos-metal --target mbgl-test-runner --parallel 3
|
||||||
|
build-macos-metal/mbgl-test-runner --gtest_filter='RenderSegmentDiagnostics.*'
|
||||||
|
```
|
||||||
|
|
||||||
|
结果:
|
||||||
|
|
||||||
|
- `RenderSegmentDiagnostics.*`:**6/6 PASS**
|
||||||
|
- 新增 `ReadinessSnapshotMapsSourcesToSegmentsWithoutSideEffects`:PASS
|
||||||
|
- 覆盖 source loaded/unloaded、tile stats、source→segment、shared source、source-less、重复 query、topology/cache/content revision 无副作用。
|
||||||
|
|
||||||
|
证据:
|
||||||
|
`artifacts/maplibre-particle/android-validation/step099-metal-gtest.log`
|
||||||
|
|
||||||
|
SHA-256:
|
||||||
|
`f0618750ead03eae1b251126dd49488a9269a120373a66e3453fa9aaa1dc0f10`
|
||||||
|
|
||||||
|
说明:该 6/6 发生在 Android NDK 首轮暴露“默认 readiness struct designated initializer 未显式列完 optional 字段”之前;随后仅补全默认空字段初始化。最终源码由 Android 全量 native build 成功覆盖。为了在最终源码上重跑 Metal,重新 configure 时当前 Mac 缺 `libuv` pkg-config,configure fail;没有安装系统依赖来制造 PASS。
|
||||||
|
|
||||||
|
### 5.2 Vulkan
|
||||||
|
|
||||||
|
`macos-vulkan` configure:**BLOCKED / NOT RUN TESTS**。
|
||||||
|
|
||||||
|
原因:
|
||||||
|
|
||||||
|
```text
|
||||||
|
The following required packages were not found:
|
||||||
|
- libuv
|
||||||
|
```
|
||||||
|
|
||||||
|
这是当前 Mac host 环境依赖,不是 STEP-099 源码编译错误。
|
||||||
|
|
||||||
|
### 5.3 Jest
|
||||||
|
|
||||||
|
**NOT RUN**。用户未要求 Jest,任务未加入 Jest。
|
||||||
|
|
||||||
|
## 6. Android 构建与设备
|
||||||
|
|
||||||
|
### 6.1 首轮 Android 编译问题
|
||||||
|
|
||||||
|
首轮 x86_64 OpenGL build 在 Android NDK `-Werror` 下发现:
|
||||||
|
|
||||||
|
```text
|
||||||
|
render_source.hpp:84:51:
|
||||||
|
error: missing field 'tileCount' initializer
|
||||||
|
[-Werror,-Wmissing-designated-field-initializers]
|
||||||
|
```
|
||||||
|
|
||||||
|
修复仅补全 `RenderSourceReadinessStats` 默认空字段初始化,不改变运行语义。
|
||||||
|
|
||||||
|
随后 native C++ 已越过原失败点并完整编译。
|
||||||
|
|
||||||
|
### 6.2 磁盘阻塞与恢复
|
||||||
|
|
||||||
|
第一次完整 native build 后,在:
|
||||||
|
|
||||||
|
`MapLibreAndroidTestApp:stripOpenglDebugDebugSymbols`
|
||||||
|
|
||||||
|
因 Mac 仅剩约 2 GiB 出现:
|
||||||
|
|
||||||
|
```text
|
||||||
|
No space left on device
|
||||||
|
```
|
||||||
|
|
||||||
|
RDC 只清理可再生 Gradle 9.5.1 cache / 本轮失败中间产物,保留 Android native object;可用空间恢复到约 12 GiB 后增量重跑。
|
||||||
|
|
||||||
|
### 6.3 最终 APK
|
||||||
|
|
||||||
|
命令:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./tools/particle_android_validation/build_validation_apk.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
最终结果:
|
||||||
|
|
||||||
|
- Gradle:**BUILD SUCCESSFUL in 4m 54s**
|
||||||
|
- actionable tasks:86(7 executed / 79 up-to-date)
|
||||||
|
- variant:OpenGL Debug
|
||||||
|
- ABI:x86_64
|
||||||
|
- APK:61,923,024 bytes
|
||||||
|
- `libmaplibre.so`:39,602,856 bytes
|
||||||
|
- APK SHA-256:
|
||||||
|
`5de73f0358b835a78d3ae7e2ac22f4efdb2a66775b8c63654a8bb7313957d90a`
|
||||||
|
|
||||||
|
构建时 metadata:
|
||||||
|
|
||||||
|
- base commit:`e8b451fe70054107773e82484c80e90df3889147`
|
||||||
|
- `git_dirty=true`
|
||||||
|
- 构建内容与随后形成的 implementation commit `8a5214d92` 源码一致;当前 source tree 对 implementation commit clean,剩余仅 docs closeout。
|
||||||
|
|
||||||
|
### 6.4 Android 设备
|
||||||
|
|
||||||
|
Mac ADB 直接连接:
|
||||||
|
|
||||||
|
- serial:`192.168.200.139:5555`
|
||||||
|
- model:`FZG1-2`
|
||||||
|
- Android:13
|
||||||
|
- API:33
|
||||||
|
- ABI:x86_64
|
||||||
|
|
||||||
|
APK 覆盖安装成功,`ParticleCoreLayerValidationActivity` 冷启动成功。
|
||||||
|
|
||||||
|
运行 log:
|
||||||
|
`artifacts/maplibre-particle/android-validation/step099-logcat.txt`
|
||||||
|
|
||||||
|
log SHA-256:
|
||||||
|
`0f15d75dde77e7dd2f4d98c46a4c1501a628205e8aae62130b0cb96db6b8482f`
|
||||||
|
|
||||||
|
## 7. T1~T4 实测
|
||||||
|
|
||||||
|
### T1 STATIC
|
||||||
|
|
||||||
|
场景:
|
||||||
|
|
||||||
|
- R0:静态 GeoJSON retained
|
||||||
|
- C:本地静态 RasterArray field 驱动 WeatherColor + Particle
|
||||||
|
- R1:静态 retained
|
||||||
|
- camera fixed
|
||||||
|
|
||||||
|
结果:
|
||||||
|
|
||||||
|
- 启动阶段 1 个 false window:204 ms;
|
||||||
|
- 随后 `renderOrchestratorLoaded=true` 稳定;
|
||||||
|
- `particle-fixture` 与 `step099-static` 均 loaded;
|
||||||
|
- retained cache 建立后持续 reuse;
|
||||||
|
- fast path 进入 `active=true / eligible=true / reason=none`;
|
||||||
|
- 没有持续 style-not-loaded。
|
||||||
|
|
||||||
|
aggregate:
|
||||||
|
|
||||||
|
```text
|
||||||
|
falseWindowCount=1
|
||||||
|
falseWindowAvgMs=204
|
||||||
|
falseWindowMaxMs=204
|
||||||
|
openFalseWindowMs=0
|
||||||
|
```
|
||||||
|
|
||||||
|
结论:静态基线可稳定进入 loaded/cache reuse/fast path。
|
||||||
|
|
||||||
|
### T2 GEOJSON_1HZ
|
||||||
|
|
||||||
|
两个 GeoJSON source 每 500 ms 交错更新,因此每个约 1 Hz。
|
||||||
|
|
||||||
|
实际:
|
||||||
|
|
||||||
|
- 总 source update:122 次,约 61 次/源;
|
||||||
|
- 60 秒量级观察中,出现 10 个 loaded=false window;
|
||||||
|
- 平均 203 ms;
|
||||||
|
- 最大 205 ms;
|
||||||
|
- 最终 open window = 0;
|
||||||
|
- 总 false 时间约 2.03 s,约占 60 s 的 3.4%,不是“几乎始终 false”。
|
||||||
|
|
||||||
|
aggregate:
|
||||||
|
|
||||||
|
```text
|
||||||
|
falseWindowCount=10
|
||||||
|
falseWindowAvgMs=203
|
||||||
|
falseWindowMaxMs=205
|
||||||
|
openFalseWindowMs=0
|
||||||
|
```
|
||||||
|
|
||||||
|
同时 final sample:
|
||||||
|
|
||||||
|
- global contentRevision 已到 1679;
|
||||||
|
- R0 仅依赖 `step099-static`,但 cache build=241、invalidation=362;
|
||||||
|
- R1 依赖动态 GeoJSON,也同样 build=241;
|
||||||
|
- mutation diagnostics 能正确指出动态 source 只 `affected=[2]`,但正式 cache invalidation 仍非局部。
|
||||||
|
|
||||||
|
### T3 PERMANENT_UNREADY
|
||||||
|
|
||||||
|
额外加入:
|
||||||
|
|
||||||
|
`step099-unready-raster-array`
|
||||||
|
|
||||||
|
它:
|
||||||
|
|
||||||
|
- 没有 layer;
|
||||||
|
- 因此 `enabled=false`;
|
||||||
|
- host-submission 无 field;
|
||||||
|
- `isLoaded=false`。
|
||||||
|
|
||||||
|
其他主要 source 均 loaded。
|
||||||
|
|
||||||
|
实测:
|
||||||
|
|
||||||
|
- `renderOrchestratorLoaded=false` 持续;
|
||||||
|
- retained segment cache 持续 fallback;
|
||||||
|
- `lastInvalidationReason=style-not-loaded`;
|
||||||
|
- 观察结束仍没有恢复。
|
||||||
|
|
||||||
|
aggregate:
|
||||||
|
|
||||||
|
```text
|
||||||
|
falseWindowCount=0
|
||||||
|
openFalseWindowMs=21459
|
||||||
|
```
|
||||||
|
|
||||||
|
结论:即使 source 与当前 layer/segment 无关且 disabled,只要仍在 `renderSources` 且 `isLoaded=false`,V17 全局 `RenderOrchestrator::isLoaded()` 就保持 false。
|
||||||
|
|
||||||
|
### T4 R-C-R
|
||||||
|
|
||||||
|
结构:
|
||||||
|
|
||||||
|
- R0:`deps=[step099-static]`
|
||||||
|
- C:`deps=[particle-fixture]`,WeatherColor + Particle
|
||||||
|
- R1:`deps=[org.maplibre.annotations, step099-dynamic, step099-static]`
|
||||||
|
- `step099-dynamic` 约 1 Hz 更新
|
||||||
|
|
||||||
|
实际:
|
||||||
|
|
||||||
|
- dynamic update:61 次;
|
||||||
|
- loaded false window:4;
|
||||||
|
- 平均 203 ms;
|
||||||
|
- 最大 207 ms;
|
||||||
|
- global contentRevision:1760 → 2540;
|
||||||
|
- mutation diagnostics:`step099-dynamic` 对应 `affected=[2]`;
|
||||||
|
- R0 并不依赖 `step099-dynamic`,但:
|
||||||
|
- build:1 → 121
|
||||||
|
- invalidation:20 → 200
|
||||||
|
- R1 同步得到相同级别 build/invalidation 增长;
|
||||||
|
- fast path 在稳定窗口可恢复 active,但 global revision / transient readiness 会反复制造 full CPU work。
|
||||||
|
|
||||||
|
aggregate:
|
||||||
|
|
||||||
|
```text
|
||||||
|
falseWindowCount=4
|
||||||
|
falseWindowAvgMs=203
|
||||||
|
falseWindowMaxMs=207
|
||||||
|
openFalseWindowMs=0
|
||||||
|
```
|
||||||
|
|
||||||
|
结论:依赖诊断已经能准确表达“R1 source-local”,但 V17 正式 content revision/cache invalidation 仍是 global。
|
||||||
|
|
||||||
|
## 8. Q1~Q7
|
||||||
|
|
||||||
|
### Q1:单个 permanently unloaded source 会造成 V17 style-not-loaded 吗?
|
||||||
|
|
||||||
|
**YES / CONFIRMED。**
|
||||||
|
|
||||||
|
T3 中 `step099-unready-raster-array` 无 layer、`enabled=false`、`isLoaded=false`;其他主要 source loaded,但整体 `renderOrchestratorLoaded=false` 持续 21.459 s 未恢复,retained cache 持续 `style-not-loaded` fallback。
|
||||||
|
|
||||||
|
源码事实与运行事实一致:`RenderOrchestrator::isLoaded()` 遍历全部 `renderSources`,不按 enabled/segment dependency 排除 source。
|
||||||
|
|
||||||
|
### Q2:1 Hz GeoJSON 会周期性让 isLoaded=false 吗?平均/最大窗口?
|
||||||
|
|
||||||
|
**YES / CONFIRMED。**
|
||||||
|
|
||||||
|
T2 双 source 交错各约 1 Hz:
|
||||||
|
|
||||||
|
- 10 次 false window;
|
||||||
|
- avg 203 ms;
|
||||||
|
- max 205 ms。
|
||||||
|
|
||||||
|
T4 单动态 source 约 1 Hz:
|
||||||
|
|
||||||
|
- 4 次 false window;
|
||||||
|
- avg 203 ms;
|
||||||
|
- max 207 ms。
|
||||||
|
|
||||||
|
### Q3:错开的多个 1 Hz GeoJSON 会导致 global loaded 几乎无法稳定为 true 吗?
|
||||||
|
|
||||||
|
**NO / 本次观测不支持。**
|
||||||
|
|
||||||
|
T2 约 60 s 中总 false 时间约 2.03 s,约 3.4%;绝大多数时间 global loaded=true。它确实产生 readiness thrash,但不是“几乎永远 false”。
|
||||||
|
|
||||||
|
### Q4:GeoJSON tile mutation 会推进 global retainedUnderlayContentRevision 并影响 retained cache 吗?
|
||||||
|
|
||||||
|
**YES / CONFIRMED。**
|
||||||
|
|
||||||
|
T4 global contentRevision 1760 → 2540。仅依赖静态 source 的 R0 也从 build 1 → 121、invalidation 20 → 200。
|
||||||
|
|
||||||
|
### Q5:不引用 GeoJSON 的 retained segment 仍会受它的 loaded/fading/tile mutation 影响吗?
|
||||||
|
|
||||||
|
**YES。**
|
||||||
|
|
||||||
|
运行证据:
|
||||||
|
|
||||||
|
- T4 diagnostics 正确报告动态 source `affected=[2]`;
|
||||||
|
- 但 R0 `deps=[step099-static]` 仍随动态 source mutation 重建/失效。
|
||||||
|
|
||||||
|
源码证据:
|
||||||
|
|
||||||
|
- `retainedRangeIsStable(begin,end)` 虽为 range API,但最后遍历 **全部 `renderSources`**,任一 source `hasFadingTiles()` 都让任意 retained range unstable。
|
||||||
|
|
||||||
|
本次 T4 稳态 `fade=false`,因此 R0 的实际反复失效主要直接证明 global content revision/tile mutation;GLOBAL_FADE 属源码确认、未在本轮场景主动触发的全局 gate。
|
||||||
|
|
||||||
|
### Q6:`tryRenderParticleFastFrame` 仍有哪些 global gate 会阻挡未来 localized cache CPU fast path?
|
||||||
|
|
||||||
|
**确认仍存在:**
|
||||||
|
|
||||||
|
1. **GLOBAL_UPDATE_SIGNATURE**
|
||||||
|
- `particleFastPathNonCameraInputsMatch` 全局比较:
|
||||||
|
- styleLoaded / spriteLoaded
|
||||||
|
- light
|
||||||
|
- images
|
||||||
|
- **sources**
|
||||||
|
- **layers**
|
||||||
|
- fontFaces / fileSource / glyphURL
|
||||||
|
- transition / placement / tile LOD 等全局输入。
|
||||||
|
|
||||||
|
2. **GLOBAL_CONTENT_REVISION**
|
||||||
|
- `particlePreparedContentRevision == orchestrator.getRetainedUnderlayContentRevision()`。
|
||||||
|
|
||||||
|
3. **GLOBAL_FADE**
|
||||||
|
- `particleFastPathDynamicState` 遍历全部 renderSources 汇总 fading;
|
||||||
|
- `retainedRangeIsStable` 也遍历全部 renderSources。
|
||||||
|
|
||||||
|
4. **GLOBAL_PENDING / TRANSITION / REPAINT**
|
||||||
|
- pendingChanges
|
||||||
|
- renderLight transition
|
||||||
|
- 任意 layer transition
|
||||||
|
- 任意非粒子 layer repaint
|
||||||
|
- placement transition。
|
||||||
|
|
||||||
|
5. **GLOBAL_ANNOTATION_MUTATION**
|
||||||
|
- AnnotationManager `hasPendingChanges()`。
|
||||||
|
|
||||||
|
6. **RETAINED REVISION / CACHE / TOPOLOGY / BOUNDARY**
|
||||||
|
- retained cache validity/static revision
|
||||||
|
- global retained revision tracker
|
||||||
|
- topology revision
|
||||||
|
- boundary/config revision。
|
||||||
|
|
||||||
|
7. **singleContinuousSegment**
|
||||||
|
- 仍要求 plan 恰好能由一个 Continuous segment 表达;
|
||||||
|
- multi-continuous 继续 fail closed,本 Step 未修改。
|
||||||
|
|
||||||
|
因此即使未来 cache invalidation 变成 source/segment-local,fast path 仍有多组 global gate 需要后续 Step 单独设计,不能在 STEP-099 顺手放宽。
|
||||||
|
|
||||||
|
### Q7:blocker 分类
|
||||||
|
|
||||||
|
**运行态 CONFIRMED:**
|
||||||
|
|
||||||
|
- `PERMANENT_SOURCE_UNLOADED`
|
||||||
|
- `DYNAMIC_SOURCE_READINESS_THRASH`
|
||||||
|
- `GLOBAL_CONTENT_REVISION`
|
||||||
|
|
||||||
|
**源码 CONFIRMED,本轮未主动触发独立运行场景:**
|
||||||
|
|
||||||
|
- `GLOBAL_FADE`
|
||||||
|
- `GLOBAL_UPDATE_SIGNATURE`
|
||||||
|
|
||||||
|
**OTHER:**
|
||||||
|
|
||||||
|
- global pendingChanges
|
||||||
|
- placement/light/non-particle transition/repaint
|
||||||
|
- annotation mutation
|
||||||
|
- topology/boundary/revision/cache validity
|
||||||
|
- singleContinuous fail-closed
|
||||||
|
|
||||||
|
## 9. 任务边界审计
|
||||||
|
|
||||||
|
确认未改:
|
||||||
|
|
||||||
|
- retained cache 核心算法;
|
||||||
|
- fast path gate 逻辑;
|
||||||
|
- `singleContinuousSegment`;
|
||||||
|
- multi-continuous 策略;
|
||||||
|
- segment-local invalidation 正式语义;
|
||||||
|
- RenderSegment execution;
|
||||||
|
- NavSea;
|
||||||
|
- private NavSea Native API;
|
||||||
|
- RN 业务 API;
|
||||||
|
- Source `isLoaded()` 定义。
|
||||||
|
|
||||||
|
新增 dependency / affectedSegmentIndices 只是观察信息;它没有参与正式 invalidation。
|
||||||
|
|
||||||
|
## 10. 证据文件
|
||||||
|
|
||||||
|
忽略目录:
|
||||||
|
|
||||||
|
`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`
|
||||||
|
- `step099-cmake-metal.log`
|
||||||
|
|
||||||
|
APK SHA-256:
|
||||||
|
|
||||||
|
`5de73f0358b835a78d3ae7e2ac22f4efdb2a66775b8c63654a8bb7313957d90a`
|
||||||
|
|
||||||
|
STEP-099 log SHA-256:
|
||||||
|
|
||||||
|
`0f15d75dde77e7dd2f4d98c46a4c1501a628205e8aae62130b0cb96db6b8482f`
|
||||||
|
|
||||||
|
## 11. 下一阶段建议
|
||||||
|
|
||||||
|
STEP-099 只负责定位,不在本 Step 修复。
|
||||||
|
|
||||||
|
下一阶段应基于本轮证据拆开处理:
|
||||||
|
|
||||||
|
1. 先决定 global source readiness 是否要引入“影响当前 style/render segment 的 readiness 范围”,解决 permanently unready / transient unrelated source 对全局 loaded 的影响;
|
||||||
|
2. 再设计 source/segment-local content revision 与 invalidation,避免 R1 GeoJSON mutation 重建 R0;
|
||||||
|
3. 最后单独审查 fast-path global signature/fade/pending/placement 等 gate,不能把 cache locality 与 fast-path locality 混成一个修改;
|
||||||
|
4. 保持 Style Z-order 唯一事实来源和当前通用 Render Segment 模型。
|
||||||
|
|
||||||
|
## 12. 最终状态
|
||||||
|
|
||||||
|
**STEP-099 CLOSED / PASS。**
|
||||||
|
|
||||||
|
Pass 含义仅为:
|
||||||
|
|
||||||
|
- diagnostics 能回答任务问题;
|
||||||
|
- Native 定向测试已有 PASS 证据;
|
||||||
|
- 最终 Android x86_64 OpenGL APK BUILD SUCCESS;
|
||||||
|
- FZG1-2 T1~T4 实跑完成;
|
||||||
|
- Q1~Q7 有源码/运行证据;
|
||||||
|
- 未改变正式渲染语义。
|
||||||
|
|
||||||
|
不代表:
|
||||||
|
|
||||||
|
- Vulkan host 已通过;
|
||||||
|
- iOS runtime 已测试;
|
||||||
|
- 下一阶段 localized readiness/invalidation 已实现;
|
||||||
|
- fast path global gates 已优化。
|
||||||
10
粒子开发记录.md
10
粒子开发记录.md
@@ -1022,3 +1022,13 @@ Android V3-08 单次综合验收已完成并关闭。Native `13.4.1-particle.2`
|
|||||||
|
|
||||||
- 统一发行 Android 四 ABI 和 Maven Local 通过;首次 iOS Metal Bazel 在 render_weather_color_layer.cpp 编译时找不到新增 WeatherColor lifecycle 头文件。
|
- 统一发行 Android 四 ABI 和 Maven Local 通过;首次 iOS Metal Bazel 在 render_weather_color_layer.cpp 编译时找不到新增 WeatherColor lifecycle 头文件。
|
||||||
- 在 bazel/core.bzl 的 MLN_CORE_HEADERS 精确登记该头文件;保留 WeatherColor 业务实现不变。由 RDC 重跑完整 v16 构建、公开回读,iPad 人工验收仍待执行。
|
- 在 bazel/core.bzl 的 MLN_CORE_HEADERS 精确登记该头文件;保留 WeatherColor 业务实现不变。由 RDC 重跑完整 v16 构建、公开回读,iPad 人工验收仍待执行。
|
||||||
|
|
||||||
|
### 2026-10-06 STEP-099 RenderSource readiness 与 RenderSegment 失效诊断(CLOSED / PASS)
|
||||||
|
|
||||||
|
- frozen release 为 `maplibre-particle/rn/13.4.1-particle.17` / `e8b451fe70054107773e82484c80e90df3889147`;implementation commit 为 `8a5214d92dd2f8899db76d2194da42999fa0c87d`。未修改 Integration/NavSea。
|
||||||
|
- 完成 renderer/source readiness additive snapshot、tile stats、mutation source/tile action、只读 source→segment dependency 与 Android T1~T4。正式 `renderTreeParameters->loaded = styleLoaded && isLoaded()`、Source `isLoaded()`、retained cache、fast path、singleContinuous、多 Continuous 和 RenderSegment execution 均未改变。
|
||||||
|
- Metal host `RenderSegmentDiagnostics.*` 6/6 PASS;最终 Android x86_64 OpenGL APK BUILD SUCCESSFUL in 4m54s,APK 61,923,024 bytes,SHA-256 `5de73f0358b835a78d3ae7e2ac22f4efdb2a66775b8c63654a8bb7313957d90a`。Vulkan/最终 Metal rerun 因当前 Mac 缺 libuv pkg-config 未执行,不虚报 PASS。
|
||||||
|
- FZG1-2 / Android 13 / API33 实跑:T1 静态仅 1 个 204ms 启动 false window 后稳定;T2 双 GeoJSON 各约 1Hz,10 个 false window、avg 203ms、max 205ms;T3 无 layer 的 disabled RasterArray 仍 isLoaded=false,使 global loaded 持续 false 21.459s;T4 61 次动态更新产生 4 个 false window、avg 203ms、max 207ms。
|
||||||
|
- T4 证实 dependency diagnostics 能正确给动态 source `affected=[2]`,但 global contentRevision 1760→2540,R0 虽只依赖 `step099-static`,cache build 仍 1→121、invalidation 20→200,确认 `GLOBAL_CONTENT_REVISION`。源码审计同时确认 global fade/update signature/pending/placement/repaint/annotation/singleContinuous 等 fast-path gate 仍存在。
|
||||||
|
- Q1~Q7 与 blocker 分类已闭合:runtime confirmed `PERMANENT_SOURCE_UNLOADED`、`DYNAMIC_SOURCE_READINESS_THRASH`、`GLOBAL_CONTENT_REVISION`;source confirmed `GLOBAL_FADE`、`GLOBAL_UPDATE_SIGNATURE`。
|
||||||
|
- 完成报告:`docs/报告/STEP-099_RenderSource就绪与RenderSegment失效诊断_Codex完成报告_v1.md`;Step:`docs/50_Step记录/STEP-099_RenderSource就绪与RenderSegment失效诊断_v1.md`;运行证据保存在忽略目录 `artifacts/maplibre-particle/android-validation/`。
|
||||||
|
|||||||
Reference in New Issue
Block a user