fix: localize retained segment source invalidation
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:
454
docs/报告/STEP-100_SourceScoped_RenderSegment局部失效_Codex完成报告_v1.md
Normal file
454
docs/报告/STEP-100_SourceScoped_RenderSegment局部失效_Codex完成报告_v1.md
Normal file
@@ -0,0 +1,454 @@
|
||||
# STEP-100 SourceScoped RenderSegment 局部失效 — 完成报告 v1
|
||||
|
||||
## 1. 最终结论
|
||||
|
||||
**CLOSED / PASS(功能与 Android 运行态目标确认)**。
|
||||
|
||||
Codex 实现使用:
|
||||
- model:`gpt-6-sol`
|
||||
- reasoning effort:`high`
|
||||
|
||||
RDC 独立完成:
|
||||
- 源码 diff 审计;
|
||||
- Android x86_64 OpenGL 全量 native build;
|
||||
- Validation APK;
|
||||
- FZG1-2 自动安装与 T1/T2/T3/T4;
|
||||
- STEP-100 60 秒 locality window;
|
||||
- validation build script 小型工程修复;
|
||||
- Git diff/status 审计。
|
||||
|
||||
本 Step 核心目标已确认:
|
||||
|
||||
> 动态 GeoJSON Source 更新只影响依赖它的 RETAINED Segment;无关 R0 cache 不再跟着 invalid/rebuild,并且在 global loaded=false 时仍可安全 reuse。
|
||||
|
||||
Native host GTest 因当前 Intel Mac 缺 `libuv` 未执行;曾尝试 Homebrew 安装,但 Homebrew 要连带升级 CMake/OpenSSL/Python 且 Intel 已无 bottle 支持,因此 RDC 主动终止,未把环境变化作为任务依赖。Android 最终 C++ native build 与设备运行态用于本轮功能验收。
|
||||
|
||||
Jest:**NOT RUN**,用户未要求。
|
||||
|
||||
## 2. Git / 基线
|
||||
|
||||
- worktree:`/Users/tei/dev/MapLibreParticleLab-step100`
|
||||
- branch:`step100-segment-local-source-invalidation`
|
||||
- start HEAD:`c4b481fd2c5b5da20d31f6ae54011f0552d7dbd0`
|
||||
- start remote:`origin/particle/main = c4b481fd2c5b5da20d31f6ae54011f0552d7dbd0`
|
||||
- frozen V17 tag:`maplibre-particle/rn/13.4.1-particle.17`
|
||||
- frozen V17 commit:`e8b451fe70054107773e82484c80e90df3889147`
|
||||
- V17 tag/release worktree:未修改。
|
||||
|
||||
最终 STEP-100 commit / push / remote HEAD 在 Git 收尾后由最终交付回读记录,避免文档自引用。
|
||||
|
||||
## 3. 实际修改
|
||||
|
||||
生产源码:
|
||||
|
||||
- `include/mbgl/renderer/render_segment.hpp`
|
||||
- `src/mbgl/renderer/render_orchestrator.hpp`
|
||||
- `src/mbgl/renderer/render_orchestrator.cpp`
|
||||
- `src/mbgl/renderer/renderer_impl.cpp`
|
||||
- `src/mbgl/renderer/retained_underlay_cache.cpp`
|
||||
- `src/mbgl/renderer/retained_underlay_runtime_state.hpp`
|
||||
- `src/mbgl/renderer/render_segment_json.hpp`
|
||||
- `packages/maplibre-particle-rn/src/types.ts`
|
||||
|
||||
Test App / tests:
|
||||
|
||||
- `platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/particle/Step099ReadinessFixture.kt`
|
||||
- `platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/particle/ParticleCoreLayerValidationActivity.kt`
|
||||
- `test/renderer/retained_underlay_cache.test.cpp`
|
||||
|
||||
工具:
|
||||
|
||||
- `tools/particle_android_validation/build_validation_apk.sh`
|
||||
- RDC 修复 `unzip | awk ... exit` 在 `pipefail` 下偶发 SIGPIPE/141;
|
||||
- 仅移除 awk 的提前 exit,不改变 APK 验证语义。
|
||||
|
||||
文档:
|
||||
|
||||
- `docs/40_任务/STEP-100_SourceScoped_RenderSegment局部失效_Codex任务_v2.md`
|
||||
- `docs/50_Step记录/STEP-100_SourceScoped_RenderSegment局部失效_v1.md`
|
||||
- 本报告;
|
||||
- `粒子开发记录.md`
|
||||
|
||||
## 4. 生产设计
|
||||
|
||||
### 4.1 Source-scoped revision
|
||||
|
||||
新增正式 source-scoped revision bookkeeping。
|
||||
|
||||
明确的 Source/Tile mutation:
|
||||
- source diff;
|
||||
- feature state;
|
||||
- tile changed;
|
||||
|
||||
推进对应 sourceId revision。
|
||||
|
||||
现有 global `retainedUnderlayContentRevision` 继续增长,供:
|
||||
- compatibility;
|
||||
- diagnostics;
|
||||
- Fast Path fail-closed。
|
||||
|
||||
RETAINED Segment cache 不再直接以 global Source/Tile revision 作为内容 revision。
|
||||
|
||||
### 4.2 Segment dependency
|
||||
|
||||
正式 renderer 与 diagnostics 共用 source→segment 依赖推导。
|
||||
|
||||
规则:
|
||||
- layer sourceId 决定 source dependency;
|
||||
- source-less background 不制造假 dependency;
|
||||
- shared source 可影响多个 segment;
|
||||
- symbol 的 glyph/image/placement 作为明确 global prerequisite;
|
||||
- 真正无法证明的 dependency fail closed。
|
||||
|
||||
### 4.3 Per-segment readiness
|
||||
|
||||
未修改:
|
||||
- `Source::isLoaded()`;
|
||||
- `renderTreeParameters->loaded = styleLoaded && isLoaded()`。
|
||||
|
||||
full CPU retained path 增加 per-segment source readiness/stability:
|
||||
|
||||
- dependent source unloaded → 仅该 Segment fallback;
|
||||
- dependent source fading → 仅该 Segment unstable;
|
||||
- unrelated source unloaded/fading → 不影响该 Segment;
|
||||
- style/image/sprite/glyph/placement/context 等 global prerequisite 仍 fail closed。
|
||||
|
||||
### 4.4 Mixed Build / Reuse / Fallback
|
||||
|
||||
移除 retained full-CPU path 的 all-or-none `useRetainedRanges` 依赖。
|
||||
|
||||
每个 RETAINED Segment独立决定:
|
||||
|
||||
- Build
|
||||
- Reuse
|
||||
- Fallback
|
||||
|
||||
主 buffer 按 Style Segment 顺序执行:
|
||||
|
||||
- RETAINED Build/Reuse → composite cache
|
||||
- RETAINED Fallback → live render only that range
|
||||
- CONTINUOUS → live render
|
||||
|
||||
因此允许:
|
||||
|
||||
```text
|
||||
R0 = Reuse
|
||||
C = Live
|
||||
R1 = Fallback
|
||||
```
|
||||
|
||||
不再因为 R1 fallback 把 R0 一起变成 live redraw。
|
||||
|
||||
Fast Path gate / `singleContinuousSegment` / multi-continuous Fast Path:**未修改**。
|
||||
|
||||
## 5. Android build
|
||||
|
||||
首次标准 validation script 的 Gradle 本体实际结果:
|
||||
|
||||
```text
|
||||
BUILD SUCCESSFUL in 12s
|
||||
86 actionable tasks: 6 executed, 80 up-to-date
|
||||
```
|
||||
|
||||
但脚本在 Gradle 成功后以 141 退出。RDC 用 `bash -x` 精确定位到:
|
||||
|
||||
```bash
|
||||
LIB_BYTES="$(unzip ... | awk '/.../ {print $1; exit}')"
|
||||
```
|
||||
|
||||
在 `set -o pipefail` 下触发 SIGPIPE。
|
||||
|
||||
RDC 仅去掉 awk 的 `exit`,重跑标准脚本:
|
||||
|
||||
```text
|
||||
RC=0
|
||||
[validation-apk] BUILD SUCCESS
|
||||
```
|
||||
|
||||
最终 APK:
|
||||
|
||||
- variant:OpenglDebug
|
||||
- ABI:x86_64
|
||||
- apk bytes:61,956,640
|
||||
- libmaplibre.so bytes:39,636,472
|
||||
- SHA-256:
|
||||
`86e22bf081bf7d3196f0bf0e7c56af51bde01e9f0b01e0bab238cb794273315a`
|
||||
|
||||
证据:
|
||||
`artifacts/maplibre-particle/android-validation/`
|
||||
|
||||
## 6. 设备
|
||||
|
||||
- serial:`192.168.200.139:5555`
|
||||
- model:FZG1-2
|
||||
- Android:13
|
||||
- API:33
|
||||
- ABI:x86_64
|
||||
|
||||
APK 覆盖安装成功,`ParticleCoreLayerValidationActivity` 冷启动成功。
|
||||
|
||||
STEP-100 log:
|
||||
`artifacts/maplibre-particle/android-validation/step100-logcat.txt`
|
||||
|
||||
log SHA-256:
|
||||
`e9d18ea987d12cb30e321d0d9c669b2588972aac89e5277920bf1fa9fee8146b`
|
||||
|
||||
## 7. T1 STATIC
|
||||
|
||||
运行约 20 秒。
|
||||
|
||||
aggregate:
|
||||
|
||||
```text
|
||||
falseWindowCount=1
|
||||
falseWindowAvgMs=203
|
||||
falseWindowMaxMs=203
|
||||
openFalseWindowMs=0
|
||||
```
|
||||
|
||||
最终:
|
||||
|
||||
- R0 build=1
|
||||
- R0 reuse=1217
|
||||
- R0 decision=reuse
|
||||
- R1 build=1
|
||||
- R1 reuse=1187
|
||||
- R1 decision=reuse
|
||||
|
||||
静态 R-C-R 正常。
|
||||
|
||||
## 8. T4 R-C-R 主验收
|
||||
|
||||
结构:
|
||||
|
||||
```text
|
||||
R0 -> step099-static
|
||||
C -> particle-fixture
|
||||
R1 -> step099-dynamic (+ framework annotation source if present)
|
||||
```
|
||||
|
||||
window marker:
|
||||
|
||||
```text
|
||||
baseline tick=8 17:05:21.642
|
||||
final tick=130 17:06:23.240
|
||||
```
|
||||
|
||||
窗口约 61.6 秒。
|
||||
|
||||
dynamic update 总计:68 次。
|
||||
|
||||
global revision:
|
||||
|
||||
```text
|
||||
128 -> 973
|
||||
```
|
||||
|
||||
说明 global compatibility revision **仍正常增长**,没有通过停掉 global revision“作弊”。
|
||||
|
||||
### R0
|
||||
|
||||
baseline:
|
||||
|
||||
```text
|
||||
build=1
|
||||
reuse=132
|
||||
invalidation=20
|
||||
srcRev=5127273714767523329
|
||||
decision=reuse
|
||||
```
|
||||
|
||||
final:
|
||||
|
||||
```text
|
||||
build=1
|
||||
reuse=4042
|
||||
invalidation=20
|
||||
srcRev=5127273714767523329
|
||||
decision=reuse
|
||||
```
|
||||
|
||||
Delta:
|
||||
|
||||
```text
|
||||
buildDelta = 0
|
||||
invalidationDelta = 0
|
||||
reuseDelta = +3910
|
||||
sourceRevision = unchanged
|
||||
```
|
||||
|
||||
**硬门槛 PASS。**
|
||||
|
||||
### R1
|
||||
|
||||
baseline:
|
||||
|
||||
```text
|
||||
build=5
|
||||
invalidation=26
|
||||
```
|
||||
|
||||
final:
|
||||
|
||||
```text
|
||||
build=135
|
||||
invalidation=211
|
||||
```
|
||||
|
||||
动态 Source mutation 正常驱动 R1。
|
||||
|
||||
mutation diagnostics 持续:
|
||||
|
||||
```text
|
||||
sourceId=step099-dynamic
|
||||
affected=[2]
|
||||
scope=source-local-diagnostic
|
||||
```
|
||||
|
||||
### loaded false windows
|
||||
|
||||
T4:
|
||||
|
||||
```text
|
||||
falseWindowCount=5
|
||||
falseWindowAvgMs=202
|
||||
falseWindowMaxMs=203
|
||||
openFalseWindowMs=0
|
||||
```
|
||||
|
||||
即 transient global loaded=false 仍存在,但不再让 R0 build/invalidation 增长。
|
||||
|
||||
## 9. T2 双 GeoJSON readiness 回归
|
||||
|
||||
约 35 秒。
|
||||
|
||||
aggregate:
|
||||
|
||||
```text
|
||||
falseWindowCount=6
|
||||
falseWindowAvgMs=203
|
||||
falseWindowMaxMs=205
|
||||
openFalseWindowMs=0
|
||||
```
|
||||
|
||||
R0 在动态窗口保持:
|
||||
|
||||
- build=1
|
||||
- invalidation=18
|
||||
- revision unchanged
|
||||
- reuse 持续增长。
|
||||
|
||||
R1 随两个动态 GeoJSON 持续 build/invalidate。
|
||||
|
||||
结论:
|
||||
**DYNAMIC_SOURCE_READINESS_THRASH 仍是 global loaded 事实,但不再误伤无关 retained cache。**
|
||||
|
||||
## 10. T3 permanently unready unrelated source
|
||||
|
||||
`step099-unready-raster-array`:
|
||||
|
||||
- no layer;
|
||||
- enabled=false;
|
||||
- isLoaded=false。
|
||||
|
||||
global:
|
||||
|
||||
```text
|
||||
renderOrchestratorLoaded=false
|
||||
openFalseWindowMs=21468
|
||||
```
|
||||
|
||||
约 21.468 秒持续 false。
|
||||
|
||||
与此同时:
|
||||
|
||||
R0:
|
||||
- build=1
|
||||
- invalidation=19
|
||||
- reuse:11 → 1200
|
||||
- decision=reuse
|
||||
|
||||
R1:
|
||||
- build=1
|
||||
- invalidation=19
|
||||
- reuse:11 → 1200
|
||||
- decision=reuse
|
||||
|
||||
因此:
|
||||
|
||||
> global loaded 仍保持旧兼容语义,但 unrelated permanently-unready source 已不能把无关 RETAINED Segment 拖成 style-not-loaded fallback。
|
||||
|
||||
**硬门槛 PASS。**
|
||||
|
||||
## 11. Mixed fallback
|
||||
|
||||
T4 中 R1 `fallbackCount` 从约 21 增长到 76,而 R0 fallback 计数保持不变,同时 R0 reuse 持续增长。
|
||||
|
||||
这证明运行期间真实发生了:
|
||||
|
||||
```text
|
||||
R0 = Reuse
|
||||
R1 = transient Fallback / rebuild
|
||||
```
|
||||
|
||||
而不是只有“两个段都 ready”的理想场景。
|
||||
|
||||
未观察到 crash / ANR。
|
||||
|
||||
## 12. Fast Path 边界
|
||||
|
||||
RDC diff 审计确认未修改:
|
||||
|
||||
- `tryRenderParticleFastFrame`
|
||||
- `particleFastPathNonCameraInputsMatch`
|
||||
- `singleContinuousSegment`
|
||||
- multi-continuous fail-closed
|
||||
- global Fast Path signature/fade/contentRevision/pending/placement 等 gate。
|
||||
|
||||
STEP-100 只修 full CPU retained locality。
|
||||
|
||||
## 13. Native host tests
|
||||
|
||||
Codex 已新增 `RenderSegmentLocality.*` C++ 测试源码。
|
||||
|
||||
RDC 尝试恢复 `macos-metal` test runner,但 host configure 需要 `libuv`,当前未安装。
|
||||
|
||||
尝试 `brew install libuv` 时发现 Intel Homebrew 会连带升级:
|
||||
- CMake
|
||||
- OpenSSL
|
||||
- Python
|
||||
- ca-certificates 等
|
||||
|
||||
且当前 Intel macOS 已无官方 bottle 支持。为避免污染开发环境,RDC 主动停止。
|
||||
|
||||
因此:
|
||||
|
||||
- Native host GTest:**ENV BLOCKED / NOT RUN**
|
||||
- Android C++ full native build:**PASS**
|
||||
- Android device runtime:**PASS**
|
||||
|
||||
## 14. Jest / iOS
|
||||
|
||||
- Jest:NOT RUN。
|
||||
- iOS runtime:本 Step 未运行。
|
||||
- V18 unified release:在 STEP-100 Git 收尾后单独执行。
|
||||
|
||||
## 15. 最终判定
|
||||
|
||||
STEP-100 的核心实现目标全部成立:
|
||||
|
||||
1. global revision 继续增长;
|
||||
2. R1 GeoJSON mutation 不再 invalid/rebuild R0;
|
||||
3. R0 buildDelta=0;
|
||||
4. R0 invalidationDelta=0;
|
||||
5. R0 reuseDelta>0;
|
||||
6. transient unrelated unloaded 不影响 R0 reuse;
|
||||
7. permanent unrelated unloaded 不影响 R0 reuse;
|
||||
8. mixed Reuse/Fallback 实际发生;
|
||||
9. Fast Path 语义未放宽。
|
||||
|
||||
因此本 Step 功能与 Android runtime 验收:
|
||||
|
||||
**PASS / CLOSED**。
|
||||
|
||||
下一步允许进入 V18 unified release。
|
||||
Reference in New Issue
Block a user