66 KiB
UPSTREAM-001 MapLibre 官方升级兼容性架构审计 Codex 完成报告 v1
日期:2026-10-09(JST)。任务基线:630ec657687bad4200c059bbccbb950d9c6f7ce9。本报告只交付架构审计、三方干跑与后续建议,没有实施升级。
1. 结论摘要
结论:CONDITIONAL GO。 可以立项开展隔离迁移;不允许据本报告直接发布升级版本。必须先完成命名空间/接口迁移、Renderer 适配边界与两端单 SDK 收敛,再由 RDC/用户独立构建和运行验收。本次没有编译、运行、设备或发行 PASS。
- Particle 的 Field/Ingress/Binding 具备可移植基础,WeatherColor 与 Particle 为独立 RenderLayer;不需要重写引擎。但 GPU 实现在新增的
render_particle_validation_layer.cpp内,仍依赖 MapLibre 内部 RenderTarget、LayerGroup、Heatmap 顶点结构、PaintParameters 和生命周期,不能把“新增文件”解释成“独立 SDK”。 - 长期维护的主要负担是
Renderer::Impl与RenderOrchestrator中的缓存调度、Fast Path 输入签名、source/placement 失效及资源所有权。相对初始基线,两个.cpp分别增加/删除 632/39、505/5 行,已超过 thin-hook 的含义。 - 官方目标均发生
mbgl→mln目录和 C++ 命名空间迁移。标准 dry-run:Android 76 个冲突路径(31 content + 44 file location + 1 modify/delete);iOS 78 个(33 + 44 + 1)。两者退出码均 1:模拟完成且存在冲突,不是执行失败,也不是升级成功。 .21相对初始基线共 765 个变化路径:680 新增、85 修改。两条官方升级线原路径交叉分别 72/76,其中可自动合并的交叉路径为 40/42。不能把 85、72、76 或旧说法中的“62 个修改文件”当作文本冲突数。- 已读官方目标函数定义,确认
RenderLayer::update()新增const PaintParameters&、PaintParameters增加renderableSize、RenderStaticData::backendSize被移除。新增粒子层、Fast Path 和 retained key 的调用必须适配;这是确定的源码接口差异,未执行编译,不能伪称已观察到编译报错。 - RN 11.5.0 必须与 Native 升级分开验收。当前 RN peer/dev/Podspec 锁 11.3.6,Android 插件强制 13.4.1/
.21,iOS 借用 MLRN 私有 SPM helper。只升 npm 版本会留下版本约束与 API/二进制风险。
2. 核对的版本与 SHA
| 项目 | 本次核实结果 | 证据边界 |
|---|---|---|
| 机器 | Darwin Mac.lan 24.6.0,x86_64 |
uname -a,无设备操作 |
| 工作区 | /Users/tei/dev/MapLibreParticleLab-upstream-audit-20261009 |
独立审计 worktree |
| 分支 / HEAD | audit/upstream-native-20261009 / 630ec657687bad4200c059bbccbb950d9c6f7ce9 |
起点与收尾一致 |
| 本地远端跟踪引用 | origin/particle/main = 同上 SHA |
git ls-remote origin refs/heads/particle/main 退出 128,DNS 失败;不能宣称实时远端 HEAD 已回读 |
| 初始 Core | 18545ca10d296704b2cba675b182ff2c8da24588 |
HEAD 与两条目标各自的 merge-base 均为此 SHA,退出 0 |
| Android 目标 | c7506d6aff3800e946f89e1a51432fc22d1a6534 |
本地 commit subject 为 Release MapLibre Android 13.6.1;任务书给定 tag 对应关系 |
| iOS 目标 | 01791ad02c1bfe3b22c42a97619b972aba962f82 |
本地 commit subject 为 Release MapLibre iOS 6.31.0;任务书给定 tag 对应关系 |
| 官方目标相互关系 | 两者 merge-base 为 Android 目标 SHA | Android 目标是 iOS 目标祖先;不能把它们当成两个无关 Core |
| 本地 tags | android-v13.6.1^{commit}、ios-v6.31.0^{commit} 均退出 128 |
tag 引用未安装;以完整 commit SHA 复现,不伪称完成 tag 公网认证 |
| 当前 Android / RN | 13.4.1-particle.21 |
platform/android/VERSION、RN package.json、release manifest |
| 当前 iOS | 6.28.0-particle.21,Metal,模块 MapLibre |
release/maplibre-particle/ios/release-manifest.json |
.21 制品源码 |
manifest 的 sourceCommit=16a5d15f164dc93d220e3fac62de66a9c9527ccc |
与审计 HEAD/发行记录提交是不同概念;未重新下载或核验制品 |
| 官方 RN | v11.5.0,release 页面短 SHA 059f46b,2026-10-04 |
没有取得完整 RN tag checkout,不能声称审查了全部 RN 11.5.0 源码 |
| Integration | Mac 现存 /Users/tei/dev/navsea-particle-integration HEAD=80667d6c343411d03a760425438e3d292f452118 |
只读 README/规则/COORD-005/C-001/C-002/状态;未访问 Linux 文件系统或修改合同 |
| Git / submodule | Git 2.54.0;非 shallow;39 个 submodule 均未初始化(-) |
submodule status 退出 0;不构成构建环境就绪 |
根目录总则当前路线 v2 仍描述 .3,Integration 部分状态仍是旧开发状态,STEP-094 设计仍描述 source 全局失效;以 .21 代码与后续 STEP-100/102 实现事实为准,不回写历史文档。已阅读 STEP-098~102 记录及 STEP-094 设计;本审计基线的 docs 中没有 STEP-103 文件,因此不把其他 dirty worktree 或临时执行日志中的 STEP-103 当成 .21 已有能力。
3. 方法和数据可信度
3.1 执行范围
读取根规则、项目规范、四份有效总则、架构设计、任务书、相关 Step、实际源码与 base→HEAD diff。未启动子代理、第二个 Codex、后台构建、Jest、Gradle/APK/AAR、Xcode、ADB 或设备步骤。未真实 merge/rebase、未变更分支/index、未修改源码/依赖/构建脚本/Integration。任务书允许的两份文档中,本轮仅新增本报告,任务书保持原样。
证据临时目录:/private/tmp/upstream-001-audit-20261009/。Git object 写入也隔离于其 objects/,原共享对象库仅作只读 alternate。临时目录不是项目交付文件,RDC 应连同 JSONL/stdout/stderr 归档;本报告已嵌入冲突全表、命令与关键哈希,不依赖临时目录才能理解结论。
3.2 失败与恢复过程
| 操作 | 实际退出码 | 事实 |
|---|---|---|
三个 git merge-base HEAD <base/Android/iOS> |
0 | 均为初始 Core SHA |
初次 git diff --name-status base <Android/iOS> |
各 128 | promisor 补取 3354d3daaf97803cc42e43758177cb126a7f1671 时 github.com DNS 失败 |
初次标准 git merge-tree --write-tree --messages HEAD <目标> |
各 128 | promisor 补取 0e98150849597096c3fe2f1128b6e89884dcabdb 时 DNS 失败;stdout 为空,不能计作零冲突 |
| 原对象目录、关闭 rename 的诊断干跑 | 各 128 | unable to create temporary file: Operation not permitted / failure to merge |
git diff --no-renames --name-status base <目标> |
各 0 | 可得原路径交叉统计,但把移动表示为 D+A |
| 临时可写对象目录、标准 rename 干跑 | 各 1 | 完成,产生 tree 与冲突清单;未要求越过权限或修改原共享对象目录 |
| 同一临时对象目录标准干跑复跑 | 各 1 | 两次 stdout 字节完全一致,tree SHA 相同,stderr 为空 |
临时对象目录普通 git diff --name-status |
各 0 | rename-aware 清单取得成功 |
| 临时对象目录关闭 rename 的对照干跑 | 各 1 | Android 63、iOS 64 个路径;人为禁用目录迁移识别,不是主结论 |
| 远端 HEAD / 本地 tag 验证 | 128 | 分别为 DNS 失败 / 本地引用不存在,尚待 RDC |
失败原始日志保留,没有把后一次完成倒写成首轮成功。成功使用的环境覆盖没有改 Git 配置或合并算法;没有使用 -Xours、-Xtheirs 或关闭冲突检测。没有证据证明网络后来恢复,不能从本地干跑成功推导网络已通。另有探索性旧路径读取、缺失测试文件名及 glob 查询失败,随后按实际新路径/文件定位;这些不是编译或测试失败。
3.3 统计定义
- footprint:base→HEAD 的 Git 路径与 numstat,文档/fixture/测试/构建均分开说明。
- 原路径交叉:关闭 rename 时两边变更路径集合的交集。Android 23 M+49 D=72;iOS 27 M+49 D=76。49 D 中 48 被 Git 识别为 rename,shader_manifest 为 modify/delete;不是 49 个独立算法冲突。
- 冲突路径:标准 merge-tree stdout 第一段 stage 记录的路径去重;不把 stage 1/2/3 三条算三文件,也不靠
Auto-merging文本计数。冲突类型另由CONFLICT (...)消息统计,恰与本轮路径数一致。 - 自动合并交叉路径:交叉集合中,旧路径及其
mbgl→mln对应路径均不在 unmerged 清单者。它仅说明文本可合并;不代表符号、ABI、shader、资源或视觉正确。 - 行号默认是审计 HEAD。标注“目标”的
src/mln/...行号来自指定官方 commit blob;审查用 namespace 归一 diff 只写临时文件,未用归一文本作为正式干跑输入。
4. 两条 Native 升级线冲突统计与具体文件
| 指标 | Android 13.6.1 | iOS 6.31.0 |
|---|---|---|
| 官方 diff(rename-aware)路径数 | 2196 | 2250 |
| A / M / D / R | 91 / 709 / 27 / 1369 | 117 / 719 / 69 / 1345 |
| 官方 diff(no-renames)A / M / D | 1460 / 709 / 1396 | 1462 / 719 / 1414 |
| 与我方原路径交叉 | 72 | 76 |
| 交叉中冲突的官方既有文件 | 32 | 34 |
| 交叉中自动合并的官方既有文件 | 40 | 42 |
| 新增扩展的 file-location 冲突 | 44 | 44 |
| 全部 unmerged 路径 | 76 | 78 |
| content / file location / modify-delete | 31 / 44 / 1 | 33 / 44 / 1 |
| stage 条目数(不可当文件数) | 139 | 145 |
| 标准 dry-run 退出码 | 1 | 1 |
| 结果 tree | 9509597174b70c9eede21d6900b6f54fb092fefa |
ae31097f803a49be28c27eca6291252baebfa4c0 |
iOS 比 Android 多出的文本冲突是 platform/darwin/src/MLNStyleLayerManager.mm 和 src/mln/shaders/shader_source.cpp。虽然目标名标注某个平台,比较对象是整个 Native 仓库,Android 干跑同样可能报告 iOS 文件冲突。
完整冲突路径见附录 A;全部 85 个官方修改文件及交叉标记见附录 B。自动合并不能豁免审查,尤其包括 render_layer.hpp、paint_parameters.*、render_target.*、gfx/context.hpp、mtl/offscreen_texture.cpp、mtl/texture2d.cpp。
4.1 目标源码证据与合并含义
| 位置 / 函数 | 已核实差异 | 迁移处理 |
|---|---|---|
目标 src/mln/renderer/render_layer.hpp:159,RenderLayer::update |
新增 const PaintParameters& 参数;该官方文件本次文本自动合并 |
同步 Particle/WeatherColor override、声明、普通/hidden cleanup/Fast Path 调用;不能只修改 factory |
目标 src/mln/renderer/renderer_impl.cpp:184、:224、:302 |
使用 renderableSize 构造 PaintParameters,并以其作为 UBO world size |
retained viewport/key、scissor、target size 与主画布统一取当前 frame 数据 |
目标 src/mln/renderer/render_static_data.hpp |
删除 backendSize,增加 symbol geometry 方法 |
.21 renderer_impl.cpp:745、:766 等旧引用需适配;不能恢复旧字段掩盖所有权变化 |
目标 src/mln/renderer/render_orchestrator.cpp,updateLayers / onSymbolError |
传递新 PaintParameters,并增加 symbol error 转发 | 外提适配器须保留官方 observer 行为,包括 .21 自有的 source revision 和 teardown |
目标 src/mln/renderer/render_source.cpp / include/mln/style/types.hpp |
新增 CustomMVTVector 与 source factory 分支 | 合并保留官方新增 source 与自定义 RasterArray,source dependency 不认识的新类型需 fail closed |
目标 src/mln/renderer/render_target.cpp、include/mln/gfx/context.hpp |
审查的归一 diff 无其它差异;本地追加 isRenderable / depth-stencil 接口 | 可保留薄能力接口,仍做 GL/Metal clear、bind、恢复验证 |
目标 src/mln/mtl/render_pass.cpp |
保存 commandBuffer,并修改 encoder 构造附近代码 | 合并自有 clear/store 与 vertex texture 逻辑时同时保留官方 commandBuffer 生命周期 |
目标 src/mln/mtl/offscreen_texture.cpp |
官方也已把基类构造参数 size 修正为 size_ |
删除重复维护的修复补丁;保留并单独审查自有 stencil/renderability 扩展 |
| 两条目标 shader_manifest | Git 不识别为 rename,旧头删除与我方追加冲突 | 按新 shader manifest/生成机制注册扩展,不能把旧头直接并排保留 |
44 个位置冲突解决为“搬到 mln”后,文件内容仍可能保留 namespace mbgl / <mbgl/...>。标准结果 tree 中还保留 25 个 /mbgl/ 路径:24 个完全新增的 particle 子树文件及旧 shader_manifest。已直接读取模拟结果,确认搬到 src/mln/renderer/layers/render_raster_particle_layer.hpp 的内容仍是旧 namespace/include 和旧 update 签名。因此“解决冲突标记”不是完整升级;新增纯模块也需要机械命名迁移。
5. Particle 耦合清单
5.1 可保留的独立模块与实际边界
| 代码证据 | 独立性判断 | 适配重点 |
|---|---|---|
src/mbgl/particle/field/field_runtime.cpp:173,FieldSeries::submit;:223,resolve |
Shared Core 内按 validTime 排序、候选集合原子校验后 swap;exact 时 T0/T1 指向同帧;插值检查批次身份;不依赖 renderer | 迁移 namespace/include,保留 C-002 八帧、拒绝零淘汰与单帧真实时刻语义 |
src/mbgl/particle/ingress/qbin_v2_decoder.cpp:75,EncodedFieldIngress::decodeAndValidate |
字节解码→profile 校验→decoded frame,在 Core;未把 HTTP/provider 放进 renderer | 二进制/数值/错误枚举一致性;不得用升级机会改变 QBIN 公共契约 |
src/mbgl/style/sources/raster_array_source.cpp:431,submitEncodedField |
host metadata/contract/raw bytes→Ingress→Store→refreshV4RendererState;不在提交中偷偷改目标时间 | Source::Impl/observer 桥是版本适配层;建议把 Store/Projection 协调留在专用 runtime,不继续扩充官方 Map |
src/mbgl/renderer/layers/render_particle_validation_layer.cpp:1175,prepare |
只消费 RenderRasterArraySource projection,绑定 T0/T1/mix;没有平台专属引擎 | 此 renderer 源文件实际实现正式 RenderRasterParticleLayer,不能按文件名把它当可删除测试 |
同文件 ParticleGpuResources:320、update:1211、GPU tweaker:524 |
state/trail A/B、shader、texture、timeline 与 context 生命周期集中在新增文件;使用 gfx 资源 | 2136 行集成了 fixture/正式路径、GPU pass、时钟和诊断;P1 外提资源与 pass executor,保持 engine 一套 |
render_weather_color_layer.cpp:163、prepare:197、update:229 |
与 Particle 有独立 class/resources,消费同一 projection;scalar/vector magnitude 分离 | 复用 HeatmapTextureLayoutVertex/RenderStaticData geometry(:274)是内部布局耦合,宜专用 quad adapter |
render_particle_validation_layer.cpp:1141、:1157、:1223 |
layerRemoved 移除注册 target;contextDestroyed 标志;清空 field 时清 drawable、解除 target/tweaker/resource 环 | 跨版本必须保持 render-thread 销毁;不能用任意 UI 线程 delete 或通用 shared_ptr 推断无环 |
src/mbgl/layermanager/raster_particle_layer_factory.cpp:19 |
创建专用 RenderRasterParticleLayer;default/Android/Darwin 仅注册类型 | factory 注册、SourceType、source switch 是真正应保留的薄 hook |
本次口径仅取 src/ 与 include/ 下所有 base→HEAD 变化:68 个新增文件、11438 新增行;47 个官方既有文件、2035 新增行/133 删除行。新增文件承载新增行比例 84.90%,不是目标“约 95%”;它是可复现的近似工程指标,不是全部平台/测试代码比例,更不能衡量语义独立性。附录 C 列出 68 个新增 Core 文件;另外 612 个新增路径主要为文档、平台/测试、RN、fixture、集成与工具,不可拿它们稀释核心耦合。
5.2 真正 thin hook、可外提和深耦合
- 不可避免的官方接入 hook:LayerManager 三平台注册、SourceType/RenderSource factory、shader registry/enum/清单、repaint/hidden-source-cleanup 扩展点、Map runtime state 传递、PaintParameters target 边界重置。目标是窄调用和能力描述,不在 hook 中展开业务策略。
- 可外提的官方修改:
style/conversion/source.cpp:206的 103 行 RasterArray parser 应移到专用 converter;map/map_impl.cpp:115的 RasterArray 类型扫描/forecast tick 应由 source frame participant 适配器承担;JNInative_map_view.cpp:1192的 field/layer 控制实现、MapLibreMap/MLNMapView diagnostics 可委托独立 facade。公开方法与生命周期所有者仍留在正式 SDK,不能以 global map registry 替代。 - 深耦合必须分步重构:Renderer::Impl 直接组织段 key/revision/cache 与主 buffer;RenderOrchestrator 同时管理 topology、dependency、source readiness、placement 与快路径;MTL Texture2D::bind 对所有纹理镜像 vertex binding,影响所有官方层,宜改为 shader-stage-aware backend 能力。
- 通用 backend 修复应独立维护/争取上游化:offscreen depth/stencil、clear/store、attachment-aware pipeline key。这些不能全塞入 Particle 私有 adapter,否则普通地图 target 仍可能不一致;保留在 gfx 的窄语义接口,并隔离成单独补丁与回归项。
- Vulkan 尚不能宣称等价:现有新增 shader 源及注册明确覆盖 GL/Metal;在
src/mbgl/vulkan、include/mbgl/shaders/vulkan、cmake/vulkan.cmake未找到 ParticleGpuValidation/RetainedUnderlayComposite 注册。context 的 override 补齐不等于 Vulkan 粒子功能已实现。后续必须验证能力返回/fail-closed 与专用实现,不能继承早期普通 Vulkan 构建 PASS。
6. RenderSegment 耦合清单
| 主题 | .21 已实现事实 |
未来兼容约束 / 验收 |
|---|---|---|
| 单一 topology | render_segment_plan.hpp:32 解析 explicit/legacy/continuous-range;:160 检查完整覆盖;全局 Style index 不重新编号 |
boundary 删除、重排、hidden、新插层、非法 JSON 均重解;不能复用旧合法 cache 掩盖非法 plan |
| source→segment | include/mbgl/renderer/render_segment.hpp:50 从 Style metadata 统一推导依赖;:114 RevisionBook;orchestrator:1172 查询 source loaded/fading |
shared source 使多个段失效;无 source 的 background 不造依赖;custom/unknown/missing fail closed;remove/recreate 同 id 保留 revision 身份 |
| 分层失效 | renderer_impl:631–676 合并 source revision、layer fingerprint、pixelRatio,逐段 Build/Reuse/Fallback;orchestrator:260 保留全局 revision | source/tile/feature-state 走 source epoch;image/glyph/style/context 等共享事件走 global epoch;不能漏掉新的官方 mutation 入口 |
| loaded 与局部复用 | orchestrator:698 仍是 styleLoaded && isLoaded();full CPU segment gate 用自己的 dependency/readiness |
unrelated unloaded source 可阻塞 global loaded/快路径,不能据此禁用无关段的局部复用;也不能改 loaded 语义造 PASS |
| placement | render_segment.hpp:75 结构性 symbol 能力;renderer_impl:645–656 按段 gate |
无 symbol 段可在别段 placement 活跃时复用;含 symbol 段仍受 changed/fade/transition 约束;不是 segment-local placement 算法 |
| Fast Path | renderer.cpp:47 尝试快路径;:51 在全帧前释放 prepared tree;renderer_impl:199 起匹配签名/全局内容/拓扑/cache/稳定性;particle_fast_path.hpp:97 逐项 gate | singleContinuous 限制保持;sources/layers/images/light/font 等身份或参数变化必须回全帧;新增上游输入必须纳入签名,不能只检查 camera |
| 全局限制 | orchestrator:1155 的 retainedRangeIsStable 检查所有 source fading;快路径 dynamic state 含 pending/light/placement/非粒子 repaint/annotation | STEP-100/102 的 full CPU 局部复用不等于快路径局部化;多 Continuous 正常执行仍需 full CPU |
| Style / pass 顺序 | renderer_impl:805 构建 retained 段;:880/:904 opaque reverse/translucent forward;保留 layerGroup 原 ordinal 与全局 depthRange;:1005 顺序执行 composite/live | 半透明 fill/line/symbol、跨段遮挡与自定义层必须视觉对照;3D、debug、custom、legacy 等保守退回 live,不可简单按段局部重编号 |
| Top / Bottom | renderer_impl:506–524 按 segmentIndex 创建独立 cache;遇到首个 Continuous 后用 Top 兼容 role;cache:310 透明 clear,:286 禁 depth composite | Top/Bottom 是旧诊断兼容角色,不是只有两张 texture;多段以 segment diagnostics 为准,不能复用 Bottom texture 充当 Top |
| Context / target | paint_parameters.cpp:111 beginRenderTarget 清 stencil ID 和 tile mask;cache:246 depth+stencil offscreen、:310 clear、:320 present | 新目标 renderableSize、Metal attachment 格式/commandBuffer 与 GL FBO/stencil 恢复都要测;context generation 变化不得复用旧 texture |
| 所有权 / teardown | orchestrator:180–209 两次 tagged drain、中间 detach observer 并销毁 sources;render_source.cpp:74 nullObserver;renderer prepared tree 在替换前丢弃引用 | tagged drain 不等于排空独立 render jobs;reset 循环、source cancel 回调、style reload、后台恢复必须独立验证 |
建议内部抽出 SegmentPlanner/DependencyTracker(不持 GPU)、RetainedSegmentExecutor(持 cache、执行顺序与 target scope)、FrameReuseAdapter(官方 Update/Paint/Placement 输入映射)、ParticleGpuResources/PassExecutor(动画资源)。这些是建议职责,不是本轮新建 API。官方文件只传入明确 snapshot/事件并调用;资源生命周期和 Style 顺序必须保留在 renderer 所有权范围,不能外提成第二个 renderer。
7. RN 11.5.0 适配风险
7.1 官方信息与未取得材料
RN v11.4.0 官方 release 明确升级 Android Native 13.6.1、iOS Native 6.31.0;官方 release 列表 记载 v11.4.1 的 iOS SPM target 挂接修复;v11.5.0 release 增加 feature state API。这是 release 证据,不是对 11.5.0 每个构建文件的逐行认证。
尝试 raw/GitHub 的 v11.5.0 android/build.gradle、Podspec 及 packages 子路径,返回 404 或 Cache miss,未取得完整 RN 目标源码。因此其私有 helper 签名、组件内部布局、Gradle property 名称是否保持均列为待核实,不伪造兼容结论。
7.2 当前包已核对的问题
| 文件与证据 | 风险与建议 |
|---|---|
packages/maplibre-particle-rn/package.json:34 / devDependencies |
MLRN peer/dev 均精确 11.3.6;迁移时与 consumer lockfile 一起更新,经兼容 Gate 后锁定新版本,不能用宽泛 range 掩盖不支持 |
app.plugin.js:22–23 |
已有 marker 就提前返回;项目升级若保留旧生成块,可能继续锁旧 .21。建议版本化且幂等替换受管块,验证重复 prebuild;本轮没有运行 prebuild |
app.plugin.js:23 / android/build.gradle:17 |
substitution 只覆盖 org.maplibre.gl:android-sdk-opengl;另直接 implementation 自有 .21;nativeVersion=13.4.1、variant=opengl |
MapLibreParticleRN.podspec:10–34 / :47 |
依赖 MLRN 11.3.6,借 $MLRN._add_spm_to_target 与 $MLRN_SPM_SPEC,属于私有 helper 耦合 |
ios/WeatherRuntimeBridge.mm:103–118 |
fresh Fabric registry→MLRNMapViewComponentView→contentView→MLRNMapView/MLNMapView;按类名识别内部组件 |
android/.../WeatherRuntimeBridgeModule.kt:363–369 |
Fabric resolveView、强类型 MLRNMapView、view.mapLibreMap |
src/NativeWeatherRuntimeBridge.ts / RendererRuntime.ts / 两端 bridge |
typed TS→schema JSON→platform→Core;V4 submit/time、attach/detach、diagnostics |
.21 Core orchestrator:1015–1046 |
set/removeFeatureState 已推进 source revision |
功能验证必须覆盖:1)单 SDK 依赖树和制品身份;2)Fabric 新旧 map attach/detach、style reload、销毁后调用、20 次 reset;3)V4 单帧向量持续运动、标量无粒子、双帧 mix、八帧滚动、跨批次 unavailable、坏帧零副作用;4)RenderSegment R-C-R/C-R/R-C/多段、连续与 retained 中 feature-state/GeoJSON 更新;5)相机/pitch/wrap/resize、mask、透明度/颜色定量;6)GL 与 iOS Metal context loss/后台恢复和内存趋势。Android/iOS 各自提交日志/截图/计数,不互相替代。
8. 改造优先级矩阵
工作量为相对估计:S=局部少量文件,M=跨数个接口/模块,L=跨执行链和平台 Gate;不是承诺工期。P0 指迁移正确性前置,P1 指长期维护治理,P2 指后续优化。
| 级别 / 项目 | 路径与当前耦合证据 | 方案 | 风险 / 工作量 | 验收标准 | Android / iOS |
|---|---|---|---|---|---|
| P0 命名与构建移植 | 68 新增 Core 文件、44 location 冲突、24 particle 文件未随目录移走;附录 A/B/C | 独立机械迁移补丁处理路径/namespace/include/清单;删旧 shader_manifest 接法 | 漏引用/并存 namespace,M | 全部自定义符号单 namespace,生成清单一致;无旧 include、缺失 source 或重复 shader | 共用 Core,双端 |
| P0 帧接口适配 | render_layer.hpp 新 PaintParameters;renderer_impl 旧 backendSize;新增粒子 override | 建立 FrameReuseAdapter,先接全帧,再接 Fast Path;不恢复被官方移除状态 | 错 viewport/override/失效输入,M | 同帧 size/matrix 一致;普通/hidden/Fast 三入口完整;编译与 resize Gate | GL/Vulkan/Metal |
| P0 执行边界 | renderer_impl.cpp:501–1020 +632/-39,orchestrator.cpp +505/-5 | 先外提 segment 决策/执行与官方输入映射,行为保持;策略不继续嵌入官方主函数 | Z-order、placement、stale cache,L | retained on/off 图像对照;global index/pass 顺序;source/placement/资源失败逐项验证 | 双端必测 |
| P0 offscreen / MTL 生命周期 | gfx context overload、paint target reset、mtl render_pass clear 与新 commandBuffer | 窄 offscreen descriptor/target scope,保留官方所有权并独立迁移通用修复 | stencil 污染/格式错配/释放次序,M | GL stencil;Metal clear depth/stencil、pipeline format、device/simulator、context reset | Android GL;iOS/Metal |
| P0 单 SDK 收敛 | RN package/plugin/podspec 与 .21 implementation |
同时更新支持锁、替换规则、SPM helper adapter 与发行 manifest | 双二进制/旧 API/生成块残留,M | Gradle/Pods/SPM 仅一个 Native;Symbols/headers 来自同一源码 | 两端分别验收 |
| P0 回归证据 | STEP-102 未完整运行验收即纳入 V21;STEP-103 本基线无文件 | 冻结旧版作对照;建立升级候选完整 Gate | 继承未知行为,M | 独立日志、同源制品 SHA、真实设备结果;无测试豁免冒充 PASS | 各平台明确状态 |
| P1 source dependency | render_segment.hpp:50 / RevisionBook;orchestrator:242/1172 | 从 diagnostics DTO 分离 typed dependency snapshot/event adapter,保持 shared/global/unknown | 新 source/feature-state 漏失效,M | 同 source 多段刷新,无关段 reuse,remove/recreate、unknown fail closed | 共用 |
| P1 GPU 模块外提 | render_particle_validation_layer.cpp 2136 行,Heatmap geometry 与资源环 | 专用 quad/资源/pass/lifecycle 模块,RenderLayer 只转发 | 跨 pass commit 与清理退化,M | 同样 state/trail generation、同帧推进一次、clear/reset 无泄漏 | GL/Metal;Vulkan另 Gate |
| P1 backend stage 抽象 | mtl/texture2d.cpp:262 全纹理镜像 vertex bind | 用 shader-stage/binding metadata 描述需要的 stage,通用修复尽量上游化 | 影响普通层 binding/cache,M | 既有地图 shader 与 Particle 都正确;无无效 stage 绑定 | iOS/Metal 主,Core接口共用 |
| P1 公共桥减重 | native_map_view.cpp:1192、MapLibreMap.java、MLNMapView.mm | 专用 Native facade/adapter 持实现,官方类保留方法与 map 生命周期 hook | JNI/ObjC API/销毁顺序,M | 方法签名不变,错误一致,stale tag/destroy callback 验证 | 两端 |
| P1 parser / 时钟薄接入 | style/conversion/source.cpp:206;map_impl.cpp:115 | RasterArray converter 外提;source frame participant tick | clock 改变错误/数据所有权,S–M | submit 不改目标时间;cadence/pause/background 正确 | 共用 |
| P1 Vulkan 能力闭环 | Vulkan 缺本任务 shader 注册证据 | 确认能力与 fail-closed;专用 backend 实现另立项 | 不支持被误报支持,L | Android Vulkan 粒子与 retained 实测;不能只编译普通地图 | Android Vulkan |
| P2 多 Continuous Fast Path | singleContinuousSegment / 全局 signature | 先保留 full CPU;待依赖模型和预算稳定再单独设计 | 跨段 placement/顺序/上传遗漏,L | 多段对照、source mutation/placement 全组合,必要时 RFC | 共用 |
| P2 footprint 预算与上游补丁 | 85 官方修改、47 Core 原文件 | 建 ledger、自动审计、补丁主题拆分、删除已上游化修复 | 日常维护成本,S | 每版本 diff/冲突/功能 gate 有独立可复现证据 | 共用 |
不是所有 P1 都应阻塞首个候选。Field/Ingress/Binding、专用 layer/factory 和窄注册点可以在机械迁移后直接移植;Renderer 调度与新帧接口、offscreen 生命周期、单 SDK 必须先界定并验证。不得先做多段高级优化再补基础升级验收。
9. 阶段性迁移与验收
Gate 0:冻结与可回滚准备
RDC 回读 origin HEAD,认证两个官方 tag→SHA,归档 .21 的源码/manifest/制品;取得 RN 11.5.0 完整源码、11.3.6→11.5.0 diff。统一选择一个 Shared Core 候选:iOS 目标包含 Android 目标,但能否由该 commit 同时发行两端须构建验证,不能据祖先关系直接定版。本轮只给建议,不创建升级分支。
回滚点:保留 .21 不可变制品与 consumer 锁。任何 Gate 失败,停止推进;候选分支可丢弃,生产分支/旧制品不覆盖。需运行回退时可用既有 map-scoped retained enable 开关关闭优化,另保留完整旧版本回退;不把关闭功能当作新版本通过。
Gate 1:行为保持的边界整理
在旧基线单独重构 segment executor / frame adapter / target scope;保持 C-001/C-002、Style 顺序与既有 fail-closed,不顺带提高 Fast Path 支持范围。RDC 完成旧基线等价回归后冻结此检查点。若无法保持行为,停下修复,不混进 namespace 迁移使定位困难。
Gate 2:机械迁移与 Native 三方整合
从选定官方目标在隔离候选中按主题移植:Core/字段→类型注册→shader/backend→Renderer adapter→平台 bridge→测试/发行清单。先统一 mln namespace/include,适配 PaintParameters/renderableSize、source enum、symbol observer;处理 shader_manifest 删除和官方已有修复。保留官方新功能,禁止整文件选 ours/theirs。
RDC 记录每主题冲突解决、构建日志和 patch footprint;无冲突标记、无未注册新 shader/重复 namespace 后才进入功能 Gate。Android 和 iOS release tag 是同仓库不同发布点,不建立两套 Core fork。
Gate 3:分 backend / 平台验证
由 RDC 在目标版本实际支持的 CMake/Bazel target 上配置/编译;本次没有替它运行。可复用旧仓库文档中的 host 路径仅作候选,目标改名后应以配置输出确定 runner,不能硬称 mbgl-test-runner 必然保留。已有 runner 的定向过滤器如下(由 RDC 设置真实路径):
"$UPSTREAM_AUDIT_TEST_RUNNER" --gtest_filter='Particle*.*:Source.RasterArray*:Retained*.*:ContinuousLayerRange.*:RenderSegment*.*:RenderOrchestratorTeardown.*'
该变量必须指向同候选源码构建的测试程序。额外执行官方基础地图回归。Android Gradle/APK/安装/ADB/实体机仍按用户手工规则;iOS/Metal host 编译不能替代 iOS 设备。GL、Vulkan、Metal 分别记录结果,不以某 backend 通过覆盖其它 backend。
硬门槛:R-C-R 动态 source 只刷依赖段;无关 source 永久 unloaded 时局部 retained 仍可复用;含 symbol / 无 symbol 的 placement 场景正确;global live fallback 不错过图层;feature-state set/remove 使依赖段更新;camera/pitch/wrap/resize/context reset 无旧纹理;20 次 teardown、clear/reload 无回调到已销毁对象;单帧/八帧 C-002 同两端语义;定量 WeatherColor 和统一 mask 不退化。记录实际 build/reuse/invalidation、actualExecution、sourceRevision、fastPath miss reason、日志与图像对照。
Gate 4:RN 与发行
确认 Android 每个 debug/release dependency graph 中仅自有一个 Native SDK;由用户手工 Gradle 验证 dependencyInsight 和 APK so 唯一性。iOS 检查 Podfile.lock、Package.resolved、Pods/宿主 target 的同一个 MapLibre SPM product 与私有 helper 兼容。两端 Fabric bridge 功能通过后,再由授权发行任务升版本、build/publish/readback/finalize;不覆盖 .21,manifest 绑定同一源码。
必须回 Integration RFC/Contract 的情形:公共 API/返回值/错误、attach/detach 与资源所有权、QBIN/profile/time/window/mask 语义、Host/Native 责任边界、Android/iOS 公共行为产生分叉;或希望把多 Continuous/placement 新语义公开为能力。纯 namespace、内部模块外提和行为保持适配不自动要求新 Contract。
长期跟踪与 patch footprint budget(建议,未修改总则)
每个官方 release 单独审计 SHA/merge-base、rename-aware diff、三方冲突和自动合并后的行为清单。维护四组补丁:独立扩展、注册 hook、通用 backend 修复、平台/发行;每组有 owner、原因、上游替代情况和回归场景。不能只重放历史 Step 提交而不核对最终 diff。
建议预算:新增功能中 ≥95% 实现新增行进入专用模块(排除文档/fixture/generated/tests 的分母);官方函数内 hook 原则上一个调用、每处目标 ≤10 行;超过 30 行策略逻辑须评审外提;一次功能新增官方接点 >3 个须解释;本轮先让 47 个 Core 既有文件的修改规模不增长,重点把 renderer_impl/orchestrator 的新增策略行量减少至少一半,最终数字由行为保持 Gate 核定。预算是预警,不可为达数字拆碎代码或把复杂性藏进宏。
长期收益:把下一次官方 renderer 签名变化限制到 adapter/窄 hook;Field/GPU 逻辑继续复用。仍需承担 backend 与 Fabric 私有接口回归费用;“新增文件比例高”无法消除 API/ABI 和行为升级成本。
10. 阻塞和未知
- 本次没有实际编译/测试/设备/发布,所有升级运行验收为 NOT RUN;静态审计与 merge-tree 不等于功能 PASS。
- RN 11.5.0 目标源码未完整取得,私有 SPM helper/Fabric 细节待 RDC 审核;本地 Native tags 与实时 origin HEAD 未认证。
.21STEP-102 记录明确以源码审查接受部分未跑 Gate 后发行;本轮不将其补写为运行 PASS。STEP-103 不在冻结基线,不能用未合入实现支持结论。- Vulkan 粒子/retained 注册缺口、Metal vertex texture 全局绑定、资源环与 target clear 的跨设备行为需专项验证;没有测量内存/FPS,不给性能承诺。
- 完整 target source 不是全部逐文件审完;重点读取了本报告所列函数与自动合并热点,未下载到的 RN 文件已单列。单次三方模拟只能描述指定 SHA,不能预测所有未来上游版本。
- Git 收尾待 RDC 验收。未 commit/push,未收到执行器的最终 Git 回执。
11. 实际模型、退出状态与文件修改清单
实际配置来自当前会话 JSONL,不由默认 config.toml 或自称推断:
文件:/Users/tei/.codex/sessions/2026/10/09/rollout-2026-10-09T08-48-37-01a11deb-3653-73b2-8b2d-43f0e59ccc3a.jsonl
第 1 行:session_meta
id=01a11deb-3653-73b2-8b2d-43f0e59ccc3a
cwd=/Users/tei/dev/MapLibreParticleLab-upstream-audit-20261009
originator=codex_exec; cli_version=0.161.0; source=exec; model_provider=openai
第 8 行:turn_context,时间 2026-10-08T23:48:46.536Z
model=gpt-6-astra
effort=high
collaboration_mode.settings.model=gpt-6-astra
collaboration_mode.settings.reasoning_effort=high
环境 CODEX_THREAD_ID 与上述 id 一致。
模型 Gate 符合 GPT-6 Astra High;未切换模型或推理档位。本 Codex 执行器进程最终退出码在本轮结束前无法由本进程自证,待 RDC 从外层执行器回执填写。 不把任意 shell 的 exit 0 或本报告写入成功当成 Codex 全任务退出 0;已观测的 dry-run exit 1、失败 exit 128 和检查退出状态见本报告及末尾收尾记录。
实际项目修改:只新增 docs/报告/UPSTREAM-001_MapLibre官方升级兼容性架构审计_Codex完成报告_v1.md。预先存在的未跟踪 docs/40_任务/UPSTREAM-001_MapLibre官方升级兼容性架构审计_Codex任务_v1.md 未修改。没有生成其它项目文档,因此没有更新 Step 或开发记录;本任务明确只允许这两份文档,优先于常规收尾规则。
独立验收需要:本报告、下列全路径表/命令/哈希、原始干跑 stdout/stderr、当前 JSONL 开始配置与外层结束回执、工作树 scoped diff、远端 HEAD 回读,以及后续单独授权的构建/设备证据。本轮可交付审计结论,不可交付新 SDK 功能 PASS。
附录 A:标准干跑完整冲突路径
路径为 merge-tree 的 unmerged 路径;mln 是模拟目标路径,并未创建到源码工作树。— 表示该升级线无此冲突。位置冲突不等于文本冲突。
| 路径 | Android | iOS |
|---|---|---|
CMakeLists.txt |
文本 | 文本 |
bazel/core.bzl |
文本 | 文本 |
cmake/metal.cmake |
文本 | 文本 |
cmake/opengl.cmake |
文本 | 文本 |
include/mbgl/shaders/shader_manifest.hpp |
修改/删除 | 修改/删除 |
include/mln/layermanager/particle_validation_layer_factory.hpp |
位置 | 位置 |
include/mln/layermanager/raster_particle_layer_factory.hpp |
位置 | 位置 |
include/mln/layermanager/weather_color_layer_factory.hpp |
位置 | 位置 |
include/mln/map/map.hpp |
文本 | 文本 |
include/mln/renderer/layers/weather_color_texture_lifecycle.hpp |
位置 | 位置 |
include/mln/renderer/render_segment.hpp |
位置 | 位置 |
include/mln/renderer/retained_underlay.hpp |
位置 | 位置 |
include/mln/shaders/gl/particle_gpu_validation.hpp |
位置 | 位置 |
include/mln/shaders/gl/retained_underlay_composite.hpp |
位置 | 位置 |
include/mln/shaders/mtl/particle_gpu_validation.hpp |
位置 | 位置 |
include/mln/shaders/mtl/retained_underlay_composite.hpp |
位置 | 位置 |
include/mln/shaders/particle_gpu_validation_ubo.hpp |
位置 | 位置 |
include/mln/style/layers/particle_validation_layer.hpp |
位置 | 位置 |
include/mln/style/layers/raster_particle_layer.hpp |
位置 | 位置 |
include/mln/style/layers/weather_color_layer.hpp |
位置 | 位置 |
include/mln/style/layers/weather_color_stop.hpp |
位置 | 位置 |
include/mln/style/sources/raster_array_source.hpp |
位置 | 位置 |
include/mln/style/types.hpp |
文本 | 文本 |
platform/android/MapLibreAndroid/src/cpp/native_map_view.cpp |
文本 | 文本 |
platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/FeatureOverviewActivity.kt |
文本 | 文本 |
platform/android/MapLibreAndroidTestApp/src/main/res/values/strings.xml |
文本 | 文本 |
platform/android/VERSION |
文本 | 文本 |
platform/android/buildSrc/src/main/kotlin/maplibre.gradle-publish.gradle.kts |
文本 | 文本 |
platform/darwin/src/MLNStyleLayerManager.mm |
— | 文本 |
platform/default/src/mln/layermanager/layer_manager.cpp |
文本 | 文本 |
platform/ios/src/MLNMapView.mm |
文本 | 文本 |
src/mln/gl/offscreen_texture.cpp |
文本 | 文本 |
src/mln/layermanager/particle_validation_layer_factory.cpp |
位置 | 位置 |
src/mln/layermanager/raster_particle_layer_factory.cpp |
位置 | 位置 |
src/mln/layermanager/weather_color_layer_factory.cpp |
位置 | 位置 |
src/mln/map/map_impl.cpp |
文本 | 文本 |
src/mln/map/map_impl.hpp |
文本 | 文本 |
src/mln/mtl/render_pass.cpp |
文本 | 文本 |
src/mln/mtl/renderer_backend.cpp |
文本 | 文本 |
src/mln/renderer/continuous_layer_range.hpp |
位置 | 位置 |
src/mln/renderer/layers/render_particle_validation_layer.cpp |
位置 | 位置 |
src/mln/renderer/layers/render_particle_validation_layer.hpp |
位置 | 位置 |
src/mln/renderer/layers/render_raster_particle_layer.hpp |
位置 | 位置 |
src/mln/renderer/layers/render_weather_color_layer.cpp |
位置 | 位置 |
src/mln/renderer/layers/render_weather_color_layer.hpp |
位置 | 位置 |
src/mln/renderer/particle_fast_path.hpp |
位置 | 位置 |
src/mln/renderer/particle_viewport_reseed.hpp |
位置 | 位置 |
src/mln/renderer/render_orchestrator.cpp |
文本 | 文本 |
src/mln/renderer/render_orchestrator.hpp |
文本 | 文本 |
src/mln/renderer/render_segment_json.hpp |
位置 | 位置 |
src/mln/renderer/render_segment_plan.hpp |
位置 | 位置 |
src/mln/renderer/render_source.cpp |
文本 | 文本 |
src/mln/renderer/renderer.cpp |
文本 | 文本 |
src/mln/renderer/renderer_impl.cpp |
文本 | 文本 |
src/mln/renderer/renderer_impl.hpp |
文本 | 文本 |
src/mln/renderer/retained_underlay_cache.cpp |
位置 | 位置 |
src/mln/renderer/retained_underlay_cache.hpp |
位置 | 位置 |
src/mln/renderer/retained_underlay_runtime_state.hpp |
位置 | 位置 |
src/mln/renderer/sources/render_raster_array_source.hpp |
位置 | 位置 |
src/mln/renderer/update_parameters.hpp |
文本 | 文本 |
src/mln/shaders/mtl/particle_gpu_validation.cpp |
位置 | 位置 |
src/mln/shaders/mtl/retained_underlay_composite.cpp |
位置 | 位置 |
src/mln/shaders/mtl/shader_program.cpp |
文本 | 文本 |
src/mln/shaders/shader_source.cpp |
— | 文本 |
src/mln/style/conversion/source.cpp |
文本 | 文本 |
src/mln/style/layers/particle_render_layer_properties.hpp |
位置 | 位置 |
src/mln/style/layers/particle_validation_layer.cpp |
位置 | 位置 |
src/mln/style/layers/particle_validation_layer_impl.hpp |
位置 | 位置 |
src/mln/style/layers/raster_particle_layer.cpp |
位置 | 位置 |
src/mln/style/layers/raster_particle_layer_impl.hpp |
位置 | 位置 |
src/mln/style/layers/weather_color_layer.cpp |
位置 | 位置 |
src/mln/style/layers/weather_color_layer_impl.hpp |
位置 | 位置 |
src/mln/style/sources/raster_array_source.cpp |
位置 | 位置 |
src/mln/style/sources/raster_array_source_impl.hpp |
位置 | 位置 |
test/CMakeLists.txt |
文本 | 文本 |
test/gl/gl_functions.test.cpp |
文本 | 文本 |
test/style/source.test.cpp |
文本 | 文本 |
test/style/style_layer.test.cpp |
文本 | 文本 |
附录 B:85 个官方既有修改文件逐项清单
+/- 来自 base→HEAD numstat;行号是首个修改 hunk 的 HEAD 起始行,详细函数解释见正文。主分类不抹除平台桥中的可外提逻辑。A/I:C 文本冲突、D 修改/删除、净 交叉但自动合并、未交叉 仅我方变动。旧路径迁移到 mln 后计同一文件。
| HEAD 路径:行 | +/- | 主分类 | 当前耦合/处理 | A / I |
|---|---|---|---|---|
.gitignore:16 |
+1/-0 | 构建/平台 | 忽略本地 artifact | 未交叉 / 净 |
CMakeLists.txt:183 |
+54/-0 | 构建/平台 | 扩展 source/header/shader 清单接入 | C / C |
bazel/core.bzl:102 |
+67/-0 | 构建/平台 | 扩展 source/header/shader 清单接入 | C / C |
cmake/metal.cmake:50 |
+4/-0 | 构建/平台 | 扩展 source/header/shader 清单接入 | C / C |
cmake/opengl.cmake:40 |
+1/-0 | 构建/平台 | 扩展 source/header/shader 清单接入 | C / C |
include/mbgl/gfx/context.hpp:85 |
+4/-0 | 必要 hook | depth/stencil offscreen 虚接口 | 净 / 净 |
include/mbgl/map/map.hpp:17 |
+10/-0 | 必要 hook | 公开 retained/segment API | C / C |
include/mbgl/mtl/context.hpp:109 |
+4/-1 | 必要 hook | depth/stencil virtual override 声明 | 净 / 净 |
include/mbgl/mtl/render_pass.hpp:20 |
+23/-2 | 深耦合 | 新增 clear helper、vertex texture/sampler 缓存 | 净 / 净 |
include/mbgl/renderer/render_target.hpp:37 |
+3/-0 | 必要 hook | isRenderable 能力 | 净 / 净 |
include/mbgl/shaders/gl/shader_info.hpp:152 |
+14/-0 | 必要 hook | 新增 shader/UBO/texture/attribute 注册;生成机制随目标迁移 | 净 / 净 |
include/mbgl/shaders/shader_defines.hpp:130 |
+33/-0 | 必要 hook | 新增 shader/UBO/texture/attribute 注册;生成机制随目标迁移 | 净 / 净 |
include/mbgl/shaders/shader_manifest.hpp:27 |
+2/-0 | 必要 hook | 新增 shader/UBO/texture/attribute 注册;生成机制随目标迁移 | D / D |
include/mbgl/shaders/shader_source.hpp:33 |
+2/-0 | 必要 hook | 新增 shader/UBO/texture/attribute 注册;生成机制随目标迁移 | 净 / 净 |
include/mbgl/style/types.hpp:18 |
+2/-1 | 必要 hook | RasterArray SourceType | C / C |
include/mbgl/vulkan/context.hpp:109 |
+4/-1 | 必要 hook | depth/stencil virtual override 声明 | 净 / 净 |
include/mbgl/webgpu/context.hpp:46 |
+4/-1 | 必要 hook | depth/stencil virtual override 声明 | 净 / 净 |
platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp:198 |
+4/-0 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | 净 / 净 |
platform/android/MapLibreAndroid/src/cpp/native_map_view.cpp:6 |
+453/-0 | 构建/平台 | JNI field/layer/segment 实现可外提,官方类保留注册/生命周期 | C / C |
platform/android/MapLibreAndroid/src/cpp/native_map_view.hpp:204 |
+49/-0 | 构建/平台 | JNI facade 方法与签名 | 净 / 净 |
platform/android/MapLibreAndroid/src/cpp/style/layers/layer_manager.cpp:22 |
+7/-0 | 构建/平台 | Android Core-only factory 薄注册 | 净 / 净 |
platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/MapLibreMap.java:15 |
+243/-0 | 构建/平台 | runtime ownership、destroy listener、公开 facade,可外提实现 | 未交叉 / 未交叉 |
platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/NativeMap.java:142 |
+60/-0 | 构建/平台 | Native 内部接口表 | 未交叉 / 未交叉 |
platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/NativeMapView.java:656 |
+221/-0 | 构建/平台 | state guard 与 Native JNI 转发 | 净 / 净 |
platform/android/MapLibreAndroid/src/main/java/org/maplibre/android/maps/renderer/surfaceview/SurfaceViewMapRenderer.java:4 |
+3/-0 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | 未交叉 / 未交叉 |
platform/android/MapLibreAndroidTestApp/build.gradle.kts:19 |
+6/-1 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | 净 / 净 |
platform/android/MapLibreAndroidTestApp/src/main/AndroidManifest.xml:289 |
+13/-0 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | 净 / 净 |
platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/FeatureOverviewActivity.kt:11 |
+12/-0 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | C / C |
platform/android/MapLibreAndroidTestApp/src/main/res/layout/activity_feature_overview.xml:8 |
+12/-1 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | 未交叉 / 未交叉 |
platform/android/MapLibreAndroidTestApp/src/main/res/values/descriptions.xml:4 |
+1/-0 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | 净 / 净 |
platform/android/MapLibreAndroidTestApp/src/main/res/values/strings.xml:11 |
+45/-0 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | C / C |
platform/android/MapLibreAndroidTestApp/src/main/res/values/titles.xml:28 |
+1/-0 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | 净 / 净 |
platform/android/VERSION:1 |
+1/-1 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | C / C |
platform/android/buildSrc/src/main/kotlin/maplibre.artifact-settings.gradle.kts:1 |
+6/-6 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | 未交叉 / 未交叉 |
platform/android/buildSrc/src/main/kotlin/maplibre.gradle-publish.gradle.kts:7 |
+12/-0 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | C / C |
platform/darwin/src/MLNStyleLayerManager.mm:17 |
+7/-0 | 构建/平台 | Darwin factory 薄注册 | 净 / C |
platform/default/src/mbgl/layermanager/layer_manager.cpp:13 |
+7/-0 | 必要 hook | 注册三种新增 LayerFactory | C / C |
platform/default/src/mbgl/storage/offline_download.cpp:219 |
+8/-0 | 必要 hook | RasterArray 无 offline tileset,switch 明确忽略 | 净 / 净 |
platform/ios/BUILD.bazel:152 |
+0/-4 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | 未交叉 / 未交叉 |
platform/ios/app/CMakeLists.txt:27 |
+31/-0 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | 未交叉 / 未交叉 |
platform/ios/app/MBXViewController.mm:19 |
+741/-2 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | 未交叉 / 净 |
platform/ios/bazel/files.bzl:8 |
+2/-0 | 构建/平台 | 平台构建/发行/验证 App 或日志配套 | 未交叉 / 未交叉 |
platform/ios/src/MLNMapView.h:31 |
+64/-0 | 构建/平台 | 公开诊断与 segment 方法 | 未交叉 / 未交叉 |
platform/ios/src/MLNMapView.mm:8 |
+125/-0 | 构建/平台 | diagnostics ObjC 对象/JSON/Map 转发可委托专用 adapter | C / C |
platform/ios/src/Mapbox.h:45 |
+1/-0 | 构建/平台 | 导出 MLNParticleFieldRuntime | 未交叉 / 净 |
shaders/manifest.json:147 |
+14/-0 | 构建/平台 | 扩展 source/header/shader 清单接入 | 未交叉 / 净 |
src/mbgl/annotation/annotation_manager.cpp:224 |
+6/-0 | 必要 hook | hasPendingChanges 持锁读取 dirty,快路径观察 | 净 / 净 |
src/mbgl/annotation/annotation_manager.hpp:45 |
+1/-0 | 必要 hook | hasPendingChanges 声明 | 净 / 净 |
src/mbgl/gl/context.cpp:439 |
+27/-1 | 可外提 | 通用 depth/stencil FBO 能力,独立 backend 补丁/上游化 | 净 / 净 |
src/mbgl/gl/context.hpp:137 |
+6/-0 | 必要 hook | 通用 offscreen/FBO 声明 | 净 / 净 |
src/mbgl/gl/offscreen_texture.cpp:11 |
+19/-4 | 可外提 | 通用 attachment 实现,独立 backend 补丁 | C / C |
src/mbgl/gl/offscreen_texture.hpp:15 |
+3/-1 | 必要 hook | depth/stencil 构造参数 | 净 / 净 |
src/mbgl/gl/renderer_backend.cpp:138 |
+2/-0 | 必要 hook | 新增 shader/UBO/texture/attribute 注册;生成机制随目标迁移 | 净 / 净 |
src/mbgl/map/map.cpp:97 |
+32/-0 | 必要 hook | 公开配置/查询委托 runtime 并 onUpdate | 净 / 净 |
src/mbgl/map/map_impl.cpp:6 |
+10/-0 | 可外提 | 直接识别 RasterArray 并 tickForecastClock | C / C |
src/mbgl/map/map_impl.hpp:16 |
+3/-0 | 必要 hook | map-scoped runtime state 所有权 | C / C |
src/mbgl/mtl/offscreen_texture.cpp:8 |
+60/-10 | 可外提 | 通用 attachment/renderability 修复;官方已有 size_ 修复 | 净 / 净 |
src/mbgl/mtl/render_pass.cpp:9 |
+61/-13 | 深耦合 | clear/store/encoder/vertex binding 与官方 commandBuffer 合并 | C / C |
src/mbgl/mtl/renderer_backend.cpp:30 |
+4/-0 | 必要 hook | 新增 shader/UBO/texture/attribute 注册;生成机制随目标迁移 | C / C |
src/mbgl/mtl/texture2d.cpp:260 |
+4/-0 | 深耦合 | 所有 Texture2D::bind 镜像 vertex stage | 净 / 净 |
src/mbgl/renderer/layers/render_location_indicator_layer.hpp:47 |
+1/-0 | 必要 hook | legacy rendering 分类 | 净 / 净 |
src/mbgl/renderer/paint_parameters.cpp:111 |
+8/-0 | 必要 hook | beginRenderTarget 清 stencil id/mask cache | 净 / 净 |
src/mbgl/renderer/paint_parameters.hpp:115 |
+3/-0 | 必要 hook | target boundary 声明 | 净 / 净 |
src/mbgl/renderer/render_layer.hpp:109 |
+21/-0 | 必要 hook | repaint/粒子能力/legacy/hidden cleanup 默认虚函数 | 净 / 净 |
src/mbgl/renderer/render_orchestrator.cpp:2 |
+505/-5 | 深耦合 | 依赖/revision/placement/readiness/teardown 与官方调度交织 | C / C |
src/mbgl/renderer/render_orchestrator.hpp:18 |
+184/-1 | 深耦合 | 上述状态、事件、遍历方法与 mutex | C / C |
src/mbgl/renderer/render_source.cpp:11 |
+5/-1 | 必要 hook | RasterArray factory 与 nullObserver 恢复 | C / C |
src/mbgl/renderer/render_source.hpp:14 |
+21/-0 | 可外提 | readiness DTO/诊断方法与正式 source 类相连 | 净 / 净 |
src/mbgl/renderer/render_target.cpp:24 |
+5/-3 | 必要 hook | isRenderable 与 target boundary | 净 / 净 |
src/mbgl/renderer/render_tree.hpp:102 |
+11/-0 | 必要 hook | prepared tree 的快帧时间与 repaint 更新 | 净 / 净 |
src/mbgl/renderer/renderer.cpp:27 |
+14/-1 | 必要 hook | 先快帧、全帧前释放引用树、提交 prepared tree | C / C |
src/mbgl/renderer/renderer_impl.cpp:4 |
+632/-39 | 深耦合 | segment 决策/资源/执行与 Fast Path 主控制链 | C / C |
src/mbgl/renderer/renderer_impl.hpp:4 |
+63/-1 | 深耦合 | cache/prepared tree、UpdateParameters 镜像签名所有权 | C / C |
src/mbgl/renderer/sources/render_tile_source.cpp:489 |
+17/-0 | 可外提 | tilePyramid 计数诊断,可委托 source adapter | 净 / 净 |
src/mbgl/renderer/sources/render_tile_source.hpp:26 |
+1/-0 | 必要 hook | readiness 查询 override | 净 / 净 |
src/mbgl/renderer/update_parameters.hpp:12 |
+4/-0 | 必要 hook | 传递 map-scoped retained runtime state | C / C |
src/mbgl/shaders/gl/shader_info.cpp:290 |
+27/-0 | 必要 hook | 新增 shader/UBO/texture/attribute 注册;生成机制随目标迁移 | 净 / 净 |
src/mbgl/shaders/mtl/shader_program.cpp:12 |
+22/-9 | 可外提 | pipeline key 纳入 attachment format,独立通用修复 | C / C |
src/mbgl/shaders/shader_source.cpp:9 |
+40/-37 | 必要 hook | 新增 shader/UBO/texture/attribute 注册;生成机制随目标迁移 | 净 / C |
src/mbgl/style/conversion/source.cpp:13 |
+106/-0 | 可外提 | 103 行 RasterArray JSON parser 可独立 converter | C / C |
src/mbgl/style/types.cpp:15 |
+2/-1 | 必要 hook | raster-array 字符串映射 | 净 / 净 |
test/CMakeLists.txt:21 |
+16/-0 | 测试配套 | 新增类型/生命周期测试或平台条件;本轮未运行 | C / C |
test/gl/gl_functions.test.cpp:7 |
+11/-0 | 测试配套 | 新增类型/生命周期测试或平台条件;本轮未运行 | C / C |
test/style/source.test.cpp:15 |
+883/-0 | 测试配套 | 新增类型/生命周期测试或平台条件;本轮未运行 | C / C |
test/style/style_layer.test.cpp:19 |
+106/-0 | 测试配套 | 新增类型/生命周期测试或平台条件;本轮未运行 | C / C |
分类合计:构建/平台 32;必要 hook 34;深耦合 7;可外提 8;测试配套 4。各类相加为 85;分类为审计判断,不代表冲突严重性排序。
附录 C:68 个纯新增 Core 扩展文件
“纯新增”是 Git 身份,独立程度仍按正文函数审计;GPU/RenderSegment 新文件也存在官方内部 API 耦合。以下为完整 src/、include/ 新增清单(24 个 particle 子树文件、其余 44 个 layer/source/renderer/shader 等文件)。
include/mbgl/layermanager/particle_validation_layer_factory.hpp
include/mbgl/layermanager/raster_particle_layer_factory.hpp
include/mbgl/layermanager/weather_color_layer_factory.hpp
include/mbgl/particle/field/field_binding.hpp
include/mbgl/particle/field/field_data_adapter.hpp
include/mbgl/particle/field/field_profile_contract.hpp
include/mbgl/particle/field/field_profile_contract_json.hpp
include/mbgl/particle/field/field_profile_validator.hpp
include/mbgl/particle/field/field_projection_materialization.hpp
include/mbgl/particle/field/field_runtime.hpp
include/mbgl/particle/field/local_particle_field_feed.hpp
include/mbgl/particle/field/particle_gpu_math.hpp
include/mbgl/particle/ingress/encoded_field_transport.hpp
include/mbgl/particle/ingress/qbin_v2_decoder.hpp
include/mbgl/particle/ingress/qbin_v3_decoder.hpp
include/mbgl/particle/renderer_debug_counters.hpp
include/mbgl/renderer/layers/weather_color_texture_lifecycle.hpp
include/mbgl/renderer/render_segment.hpp
include/mbgl/renderer/retained_underlay.hpp
include/mbgl/shaders/gl/particle_gpu_validation.hpp
include/mbgl/shaders/gl/retained_underlay_composite.hpp
include/mbgl/shaders/mtl/particle_gpu_validation.hpp
include/mbgl/shaders/mtl/retained_underlay_composite.hpp
include/mbgl/shaders/particle_gpu_validation_ubo.hpp
include/mbgl/style/layers/particle_validation_layer.hpp
include/mbgl/style/layers/raster_particle_layer.hpp
include/mbgl/style/layers/weather_color_layer.hpp
include/mbgl/style/layers/weather_color_stop.hpp
include/mbgl/style/sources/raster_array_source.hpp
src/mbgl/layermanager/particle_validation_layer_factory.cpp
src/mbgl/layermanager/raster_particle_layer_factory.cpp
src/mbgl/layermanager/weather_color_layer_factory.cpp
src/mbgl/particle/field/field_binding.cpp
src/mbgl/particle/field/field_data_adapter.cpp
src/mbgl/particle/field/field_profile_contract_json.cpp
src/mbgl/particle/field/field_profile_validator.cpp
src/mbgl/particle/field/field_projection_materialization.cpp
src/mbgl/particle/field/field_runtime.cpp
src/mbgl/particle/field/local_particle_field_feed.cpp
src/mbgl/particle/field/offline_fixture_particle_adapter.cpp
src/mbgl/particle/field/offline_fixture_particle_adapter.hpp
src/mbgl/particle/ingress/qbin_v2_decoder.cpp
src/mbgl/particle/ingress/qbin_v3_decoder.cpp
src/mbgl/renderer/continuous_layer_range.hpp
src/mbgl/renderer/layers/render_particle_validation_layer.cpp
src/mbgl/renderer/layers/render_particle_validation_layer.hpp
src/mbgl/renderer/layers/render_raster_particle_layer.hpp
src/mbgl/renderer/layers/render_weather_color_layer.cpp
src/mbgl/renderer/layers/render_weather_color_layer.hpp
src/mbgl/renderer/particle_fast_path.hpp
src/mbgl/renderer/particle_viewport_reseed.hpp
src/mbgl/renderer/render_segment_json.hpp
src/mbgl/renderer/render_segment_plan.hpp
src/mbgl/renderer/retained_underlay_cache.cpp
src/mbgl/renderer/retained_underlay_cache.hpp
src/mbgl/renderer/retained_underlay_runtime_state.hpp
src/mbgl/renderer/sources/render_raster_array_source.hpp
src/mbgl/shaders/mtl/particle_gpu_validation.cpp
src/mbgl/shaders/mtl/retained_underlay_composite.cpp
src/mbgl/style/layers/particle_render_layer_properties.hpp
src/mbgl/style/layers/particle_validation_layer.cpp
src/mbgl/style/layers/particle_validation_layer_impl.hpp
src/mbgl/style/layers/raster_particle_layer.cpp
src/mbgl/style/layers/raster_particle_layer_impl.hpp
src/mbgl/style/layers/weather_color_layer.cpp
src/mbgl/style/layers/weather_color_layer_impl.hpp
src/mbgl/style/sources/raster_array_source.cpp
src/mbgl/style/sources/raster_array_source_impl.hpp
附录 D:可复现命令、退出状态与证据摘要
以下 Python 仅执行 Git 读取和 merge-tree 干跑,并将输出/object 写入新临时目录,不执行真实 merge/rebase 或更新源码/index/ref。在同工作区与 Git 2.54.0 下运行;若原对象不足/网络不可用,保留退出码并报告阻塞,不将空 stdout 算零冲突。本轮未设置 merge.renames/directoryRenames/renameLimit 或 diff.renames/renameLimit 覆盖;检查这些配置未发现显式条目。
import os, pathlib, subprocess, tempfile, json, re, collections, hashlib
BASE = "18545ca10d296704b2cba675b182ff2c8da24588"
OURS = "630ec657687bad4200c059bbccbb950d9c6f7ce9"
TARGETS = {
"android": "c7506d6aff3800e946f89e1a51432fc22d1a6534",
"ios": "01791ad02c1bfe3b22c42a97619b972aba962f82",
}
root = pathlib.Path(tempfile.mkdtemp(prefix="upstream-001-reproduce-"))
(root / "objects").mkdir()
original = subprocess.check_output([
"git", "rev-parse", "--path-format=absolute", "--git-path", "objects"
], text=True).strip()
env = dict(os.environ, GIT_OBJECT_DIRECTORY=str(root / "objects"),
GIT_ALTERNATE_OBJECT_DIRECTORIES=original)
def run(name, args):
r = subprocess.run(["git", *args], capture_output=True, env=env)
(root / (name + ".stdout")).write_bytes(r.stdout)
(root / (name + ".stderr")).write_bytes(r.stderr)
print(name, "exit", r.returncode,
"stdout-sha256", hashlib.sha256(r.stdout).hexdigest())
return r
def paths(r):
if r.returncode != 0:
raise RuntimeError("路径 diff 未完成,停止计数")
return {line.split("\t")[-1] for line in r.stdout.decode().splitlines()}
ours = paths(run("ours-paths", ["diff", "--no-renames", "--name-status", BASE, OURS]))
for label, target in TARGETS.items():
run(label + "-base", ["merge-base", OURS, target])
run(label + "-diff", ["diff", "--name-status", BASE, target])
upstream = paths(run(label + "-paths", ["diff", "--no-renames", "--name-status", BASE, target]))
overlap = ours & upstream
r = run(label + "-merge", ["merge-tree", "--write-tree", "--messages", OURS, target])
if r.returncode not in (0, 1) or not r.stdout:
print(label, "BLOCKED,冲突数未知")
continue
lines = r.stdout.decode().splitlines()
unmerged = {m.group(1) for line in lines
if (m := re.match(r"[0-7]{6} [0-9a-f]+ [123]\t(.+)$", line))}
kinds = collections.Counter(m.group(1) for line in lines
if (m := re.match(r"CONFLICT \(([^)]+)\)", line)))
clean = {p for p in overlap if p not in unmerged
and p.replace("/mbgl/", "/mln/") not in unmerged}
print(label, "tree", lines[0], "intersection", len(overlap),
"unmerged", len(unmerged), "types", dict(kinds), "clean-overlap", len(clean))
(root / (label + "-conflict-paths.txt")).write_text("\n".join(sorted(unmerged)) + "\n")
print("证据目录", root)
本轮临时对象库:/private/tmp/upstream-001-audit-20261009/objects;只读 alternate:/Users/tei/dev/MapLibreParticleLab/.git/objects。这是审计 worktree 原本共享的 Git object 来源,未操作其它工作树源码或状态。
| 证据文件(临时目录内) | SHA-256 | 说明 |
|---|---|---|
ours-no-renames.txt |
7e63240f4460f8c502dfec535b9fcbb0f11872ae221b87b550d68a05bb70bf48 |
Git 路径证据 |
android-rename-aware.txt |
fa42160229b3407eeaa13fd90d0dfb9c4d7425e8f0dfa860b01db1ff7f18984c |
Git 路径证据 |
ios-rename-aware.txt |
e836b7699dc32c8300f8b0bfdcad16be17eeb526c48057d9a16cfa7734f32e61 |
Git 路径证据 |
android-isolated-default.stdout |
3526b74fc8152e61f72641d571c16e9055500deb1cd31540f2eacf26047b4fb6 |
标准干跑,exit 1;复跑一致 |
ios-isolated-default.stdout |
d553091afaec4f381991bfbf6e60cd0d887177d5bccd172fac4f46e70f347261 |
标准干跑,exit 1;复跑一致 |
android-conflict-paths.txt |
4c61654d97bee7bca76879d9b828db8ca5c1d4a0610e3cfb6d43edeb73029039 |
Git 路径证据 |
ios-conflict-paths.txt |
013ebe7121eaea79bf8491a1e3a55198e87acc7865b7b27bda6fdf81da993235 |
Git 路径证据 |
首轮失败见 android/ios-diff.stderr、android/ios-merge.stderr;原目录权限失败见 android/ios-merge-no-renames.stderr;成功命令与 rc 见对应 .json;复跑比对见 android/ios-repeat.json。对照禁用 rename 的 tree 为 Android 59de9836b81e90c3fef4a5a0377454bd464f5ef9、iOS b419b471131eb4fa3244e5cc3082ee7f2bd8e1e9,仅用于证明 rename 口径影响,不用于迁移决策。
已观察退出状态:标准干跑两线均 1(冲突),路径 diff/merge-base 0;原始失败 128;报告最终静态检查见下节。Codex 进程最终状态和 Git 发布回执由外层执行器/RDC 独立补证。
附录 E:最终静态收尾记录
- 报告内复现脚本已原样提取并执行,脚本退出 0;其中两次 merge-tree 各退出 1,Android 76 / iOS 78 个路径与正文完全一致。该脚本退出 0 只表示采集/计数完成,不是升级 PASS。复现临时目录
/tmp/upstream-001-reproduce-58mf60um,采集日志位于主证据目录embedded-reproduce.stdout/.stderr。 git diff --check:退出 0,无输出;tracked 与 staged 的git diff --name-only均为空,退出 0。- 未跟踪报告另用
git diff --no-index --check /dev/null <报告>检查:退出 1,stdout/stderr 均为空;这里 1 表示新增文件有差异,没有空白错误,不解释为测试失败或运行成功。 - 报告要求的 11 个章节齐全,Markdown 围栏闭合;完整本地路径:行引用的文件均存在。冲突附录为 78 个并集路径,官方修改清单 85 个,新增 Core 清单 68 个。
- 收尾 HEAD 仍为
630ec657687bad4200c059bbccbb950d9c6f7ce9;工作树只有以下两份未跟踪文档,没有源码或已跟踪文件改动:
?? docs/40_任务/UPSTREAM-001_MapLibre官方升级兼容性架构审计_Codex任务_v1.md
?? docs/报告/UPSTREAM-001_MapLibre官方升级兼容性架构审计_Codex完成报告_v1.md
任务书 SHA-256:2e2ba4b5b1e94bedf0846cea616611eab758467a3e9ffaf01a4c8691fc01c112。本轮没有编辑任务书,未 commit/push。最终外层 Codex 进程退出码仍待执行器回执,Git 收尾待 RDC 验收。
附录 F:RDC Git 收尾回执(2026-10-09 JST)
本节为 Codex 完成后 RDC 独立验收补记;前述“Git 收尾待 RDC 验收”与“未 commit/push”均指 Codex 自身退出时的阶段事实,不再代表本附录写入后的状态。
- 审计结果:PASS(仅只读架构审计与文档核验)。目标升级结论仍为 CONDITIONAL GO,任何 Native/RN 构建、设备运行与发行均 NOT RUN。
- Codex 实际模型:gpt-6-astra / high;JSONL
turn.completed,外部执行器退出码 0。 - 独立验收:报告 12 个必须章节存在;Android 76、iOS 78 条冲突复核一致;
git diff --check通过。 - 功能文档提交:
2b4075b60ba7c7265e39e18168522bf7089f3a60。 - Commit message:
docs: audit upstream MapLibre Native upgrade compatibility。 - 推送结果:PASS;
origin/particle/main从630ec657687bad4200c059bbccbb950d9c6f7ce9快进至上述文档提交,远端 SHA 回读一致。 - 本次补记作为后续独立文档提交推送;其最终 SHA 以远端
origin/particle/main回读为准,不在提交内容中自引用。 - 本次没有修改任何产品源码、测试实现或用户原有 Mac 工作树。