Files
MapLibreParticleLab/docs/报告/V26_Metal混合Segment视觉错误_安全降级调查报告_v1.md
tei a9cea8b581
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
fix: retain correct Metal composite vertex buffer slot
2026-10-14 10:16:14 +09:00

5.6 KiB
Raw Permalink Blame History

V26 Metal 混合 Segment 视觉错误与第一阶段安全降级调查报告 v1

已撤回:2026-10-13 用户明确要求必须保留 Retained 实际构建/复用/合成。本文安全降级代码已在 Particle 工作区撤销,禁止按本文编译或发布。请以同主题 v2 修复调查报告为准。

日期:2026-10-13 状态:已撤回(REJECTED)——原代码级安全降级方案不可用;保留本文件仅作历史记录 目标仓库:MapLibreParticleLab 冻结 V26 源码:fce326a9009d3fc21eb91c5df362f0769163d07e(SOURCE_LOCK),当前工作分支 particle/main,修改前 HEAD b0f34cc9a299a75af1f7e708c63d75eaa42e9ca2。

一、iPad 实测事实

iPad:Pleiades(iPad mini 5);iOS 已安装 V26 Native。实验使用 Windows CARBON7i D:\React\NavSea 的 Metro 192.168.200.100:8081,而非 Mac 本地 Metro。

  • 原始 RC:天气 ON 后本船/AIS/海图闪烁,天气 OFF 后仍异常。
  • A(关闭 Retained,完整天气):不闪烁。
  • B(保留 Retained,隐藏 Native 天气):不闪烁;色场与粒子均无显示。
  • C(只有色场,保留 Retained):色场出现,闪烁。
  • D(只有粒子,保留 Retained):闪烁。
  • E(Retained 总开关开、实际 0 Retained + 1 Continuous):不闪、天气色场和粒子完整,本船/AIS 图标尺寸与航线正常。
  • F(最底层 background 单层 Retained + 其余 114 层 Continuous):冷启动即图标异常放大、本船航行线与 AIS 航线消失;不闪;天气色场与粒子正常。F 是失败,不得据其不闪而判 PASS。

iPad Native 快照原始保存于 Mac: /tmp/navsea-v26-ipad-render-20261013/E-0746/start.json、 /tmp/navsea-v26-ipad-render-20261013/F-0740/start.json; F:enabled=true, valid=true, fallback=false; R0 [0,1) 实际 composite,C1 [1,115) 实际 live; E:enabled=true, valid=true, fallback=false; 单 Continuous [0,115) 实际 live。 旧 RCR 实验曾因 JS 预检将最后 Layer 硬编码为 chartDangerScanCenterLineLayer,但实际最后 Layer 是 route-history-dotted-line,回退到 RC。不要把当时现场当成 RCR Native 执行证明。

二、已核对的 Native 代码路径

src/mln/renderer/renderer_impl.cpp 中,实际含 Retained Segment 的绘制在独立 RenderPass 中构建离屏缓存,调用 RetainedUnderlayCache::composite,然后绘制 Continuous 图层。 src/mln/renderer/retained_underlay_cache.cpp 的缓存创建与合成对应 prepareResources、beginBuild、finishBuild、composite。 iOS Metal src/mln/mtl/render_pass.cpp 已有 Color/Depth/Stencil Clear 逻辑,尚不能证明清屏本身出错。 现有证据将异常定位在 实际执行 Retained 离屏构建/合成和连续图层共存时,但尚未证明具体 GPU 状态或 shader 错误。

三、第一阶段保护性补丁(尚未发布)

  1. include/mln/renderer/render_segment.hpp:新增 requiresMetalRetainedCompositeSafetyFallback,针对合法 Plan 内任何 RETAINED Segment + Metal 后端启用安全回退;全 Continuous 和非 Metal 保留原逻辑。
  2. src/mln/renderer/renderer_impl.cpp:Native 检测到上述情形时,禁止 Retained 离屏资源构建、Reuse、合成;释放历史缓存;完整 Style 范围做常规 Live Opaque+Translucent 绘制。阻止 Particle FastFrame 在该组合误准入。Native 诊断 globalLiveFallbackReason 记录 metal-retained-composite-safety,actualExecution 应全部为 live。
  3. test/renderer/retained_underlay_cache.test.cpp:加入 OpenGL 不启用、Metal R-C 启用、Metal全Continuous不启用、Metal全Retained启用、无效Plan不启用的安全策略单测。

此补丁属于 correctness-first 的暂时降级方案,不是 Retained 合成根因修复,也不提供 Retained GPU 加速。 禁止在未做真实 Metal 回归前声称问题已关闭。Native 公共 JS API 与输入 Contract 不变;Renderer 层仍以 Style Z-order 为唯一图层顺序。

四、待用户手工验收

  1. 保留冻结 V26 artifact,不覆盖正式发行版本;从当前修改源码建立新的测试版 iOS Metal XCFramework / Test Host,不把未验证产物标成 V26 正式版本。用户手工完成 iOS 构建、安装、启动。
  2. 用统一 JS 测试配置加载含 Retained Segment 的 RC/F 方案,确认 Native 诊断显示 global-live、metal-retained-composite-safety,且无 Retained texture build/composite;不能只凭 JS mode badge 判断。
  3. 冷启动关天气、ON、OFF,检查本船/AIS 图标尺寸、航行线、海图层、天气色场、粒子、图层 Z-order、视觉稳定。
  4. Android OpenGL 使用完全相同的 JS Plan 对照,确认没有触发 Metal 安全回退;记录 native 版本差异,版本未对齐时不得直接宣称平台差异。
  5. 记录帧率、CPU、GPU、内存和耗电;补丁性能可能低于 Retained 缓存方案。
  6. 后续通过 Metal GPU Capture/离屏纹理、Blend、Depth/Stencil 和 Drawables 生命周期调查根因,修复后再移除安全降级,并对 R-C/R-C-R、多 Retained 段复测。

五、执行边界与状态

  • 本轮没有执行 iOS/Android 原生编译、APK/XCFramework 安装、ADB、真机自动操作,也没有发布 tag/制品。
  • 粒子仓库工作区变更先保持未提交,避免污染冻结 V26。
  • Windows NavSea Debug JS 的平台分流已移除:Android/iOS 共用 E_CONTINUOUS_ONLY,Release 仍为 BASELINE。这项改动仍需 Android 用户手工真机核验。
  • 全部修复最终验收需要跨项目 Integration 按既定 Contract/Status 更新,不由 NavSea 独自宣告 Particle 发布完成。