4.8 KiB
STEP-081 iOS Metal Renderer 与真机 Smoke 入口设计 v1
状态:CLOSED / PASS。已在 Pleiades(iPad mini 5 / iPadOS 26.5.2)完成签名安装、Metal runtime、deterministic fixtures 与 QBIN V4 T0/MID/T1/Clear 真机验收。
目标和边界
Metal 路径消费既有 RasterArraySource V4 renderer projection、WeatherColorLayer 与 RasterParticleLayer。没有 iOS Field model、QBIN decoder 分支或公开 iOS SDK API。Smoke 代码仅在 platform/ios/app/MBXViewController.mm,RN iOS bridge 仍是明确非目标。
OpenGL → Metal pass 对照
u_pass.x |
OpenGL 既有语义 | Metal ParticleGpuValidationShader |
|---|---|---|
< 0.5 |
State A/B update / seed / respawn | 同一 T0/T1 decode、timeMix、VELOCITY/DIRECTION advection 与 fail-closed state write |
< 1.5 |
Trail fade | 同一 retention fade;legacy validation marker 保留 |
1.5–3.5 |
Composite / FrozenComposite | 同一 trail/particle 色彩、mask、speed-color 和 legacy diagnostic 分支 |
> 3.5 |
Trail particle line draw | State read/write displacement line,respawn alpha 抑制跨屏线 |
> 4.5 |
WeatherColor | 同一 scalar/vector magnitude、stops/ramp 和 invalid discard |
> 5.5 |
无 | Metal-only current-endpoint 1 px quad coverage;只补 raster coverage,不改变 State、速度、时间步或 previous→current 物理长度 |
MSL 使用 ParticleGpuValidationUBO 的同字段 vec4/float4x4 布局;声明与 C++ 的 alignas(16) 相同,并在 MSL 中静态断言 31 * 16 字节。此 Step 未改动 C++ UBO、QBIN V4 contract 或 OpenGL source。
Metal binding
| 类别 | Metal index | Stable ID |
|---|---|---|
vertex attribute short2 a_pos |
attribute 0 | idParticleGpuValidationPosVertexAttribute |
| UBO | buffer drawableReservedUBOCount |
idParticleGpuValidationUBO |
| previous | texture/sampler 0 | idParticleGpuValidationPreviousTexture |
| mask | texture/sampler 1 | idParticleGpuValidationMaskTexture |
| field T0 | texture/sampler 2 | idParticleGpuValidationFieldTexture |
| field T1 | texture/sampler 3 | idParticleGpuValidationNextFieldTexture |
| state | texture/sampler 4 | idParticleGpuValidationStateTexture |
这些 index 来自 Metal ShaderSource 的 attributes/textures 表以及 existing shader IDs,而非 OpenGL location 推测。注册位于 src/mbgl/mtl/renderer_backend.cpp,CMake source/include list 位于 cmake/metal.cmake。
Smoke 数据链
Test App Runtime Styling 菜单新增 Particle / QBIN V4 Smoke (T0)。点击后可选 T0、midpoint、T1 或 clear/release。它从 app bundle ParticleSmokeFixtures/T0.qbin、T1.qbin 读取现有 RN Wind Golden fixtures;platform/ios/app/CMakeLists.txt 在构建后从唯一 fixture 来源复制,不创建第二种数据格式。
private MLNMapView seam 提供 mbglMap。Smoke 直接创建 RasterArraySource,提交 fixture.wind T0/T1、Wind profile contract、ColorBinding 与 VectorComponents ParticleBinding,再添加 WeatherColorLayer 与 RasterParticleLayer。T0=1789239600000、midpoint=1789241400000、T1=1789243200000,全部通过 source-owned requested forecast time 选择窗口/mix。clear 先移除 layers 后移除 source,允许重复创建。Wind Golden fixture 实际范围为 112.5E..157.5E、0..55.776573N,Test App smoke 会把相机置于约 27.8883N / 135E、zoom 3,保证 FIELD_READY 后画面可观察;这只是 Test App 可视化入口,不改变 Core 数据范围。
Metal 真机收口结论
真机调试确认两个 Metal 特有问题并形成正式修复:
ShaderProgram::getRenderPipelineState()的缓存复用 key 原先只包含调用方 reuse hash,没有包含 color/depth/stencil attachment pixel format。粒子 State 使用 RGBA32Float、Trail 使用 RGBA8Unorm、主 renderable 常见 BGRA8Unorm,同一 shader 因此可能复用到不兼容的 pipeline。修复后 cache key 显式合并 color/depth/stencil format;物理 iPad 上 Trail RGBA8 写入从全零恢复为有效像素。- deterministic Vortex 实测真实 previous→current 线段平均约 0.065 px、最大约 0.24 px,全部小于 0.5 px。Metal
MTLPrimitiveTypeLine对该亚像素长度没有稳定可见覆盖。正式 previous→current line 保持不变,Metal 额外在真实 currentPosition 绘制 1 px quad coverage;不拉长轨迹、不改变 State、advection、时间步或物理速度。
同时确认 Metal vertex-stage texture/sampler binding、State A/B RGBA32Float、Trail A/B RGBA8、矩阵投影与 Composite 均可工作。
后续边界
STEP-081 已关闭。下一轮如需 iOS RN,必须另行设计桥接;不得把本 App 的 private Core seam 提升为 SDK 或 NavSea API。当前 Metal vertex+fragment 双阶段纹理绑定可在后续独立技术债中收窄为 stage-specific binding,但不得在 STEP-081 收尾中继续重构。