122 lines
12 KiB
Markdown
122 lines
12 KiB
Markdown
# STEP-102 RenderSegment 无 Placement 段局部复用 Codex 完成报告 v1
|
||
|
||
## 1. 执行结论
|
||
|
||
**代码完成,等待独立构建与运行验证;STEP-102 尚非 PASS。** 已按任务书实现 full CPU placement-free Retained Segment 局部复用、逐段 fallback reason 和实际 main-buffer 执行诊断。C++ 与 Android 测试均只交付源码,未运行。没有编译、设备或视觉结果,不能据此宣称无 stale、Z-order 错乱或 crash。
|
||
|
||
## 2. Git 基线与工作树
|
||
|
||
- 工作区:`/Users/tei/dev/MapLibreParticleLab-step102`
|
||
- 当前机器:macOS 15.7.7 / Darwin x86_64;未连接或操作设备。
|
||
- 分支:`step102-placement-free-retained-locality`
|
||
- start HEAD:`6df21dac38f072c5ad35b8dfc7ec5217509602bc`
|
||
- end HEAD:仍为 `6df21dac38f072c5ad35b8dfc7ec5217509602bc`;本阶段未 commit、push、merge。
|
||
- 子模块:`git submodule status` 均以 `-` 开头,本 worktree 未初始化;未更改。
|
||
- 工作树:仅下列任务文件有本阶段差异;任务开始时已经未跟踪的 v2/v3 审查说明及 STEP-102 任务书未修改、未暂存。
|
||
- V19/V20 release worktree、`particle/main`、tag 与发布坐标未修改;无新 artifact。
|
||
|
||
## 3. 实际修改与新增文件
|
||
|
||
生产代码:
|
||
|
||
1. `include/mbgl/renderer/render_segment.hpp`:结构查询、placement gate、全局 live reason 辅助函数及 diagnostics 字段。
|
||
2. `src/mbgl/renderer/render_orchestrator.hpp`、`src/mbgl/renderer/render_orchestrator.cpp`:对 full CPU 提供结构查询和 placement transition 查询;旧动态查询保持原样。
|
||
3. `src/mbgl/renderer/renderer_impl.cpp`:逐段 gate/fallback、全局 live reason、实际执行记录。
|
||
4. `src/mbgl/renderer/retained_underlay_runtime_state.hpp`、`src/mbgl/renderer/render_segment_json.hpp`:只读快照与 JSON 字段。
|
||
5. `packages/maplibre-particle-rn/src/types.ts`:现有 diagnostics 返回类型 additive 扩展。
|
||
|
||
测试/Validation:
|
||
|
||
6. `test/renderer/retained_underlay_cache.test.cpp`:新增 `RenderSegmentPlacementFree.*` C++ 测试源码。
|
||
7. `platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/particle/ParticleCoreLayerValidationActivity.kt`:STEP-102 场景菜单、Intent 入口、轮询及审计日志。
|
||
8. 新增 `platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/particle/Step102PlacementFixture.kt`:离线 R-C-R symbol/placement-free 两组 fixture。
|
||
|
||
文档:新增 `docs/50_Step记录/STEP-102_RenderSegment无Placement段局部复用_v1.md`、本报告;追加 `粒子开发记录.md`。
|
||
|
||
## 4. 实现与任务书逐项对照
|
||
|
||
- **结构能力**:扫描同一 style-layer 元数据中的 `layerType == "symbol"`;越界 range 返回 placement-capable 以 fail-closed。`retainedRangeUsesPlacement()` 的 `needsPlacement()` 动态语义未变。custom/custom-drawable 仍由原 unsupported gate 处理。
|
||
- **逐段 gate**:placement-free 返回通过;placement-bearing 要求 `!placementChanged && symbolFadeChange == 0 && !placementTransitionActive`。`symbolFadeChange==0` 只是沿用保守 gate 的条件,不命名为严格 stable。transition disabled 且 fade=1 仍不能让含 symbol 段复用。
|
||
- **逐段 fallback**:优先明确 source、global resource、placement、layer transition、legacy/unsupported 等本段理由。`static-placement` 只会由本段 gate 失败产生;不再拷贝 aggregate placement/transition 理由给邻段。
|
||
- **full CPU main-buffer**:全局 live 条件只删掉 aggregate `!retainedPlacementStable`,其他既有 3D、debug、非 Continuous MapMode、sprite、global resources、light transition 条件保留。原 `visitRenderSegmentExecution()` 和 Style 顺序不变。camera/viewport/pixelRatio、topology、content/global revision、resource/compositor failure 的原有失效路径未放宽。
|
||
- **兼容/安全边界**:aggregate `retainedStaticUsesPlacement`、`retainedPlacementStable`、prepared-tree/Fast Path eligibility 与 revision 观察继续原用;含 symbol 的 retained 仍 fail-closed;C-001、RN method surface、`setRenderSegmentPlan()` 输入未变。
|
||
|
||
与 v3 审查设计无架构差异。逐段 gate 额外显式查询当前 placement transition,属于对 placement-bearing 的更保守判定;原 `retainedSegmentIsStable()` 内仍保留既有 transition 检查。测试和 Android 场景均不修改 Placement 核心算法。
|
||
|
||
## 5. diagnostics 字段与真实执行语义
|
||
|
||
每段新增 `placementCapable`、`placementGatePassed`、`actualExecution`。前者来自 style-layer 结构,第二项表示本帧 full CPU placement cache gate;Continuous 段的 gate 为非阻塞值。`actualExecution` 在 main-buffer 全局 live 分支或 mixed executor 的 composite 回调实际发生后记录。即使 `cache.finalDecision=reuse`,全局门槛触发时仍记录 `actualExecution=live`。
|
||
|
||
全局新增 `placementChanged`、`symbolFadeChange`、`placementTransitionActive`、`crossSourceCollisions`、`mainBufferExecutionMode`、`globalLiveFallbackReason`。`mixed` 表示进入 Style 顺序的 mixed executor,可以包含某些 Retained live;`global-live` 表示整帧 live 分支。尚未渲染时 `mainBufferExecutionMode/actualExecution=not-rendered`。查询只拷贝已记录快照,不推进 revision;Android/iOS Shared Core 使用同一 JSON writer,RN TS 只补类型。
|
||
|
||
## 6. 测试源码覆盖矩阵
|
||
|
||
| 合同场景 | 新增/现有测试源码 | 尚待运行证明 |
|
||
| --- | --- | --- |
|
||
| A:R0 free、C live、R1 symbol live;Style 顺序 | `RenderSegmentPlacementFree.MixedExecutionKeepsFreeRangesInStyleOrder` | Android T1 真实 GPU composite/live 与视觉 Z-order |
|
||
| B:symbol 当前 placementData 为空仍 capable | `StructuralCapabilityAndConservativeGate` 直接输入 symbol style 结构,不依赖 placementData | Android 空 bucket/placementData 条件仍需设备审计 |
|
||
| C:两个 free Retained 复用 | `MixedExecutionKeepsFreeRangesInStyleOrder` 中 R0/R2;Android T2 | 60 秒 build/reuse/invalidation 窗口 |
|
||
| D:source-local unloaded/fading/mutation | 既有 `RenderSegmentLocality.ReadinessAndFadeFollowOnlyDependencies` 与本轮两 free cache 断言;Android T1 动态 symbol source | 设备 R0 计数不误增 |
|
||
| E:bearing 保守 gate | `StructuralCapabilityAndConservativeGate` changed/fade=1/transition 活跃组合 | transition disabled 场景的 GPU 行为 |
|
||
| F:真实全局门槛 | `RealGlobalGatesStillForceGlobalLive`;既有 revision/cache tests | style/context/image/glyph/light 等设备失效 |
|
||
| G:拓扑与 key | `TopologyAndCameraChangesCannotReuseOldRetainedKey`;既有 `OldCacheReleaseCannotChargeReplacementAtSameIndex` | 真正 GPU resource 释放及无 stale texture |
|
||
| H:reuse 但 global-live | `DiagnosticsRecordActualMainBufferAndDoNotMutateOnRead` | 设备日志中 cache/actual 分离 |
|
||
|
||
测试源码只验证可隔离的策略、cache 决策、diagnostics 和 mixed traversal;无法单凭这些单元测试替代真实 renderer/GPU 场景。
|
||
|
||
## 7. Android Validation 场景
|
||
|
||
Test App 的 STEP-093 菜单新增 `STEP-102 PLACEMENT LOCALITY`,也可用 Intent `step102_scenario` 启动:
|
||
|
||
- `T1_FREE_SYMBOL`:R0 background/fill(无 symbol)→ C0 持续粒子 → R1 symbol;每 500ms 更新 R1 GeoJSON point,让 placement/source 活跃。
|
||
- `T2_TWO_FREE`:相同 R0/C0,R1 改为 fill;两个 Retained 均结构上 placement-free。
|
||
|
||
每个 `STEP102_SAMPLE` 记录固定 camera、placement 四个全局字段、main-buffer mode/reason、每段 capability/gate/actual、cache decision、build/reuse/invalidation/fallback。tick 8/130 打窗口标记。日志字段用于验收,不在 App 中自行宣告 PASS。
|
||
|
||
## 8. 实际检查与 NOT RUN
|
||
|
||
- 已执行:`git status --short`、`git diff`/`rg` 只读审计;`git diff --check` **PASS**。三个新增未跟踪文件另以 `git diff --no-index --check /dev/null <文件>` 检查,无空白错误;该命令因有差异正常退出 1。
|
||
- **NOT RUN**:CMake/Ninja/Bazel configure/build/link、C++ GTest、Android Native TestRunner、Android Gradle、APK/AAR、codegen、Jest、ADB、设备/截图/logcat、iOS/Metal、NavSea、发布、commit、push。
|
||
- 无 APK/AAR、大小、SHA-256、运行日志或最终性能结果。没有编译失败或测试失败的事实;缺少编译/运行证据。
|
||
|
||
## 9. 后续精确验证命令与硬门槛
|
||
|
||
先由 RDC 在本工作区运行 host 定向测试;若当前 Mac `libuv` 环境仍阻塞,应记录首个真实 configure 错误,而非改动依赖:
|
||
|
||
```bash
|
||
cmake --preset macos-metal
|
||
cmake --build build-macos-metal --target mbgl-test-runner --parallel 3
|
||
build-macos-metal/mbgl-test-runner --gtest_filter='RenderSegmentPlacementFree.*:RenderSegmentLocality.*:RenderSegmentDiagnostics.*'
|
||
```
|
||
|
||
**Android Validation APK 只由用户手工构建**,使用项目固定入口:
|
||
|
||
```bash
|
||
cd /Users/tei/dev/MapLibreParticleLab-step102
|
||
./tools/particle_android_validation/build_validation_apk.sh
|
||
```
|
||
|
||
构建成功后由 RDC/用户核对 APK ZIP、ABI、`libmaplibre.so`、SHA-256、branch/commit/dirty 状态,再在选定设备上独立运行。下列 `<SERIAL>` 需替换为实际 `adb devices` 返回的 serial;每场景单独清日志、force-stop、启动并留存完整 logcat:
|
||
|
||
```bash
|
||
adb -s <SERIAL> install -r artifacts/maplibre-particle/android-validation/MapLibreAndroidTestApp-validation-opengl-debug-x86_64.apk
|
||
adb -s <SERIAL> logcat -c
|
||
adb -s <SERIAL> shell am force-stop org.maplibre.android.testapp
|
||
adb -s <SERIAL> shell am start -n org.maplibre.android.testapp/.activity.particle.ParticleCoreLayerValidationActivity --es step102_scenario T1_FREE_SYMBOL
|
||
adb -s <SERIAL> logcat -v threadtime -d > /tmp/step102-t1-logcat.txt
|
||
rg 'STEP102_(SCENARIO_START|STYLE_READY|SAMPLE|WINDOW_MARKER)|Fatal signal|ANR' /tmp/step102-t1-logcat.txt
|
||
```
|
||
|
||
对 `T2_TWO_FREE` 重复 `logcat -c`、force-stop、启动、保存到 `/tmp/step102-t2-logcat.txt`。每组至少等待 tick 130(约 65 秒)后取最终日志。T1 硬门槛:固定 camera、`mainBufferExecutionMode=mixed` 的稳定窗口中 R0 `placementCapable=false`、`actualExecution=composite`、buildDelta=0、invalidationDelta=0、reuseDelta>0;R1 `placementCapable=true`,placement gate 失败期间 `actualExecution=live`,C0 live,Style Z-order 正确,无 stale/crash/ANR。T2 两个 Retained 均无 symbol,build 一次后持续 reuse/composite。若窗口内出现真实 global mutation,应结合 `globalLiveFallbackReason` 与 lastMutation 重新选择稳定窗口,不把合法 global invalidation 算作误伤。
|
||
|
||
还需独立做 STEP-100 source locality 与 STEP-101 teardown 回归,以及 global light/style/context/camera、topology 变动资源释放验证。iOS/Metal 只可在相同源码提交的 Mac/iOS 验收后声明通过。本阶段均未执行。
|
||
|
||
## 10. 风险、未完成事项与交接
|
||
|
||
- Android symbol glyph asset 与 placement 活跃窗口尚未由构建/设备核实;T1 若未出现 placement gate 失败,不构成主场景验收。
|
||
- 现有 C++ topology 测试验证 key/revision 无旧 cache reuse,不能证明真实 GPU 资源已释放;需设备/后端证据。
|
||
- `placementChanged` 与 `symbolFadeChange` 在 Fast Path 帧来自既有 prepared render tree;本 Step 没有改变 Fast Path 判定或语义。主验收只使用 `fullCpuFrame` 增长的 full CPU 窗口。
|
||
- 构建或运行失败应保留现场、回传首个真实错误及必要上下文;不得放宽测试或安全门槛。没有触及任务书要求 BLOCKED 的架构扩张条件。
|
||
|
||
本阶段未创建 Git commit,故无 implementation commit SHA;也未执行 merge、push 或远端 HEAD 回读。后续独立验收决定 scoped commit/merge 与发行流程。
|