Compare commits
2 Commits
a49dd936c4
...
23f7b8a4d7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
23f7b8a4d7 | ||
|
|
86906c8a6a |
38
docs/50_Step记录/STEP-106_STEP102_T2_Placement边界修正_v1.md
Normal file
38
docs/50_Step记录/STEP-106_STEP102_T2_Placement边界修正_v1.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# STEP-106 STEP-102 T2 自动 Annotation 层边界修正记录 v1
|
||||
|
||||
日期:2026-10-09(JST)
|
||||
|
||||
**状态:SOURCE_FIXED / STATIC_PASS / ANDROID_BUILD_NOT_RUN / DEVICE_RETEST_NOT_RUN**
|
||||
|
||||
## 事实
|
||||
|
||||
- 旧版 13.4.1-particle.21 在 FZG 同样复现 T2 R1 placementCapable=true/gate=false/live/static-placement/reuse0,已保存同场景旧版日志。新版 13.6.1 在比较结束后成功恢复,设备 APK SHA 正确。
|
||||
- 两版 AnnotationManager 会自动在 Style 末尾插入 Symbol Layer org.maplibre.annotations.points。T2 测试 Fixture 的上层自身为 Fill,但原 R-C-R Plan 的 R1 从 step102-upper 延续至最后一层,把该内部 Symbol 也算进去。
|
||||
- 不允许修改或跳过 Shared Core/Renderer Placement 安全 Gate。此次只改两个 Android Test App Kotlin 文件;新增 C2 live 尾部区段,单独承载 MapLibre Annotation Symbol,从而使 T2 的 R1 仅含 Fill;T1 R1 仍含自身 Symbol。
|
||||
- 为 tick8 新增 STEP102_STYLE_LAYER_LAYOUT 日志,供下次实际 APK 验证真实 Style Layer 顺序、分段边界。
|
||||
- 代码 Git 提交:86906c8a6af474a8d064c6f6d7d431e2a7e3efe6;静态检查 PASS,没有执行 Gradle、ADB 修正版验证、Jest。
|
||||
|
||||
## 需用户手工编译
|
||||
|
||||
在 Mac 终端:
|
||||
|
||||
```bash
|
||||
cd /Users/tei/dev/MapLibreParticleLab-upgrade-android-1361
|
||||
export JAVA_HOME=/usr/local/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home
|
||||
export ANDROID_HOME=/Users/tei/Library/Android/sdk
|
||||
export ANDROID_SDK_ROOT="$ANDROID_HOME"
|
||||
export PATH="$JAVA_HOME/bin:$ANDROID_HOME/platform-tools:$PATH"
|
||||
export MAPLIBRE_VALIDATION_OUT_DIR="$PWD/artifacts/maplibre-particle/step106-t2-fix"
|
||||
./tools/particle_android_validation/build_validation_apk.sh
|
||||
```
|
||||
|
||||
脚本内部使用 Gradle `--console=plain`。请保留 BUILD SUCCESS 和 build-info.txt,APK 生成后再由 RDC 安装到 FZG。不得把目前设备上的 13.6.1 旧 APK 当成包含本修复的版本。
|
||||
|
||||
## 复测门槛
|
||||
|
||||
- APK 完整性、包名、版本、Native x86_64、哈希校验;签名不符禁止卸载重装。
|
||||
- 新版 STEP102_STYLE_LAYER_LAYOUT 必须显示自动 Annotation Symbol 在最后的独立 Continuous C2;Plan valid、segments=4。
|
||||
- T1_FREE_SYMBOL:R0 continued Composite/Reuse、R1 placementCapable=true 且需要时 Live、C2 包含 Annotation;不崩溃。
|
||||
- T2_TWO_FREE:R0 和 R1 均 placementCapable=false、gate=true、actualExecution=composite;tick8→130 的 buildDelta=0、invalidationDelta=0、reuseDelta>0;C2 Live;不崩溃。
|
||||
- 复测 STEP-099 T4 R-C-R R0 locality,STEP-101 单次/20次 Native Reset(日志须持续采集),V4 Golden 最小烟测。保留失败路径及原始日志。
|
||||
- 修正作用域限定 Test App 分段验证,不等同生产快帧性能达标。若仍 fallback,应保留 Placement fail-closed,重新诊断而非强制 PASS。
|
||||
78
docs/报告/STEP-106_STEP102_T2_Placement边界修正_RDC实施报告_v1.md
Normal file
78
docs/报告/STEP-106_STEP102_T2_Placement边界修正_RDC实施报告_v1.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# STEP-106 STEP-102 T2 Placement 边界修正 — RDC 实施报告 v1
|
||||
|
||||
## 1. 当前判定
|
||||
|
||||
**源码修正已提交、静态检查通过;Android/Kotlin 编译 NOT RUN、FZG 修正版设备验证 NOT RUN。**
|
||||
|
||||
本阶段专门处理 STEP-105 的 T2_TWO_FREE 未达到预期问题。保留原 STEP-105 PARTIAL 状态直至修正版 APK 手工编译和 FZG 定向运行 Gate 全部通过。没有改动核心 Renderer 的 Placement 容错判定。
|
||||
|
||||
## 2. 旧版同设备复现
|
||||
|
||||
设备 FZG1-2,Android 13,x86_64,ADB 192.168.200.139:5555。
|
||||
|
||||
先核对旧、新 APK 的包名相同为 org.maplibre.android.testapp、versionCode 均为14、证书 SHA-256 均为 e3f8fae6451ed6322259d090dd8e8788df554ab25ed89a01c78014f1d5ef8236。旧版文件 SHA-256 为 999f773276b29fffae05c1edc977e19df6cebecd94e4a4095508d0c5e97e07c2。
|
||||
|
||||
临时 adb install -r 安装旧版 13.4.1-particle.21,运行:
|
||||
|
||||
`adb -s 192.168.200.139:5555 shell am start -W -n org.maplibre.android.testapp/.activity.particle.ParticleCoreLayerValidationActivity --es step102_scenario T2_TWO_FREE`
|
||||
|
||||
流式 Logcat 在 tick29/30 记录:R0 placementCapable=false/gate=true/composite/reuse 正常;R1 placementCapable=true/gate=false/actual=live/fallback=static-placement/build0/reuse0。因而确认该现象旧 .21 **同样存在**,不是已证明由官方 Native 13.6.1 升级新引入。
|
||||
|
||||
立即 adb install -r 恢复已签名的新 13.6.1,返回 Success;设备已安装 base.apk 的 SHA-256 为 77bc0b238fb476494410a603443030b104d78f97a737307be52460bf5a68f5aa,和 Mac 现有新 APK 完全一致。随后重新启动不带 Extra 的 Particle Core Layer Validation Activity,版本仍 13.6.1。
|
||||
|
||||
证据位于 Git 忽略目录 `artifacts/maplibre-particle/step105-fzg-t2-rootcause-20261009/old21-t2-stream.log`,以及先前 `step105-fzg-runtime-20261009/09-step102-t2/stream.log`。
|
||||
|
||||
## 3. 可核对的源级原因
|
||||
|
||||
13.6.1 的 `src/mln/annotation/annotation_manager.cpp` 中,`AnnotationManager::updateStyle()` 会创建名为 `org.maplibre.annotations.points` 的 Symbol Layer 并追加至 Style。旧 .21 的 `src/mbgl/annotation/annotation_manager.cpp` 保留同样逻辑。
|
||||
|
||||
原测试计划为 R0 RETAINED → C0 CONTINUOUS 从 `step102-particle` 开始 → R1 RETAINED 从 `step102-upper` 开始并延伸到 Style 最后一层。测试 fixture 的 T2 `step102-upper` 是 Fill,但 R1 还包含默认追加的 Annotation Symbol。RenderSegment 层级的 `renderSegmentHasPlacementCapableLayer()` 只要在范围内看到 Symbol 即正确地判 true;在 fade/placement 期间 fallback `static-placement` 是安全行为,不能绕过。
|
||||
|
||||
这是对代码结构和两版设备现象的一致解释。真实 Style 的完整 `styleLayers` 数组先前没有输出,因此最终边界还要等待修正版新增诊断进一步核对;不得在这里宣称 Pixel/GPU 原因已由运行时完整证明。
|
||||
|
||||
## 4. 修改与保护边界
|
||||
|
||||
源码分支:`upgrade/android-native-13.6.1-20261009`。
|
||||
|
||||
代码提交:`86906c8a6af474a8d064c6f6d7d431e2a7e3efe6` — `test(android): isolate internal annotation symbol from STEP-102 retained ranges`。
|
||||
|
||||
两个文件:
|
||||
1. `platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/particle/Step102PlacementFixture.kt`:为 T1、T2 共用计划增加最后一段 CONTINUOUS,startLayerId=`org.maplibre.annotations.points`,使原 R1 只包含自有上层。两场景保持相同边界。若默认 Layer 不存在,现有 Plan resolver 会因 boundary-layer-missing fail-closed,不会错误地忽略该层。
|
||||
2. `platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/particle/ParticleCoreLayerValidationActivity.kt`:在 tick8 输出一次 `STEP102_STYLE_LAYER_LAYOUT`,包含 Style Layer id/type/index 与四段 begin/end,用实际测试证据验证上层边界。
|
||||
|
||||
没有修改 `src/mln`、`include/mln`、Renderer、Shared Core、NavSea 或 iOS,也未改变任何公开 API/ABI。
|
||||
|
||||
新增 C2 使本测试由 R-C-R 变为 R-C-R-C,并可能失去“仅一个 Continuous”的 Particle fast-path 优化条件:这是仅用于证明两个 Retained 在真实内部 Annotation 层存在时安全局部复用的独立测试布局,不能当作生产性能验证或建议宿主一律使用四区段布局。
|
||||
|
||||
## 5. 当前检查结果
|
||||
|
||||
- `git diff --check` PASS。
|
||||
- 静态合成 Style 解析:T1 的 R1 为 Symbol,T2 的 R1 为 Fill,Annotation Symbol 位于 C2;模拟边界覆盖完整且无空段,PASS(**非 Kotlin 构建、非真实 Runtime**)。
|
||||
- Android Gradle/Kotlin Build:NOT RUN(用户手工编译)。
|
||||
- 更新版 Validation APK:NOT BUILT。
|
||||
- FZG 新计划的 T1/T2 tick8/130:NOT RUN。
|
||||
- 其它 ABI / iOS / NavSea / Jest:NOT RUN。
|
||||
|
||||
## 6. 用户手工编译与 RDC 验收
|
||||
|
||||
Mac 终端:
|
||||
|
||||
```bash
|
||||
cd /Users/tei/dev/MapLibreParticleLab-upgrade-android-1361
|
||||
export JAVA_HOME=/usr/local/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home
|
||||
export ANDROID_HOME=/Users/tei/Library/Android/sdk
|
||||
export ANDROID_SDK_ROOT="$ANDROID_HOME"
|
||||
export PATH="$JAVA_HOME/bin:$ANDROID_HOME/platform-tools:$PATH"
|
||||
export MAPLIBRE_VALIDATION_OUT_DIR="$PWD/artifacts/maplibre-particle/step106-t2-fix"
|
||||
./tools/particle_android_validation/build_validation_apk.sh
|
||||
```
|
||||
|
||||
脚本自带 Gradle `--console=plain`、Native ABI/体积/ZIP 检查。用户编译后由 RDC 确认 Git 源码 SHA、包名、签名、APK SHA,再 adb install -r 到 FZG。
|
||||
|
||||
验收应分别运行 STEP-102 `T1_FREE_SYMBOL` 与 `T2_TWO_FREE`(明确传 `--es step102_scenario <SCENARIO>`),在 tick8 和 tick130 读取 `STEP102_STYLE_LAYER_LAYOUT` / `STEP102_SAMPLE` / `STEP102_WINDOW_MARKER`。对 T2 需要 R0 和 R1 同时 placementCapable=false、gate=true、actualExecution=composite;各自 buildDelta=0、invalidationDelta=0、reuseDelta>0;C2 live 且保持 Z-order。T1 的 R1 为 Symbol,应继续按现有安全 gate fallback;检查样本和崩溃日志。之后最小回归 STEP-099 T4、STEP-101 Native reset、QBIN V4 Golden,失败须保留现场。
|
||||
|
||||
## 7. Gate
|
||||
|
||||
**SOURCE_FIXED / STATIC_PASS / BUILD_PENDING / DEVICE_PENDING**。
|
||||
|
||||
任何未编译、未安装新版修正 APK 的设备日志不能被用来宣称 STEP-106 PASS。待 RDC 收到用户手工编译成功的制品后,才进入下一阶段设备验收和最终关闭。
|
||||
@@ -105,6 +105,26 @@ class ParticleCoreLayerValidationActivity : AppCompatActivity() {
|
||||
"fullCpuFrame=${snapshot.optLong("fullCpuFrame")} ranges=${ranges.joinToString(";")}"
|
||||
diagnostics.text = "STEP-102 $message"
|
||||
Log.i(TAG, "STEP102_SAMPLE $message")
|
||||
if (step102Tick == 8L) {
|
||||
// One-shot proof of actual runtime style ordering and annotation boundary.
|
||||
val styleLayers = snapshot.optJSONArray("styleLayers")
|
||||
val layerOrder = buildList {
|
||||
for (index in 0 until (styleLayers?.length() ?: 0)) {
|
||||
val layer = styleLayers?.optJSONObject(index) ?: continue
|
||||
add("${layer.optInt("layerIndex")}:${layer.optString("layerId")}:${layer.optString("layerType")}")
|
||||
}
|
||||
}
|
||||
val rangeOrder = buildList {
|
||||
for (index in 0 until (segments?.length() ?: 0)) {
|
||||
val segment = segments?.optJSONObject(index) ?: continue
|
||||
add("${segment.optInt("segmentIndex")}:${segment.optString("strategy")}" +
|
||||
"[${segment.optInt("beginIndex")},${segment.optInt("endExclusive")})" +
|
||||
"=${segment.optJSONArray("layers")?.length() ?: 0}")
|
||||
}
|
||||
}
|
||||
Log.i(TAG, "STEP102_STYLE_LAYER_LAYOUT scenario=$scenario layers=${layerOrder.joinToString(";")}" +
|
||||
" segments=${rangeOrder.joinToString(";")}")
|
||||
}
|
||||
if (step102Tick == 8L || step102Tick == 130L) {
|
||||
Log.i(TAG, "STEP102_WINDOW_MARKER phase=${if (step102Tick == 8L) "baseline" else "final"} " +
|
||||
"scenario=$scenario tick=$step102Tick")
|
||||
|
||||
@@ -3,7 +3,13 @@ package org.maplibre.android.testapp.activity.particle
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
/** Offline STEP-102 R-C-R fixture; only the upper retained range changes placement capability. */
|
||||
/**
|
||||
* Offline STEP-102 locality fixture.
|
||||
* R0 / particle C0 / upper R1 keep identical boundaries for T1 and T2.
|
||||
* MapLibre appends its internal annotation Symbol layer after the style layers:
|
||||
* keep that layer in a final live C2 range, outside the upper Retained cache.
|
||||
* Never bypass Renderer placement safety gates to make a fixture pass.
|
||||
*/
|
||||
internal object Step102PlacementFixture {
|
||||
enum class Scenario { T1_FREE_SYMBOL, T2_TWO_FREE }
|
||||
|
||||
@@ -12,6 +18,8 @@ internal object Step102PlacementFixture {
|
||||
private const val PARTICLE_SOURCE = "step102-field"
|
||||
private const val PARTICLE_LAYER = "step102-particle"
|
||||
private const val UPPER_LAYER = "step102-upper"
|
||||
// Built into MapLibre AnnotationManager; it is a Symbol even when the fixture has no symbols.
|
||||
private const val INTERNAL_ANNOTATION_LAYER = "org.maplibre.annotations.points"
|
||||
|
||||
fun styleJson(scenario: Scenario): String {
|
||||
val sources = JSONObject()
|
||||
@@ -56,7 +64,8 @@ internal object Step102PlacementFixture {
|
||||
.put("segments", JSONArray()
|
||||
.put(JSONObject().put("strategy", "RETAINED"))
|
||||
.put(JSONObject().put("strategy", "CONTINUOUS").put("startLayerId", PARTICLE_LAYER))
|
||||
.put(JSONObject().put("strategy", "RETAINED").put("startLayerId", UPPER_LAYER)))
|
||||
.put(JSONObject().put("strategy", "RETAINED").put("startLayerId", UPPER_LAYER))
|
||||
.put(JSONObject().put("strategy", "CONTINUOUS").put("startLayerId", INTERNAL_ANNOTATION_LAYER)))
|
||||
.toString()
|
||||
|
||||
private fun geoJsonSource(geometryJson: String): JSONObject = JSONObject().put("type", "geojson")
|
||||
|
||||
@@ -72,3 +72,16 @@
|
||||
- 候选原因:需要核实 Style 中默认注入的 annotation/symbol layer 是否被划入 R1,以及 Segment 范围;不要移除保守安全 gate 来凑 PASS。
|
||||
- 收尾:已恢复正常 GLOBAL/ACTIVE/EAST/MIX 0%/256 默认粒子页面,FZG 前台 Test App 13.6.1,进程存活,Crash Buffer 0。整体状态 PARTIAL / T2 EXPECTATION FAIL。
|
||||
- 原始证据保存在 Git 忽略目录 artifacts/maplibre-particle/step105-fzg-runtime-20261009/01-baseline 到 10-restored。未执行 Gradle、Jest、NavSea、iOS;下阶段先解决 T2 再复测。
|
||||
|
||||
## 2026-10-09 / STEP-106 / STEP-102 T2 Placement 边界修正(仅 Test App,待手工编译)
|
||||
|
||||
- 问题来源:STEP-105 FZG Android Native 13.6.1 运行回归中,STEP-102 T2_TWO_FREE 的 R1 虽然 fixture 自有的 step102-upper 是 Fill,却仍 placementCapable=true、gate=false、actual=live、fallback=static-placement、reuse=0。
|
||||
- 老版对照:FZG1-2 临时覆盖安装原 13.4.1-particle.21 APK,签名相同、包名及 versionCode=14 不变;通过 --es step102_scenario T2_TWO_FREE 运行,Logcat tick29/30 **同样** R1 placementCapable=true、gate=false、live、static-placement、reuse=0,R0 composite/reuse。说明这不是 13.6.1 新引入的特有回归。
|
||||
- 设备恢复:旧版比较后 adb install -r 恢复 **13.6.1**,设备 SHA-256 与当前新版 APK 完全一致:77bc0b238fb476494410a603443030b104d78f97a737307be52460bf5a68f5aa;已重新启动普通 Particle Core Layer Validation 页面,NavSea 未被修改。
|
||||
- 根因:源码核对两版 AnnotationManager::updateStyle() 都自动在 Style 末尾添加 org.maplibre.annotations.points(Symbol),STEP-102 原 R-C-R plan 最后 Retained 从 step102-upper 一直延伸至 Style 末尾,包含内部 Symbol。Renderer 对 Symbol 的 placementCapable=true / static-placement fail-closed 是合理行为;T2 原计划没有隔离隐式 Annotation 层。
|
||||
- 源码修正(限定 Android Test App):Step102PlacementFixture.planJson() 在两场景共同的 R0 → 粒子 C0 → 上层 R1 之后增加明确的尾部 C2,startLayerId=org.maplibre.annotations.points,保持 Style Z-order 和 Symbol 安全门,T1/T2 用相同边界;ParticleCoreLayerValidationActivity 在 tick8 增加一次性 STEP102_STYLE_LAYER_LAYOUT,打印真实 Style Layer id/type 和各 Segment index 范围。
|
||||
- 代码提交:86906c8a6af474a8d064c6f6d7d431e2a7e3efe6;只改 Test App 两个 Kotlin 文件,无 Shared Core、Renderer、公开 API、NavSea、iOS 修改。
|
||||
- 静态检查 PASS:git diff --check;合成 Layer 顺序下 T1 R1 Symbol / T2 R1 Fill / 尾部 Annotation Symbol 分段吻合,4 段覆盖完整(这是模拟,不是实际编译或设备验证)。
|
||||
- **PENDING**:本轮没有执行 Android Gradle/Kotlin 编译、没有构建更新 APK,也没有对新修正后的 T1/T2 进行真实 FZG 测试。设备目前仍是已经安装的**修正前** 13.6.1 APK。遵守用户手工编译边界,需用户在 Mac 运行 ./tools/particle_android_validation/build_validation_apk.sh;之后 RDC 核对 APK SHA、更新安装并运行 STEP-102 T1/T2 tick8/130 + STEP-099 T4 + STEP-101 定向回归。
|
||||
- 重要边界:为了测试场景保留 Annotation 的 Z-order,新计划成为 R-C-R-C;增加第二个 Continuous 会失去原 fixture 的单一 Continuous fast-path 资格,**该修正仅用于验证 Retained Placement 局部缓存**,不能拿它证明生产路径快帧性能。未确认的目标必须继续标记待验收。
|
||||
- 详细报告:docs/报告/STEP-106_STEP102_T2_Placement边界修正_RDC实施报告_v1.md;原始对照日志:artifacts/maplibre-particle/step105-fzg-t2-rootcause-20261009/old21-t2-stream.log(Git 忽略目录)。
|
||||
|
||||
Reference in New Issue
Block a user