9.3 KiB
STEP-098 QBIN V4 单帧与八帧滚动缓存
状态:进行中(Codex 源码交付;等待 RDC 独立构建/定向测试及平台验收) 日期:2026-09-26(JST)
目标与基线
- 目标:单帧真实时刻首显、合法同批双帧插值、每
fieldKey最多八帧有序滚动,保留现有 RN API 两步调用。 - 仓库:Mac
/Users/tei/dev/MapLibreParticleLab;branchparticle/main;开工 HEADb1239ac3b1554943200e6fbf14321459ccc86527,结束时 HEAD 未变。 - Integration:
main/origin/main=1dd576d3304e267e53ed64d31f9711d2350ce10a;RFC-004、ADR-001、C-002、COORD-005 均已读。旧 RFC-003 阻塞由本轮明确的新接受契约解除;旧阻塞报告保留不改。 - 当前 Android Native/RN 坐标仍为
13.4.1-particle.13;本次未改版本或发布资产。iOS 基础版本6.28.0。 - 工作树开工已有 STEP-097 B 修改/未跟踪文件、STEP-098 原任务与旧阻塞报告;保留原样。
git submodule status全部与记录 SHA 一致。
本轮完成
FieldSeries在 exact validTime 返回真实单帧窗口;非精确时间只解析本地相邻 pair。- 按 key 区分共存 schema 与插值批次身份。新批次可进入滚动序列并按精确时间单帧显示;插值要求 fieldID、reference time、resolved profile ID/version 与 grid/plane schema 全部相同。Ingress 保存已验证 profile 身份。
- 满额候选集合先按新帧时间选择远端点,等距删除原最早端;通过 schema 邻接校验后原子 swap。拒绝帧不先淘汰。八帧以上正常插入使用既有成功结果。
- 新增 decoded raw-plane + validity 字节计数;单帧 T0/T1 共享一份 materialized Snapshot,WeatherColor/Particle 首次 GPU 安装共享相同 endpoint 资源。
- 扩展 Runtime、Binding、Ingress、RasterArraySource 定向测试代码,覆盖单帧/双帧/滚动/跨批次/原子拒绝/内存计数/重复清理场景;详见设计和完成报告矩阵。
- RN TypeScript、Android Kotlin/JNI、iOS bridge 静态核对:旧 API 名称、参数、返回类型和两步顺序不变;未修改 bridge。
- 新增中文设计文档与本报告;开发记录仅追加本轮事实。
修改范围
STEP-098 本轮源代码与测试:
include/mbgl/particle/field/field_runtime.hppsrc/mbgl/particle/field/field_runtime.cppsrc/mbgl/particle/field/field_projection_materialization.cppsrc/mbgl/particle/ingress/qbin_v2_decoder.cppsrc/mbgl/renderer/layers/render_particle_validation_layer.cppsrc/mbgl/renderer/layers/render_weather_color_layer.cpptest/particle/field_binding.test.cpptest/particle/field_runtime.test.cpptest/particle/qbin_v2_decoder.test.cpptest/source/raster_array_v4_host_api.test.cpp
文档/记录:
docs/30_设计/STEP-098_QBIN_V4单帧与八帧滚动缓存设计_v1.mddocs/50_Step记录/STEP-098_QBIN_V4单帧与八帧滚动缓存_v1.mddocs/报告/STEP-098_QBIN_V4单帧与八帧滚动缓存_Codex完成报告_v1.md- 根目录
粒子开发记录.md(追加)
未修改用户原任务书、STEP-097 的矩阵/记录/清单/桥接文件、NavSea/Server、QBIN 格式、版本锁、tag、manifest、制品。test/particle/field_runtime.test.cpp 与 test/source/raster_array_v4_host_api.test.cpp 开工前已有 B 阶段 dirty 内容;原 B 的 fixture 修正保留,本轮只叠加 STEP-098 测试,并为 Source 测试 QBIN helper 增加 forecast reference 参数。
API / ABI 与限制
- RN 和平台 bridge 公开方法签名/枚举名称:未变。
DecodedFieldFrame增加了解析 profile 身份字段,C++ 结构二进制布局变化;Native/RN 配套版本必须同源码重编。没有用.13旧 AAR 验证该结构。decodedByteSize()只计原始 plane storage 与 validity bitset,不含 profile 元数据、CPU 物化数组、图像、GPU texture、粒子/trail。没有执行 CPU/GPU 峰值或长时间泄漏测量。- 单帧 Particle 的实际 GPU 运动、GL/Metal texture 复用、context loss 和设备视觉尚待平台实测。
RDC 分阶段执行命令(本轮未运行)
B:Shared Core Store / Ingress / Binding
ninja -C build-step088-opengl mbgl-test-runner
build-step088-opengl/mbgl-test-runner --gtest_filter='ParticleFieldRuntime.*:ParticleFieldBinding.*:ParticleEncodedFieldIngress.*'
C:Projection / Source / Renderer 与 OpenGL、Metal host 回归
ninja -C build-step088-opengl mbgl-test-runner
build-step088-opengl/mbgl-test-runner --gtest_filter='Particle*.*:Source.RasterArray*'
ninja -C build-step097-metal-host mbgl-test-runner
build-step097-metal-host/mbgl-test-runner --gtest_filter='Particle*.*:Source.RasterArray*'
先完成 B 并检查结果,再执行 C;Metal host GTest 不等于 iOS 设备 Metal 通过。未通过/退出未知时停在原阶段。Codex 本轮只运行 git diff --check,未运行上述命令、Android Gradle、iOS/Xcode、Jest、设备或发布。
D:RN / 平台验证前置条件
RN 端确认现有顺序为成功 await submitEncodedField(...) 后才 await setEncodedForecastTime(...);失败提交不得调用 setTime。T17 使用 V15 同源码 Native/RN 配套构建和 Host 手工验证,不能用现有 .13 AAR 替代。
Windows 11 用户手工验收(待相同 V15 Test Host APK、RN 包与 Native AAR 可用后):
cd D:\React\MapLibreParticleRNTestHost-V4
npm install <RDC提供的同版本V15 RN package tgz路径>
npx expo prebuild --platform android
cd android
$env:ANDROID_HOME='C:\Users\taibe\AppData\Local\Android\Sdk'
$env:ANDROID_SDK_ROOT=$env:ANDROID_HOME
.\gradlew.bat :app:assembleDebug
adb -s 192.168.200.139 install -r <同源码V15 Test Host APK路径>
adb -s 192.168.200.139 shell am force-stop org.maplibre.particle.rntesthost
adb -s 192.168.200.139 shell am start -n org.maplibre.particle.rntesthost/.MainActivity
在 Host 可复用的本地 QBIN 场景中一次完成:首帧单帧显示/粒子持续运动、标量无粒子、第二帧中点 mix、乱序 8 帧、未来/过去/内部插入与淘汰、跨 reference/profile 日切首帧及回退、duplicate/revision/stale/损坏帧、wind/wave key 隔离、当前 endpoint 淘汰清场、100+ 次滚动及 clear。逐项记录真实请求时间与实际显示 validTime、T0/T1/mix、提交结果、异常日志、进程内存趋势。ADB 全部显式指定 192.168.200.139;不得将 Test Host 冒充 NavSea 验收。
iOS 由 Mac 用户使用同一冻结源码和配套产物手工构建;在 Metal 设备验证单帧首显、单帧向量运动、双帧 mix、跨批次 unavailable、双向淘汰、key 隔离、坏帧不覆盖好投影、clear/context 恢复及长时间内存趋势。Metal host runner 结果不能替代该设备证据。
T01–T17 状态
测试覆盖映射见设计文档 §6。以下“代码覆盖”仅说明测试源码中存在场景;实际运行均为 NOT RUN。
| 项 | 代码覆盖状态 | 实际运行 |
|---|---|---|
| T01 | 已覆盖 | NOT RUN |
| T02 | 已覆盖 | NOT RUN |
| T03 | 已覆盖 | NOT RUN |
| T04 | 已覆盖 | NOT RUN |
| T05 | 已覆盖 | NOT RUN |
| T06 | 已覆盖 | NOT RUN |
| T07 | 已覆盖 | NOT RUN |
| T08 | 部分覆盖;现有 revision/stale 入口 + 满额分支,尚无单一 T08 全覆盖测试 | NOT RUN |
| T09 | 部分覆盖;profile/decode/numeric/grid 拒绝及原子性,错误向量仍由既有 binding 测试覆盖 | NOT RUN |
| T10 | 部分覆盖;pair mix 0.25/0.5/0.99 已覆盖,精确 T1 以单帧表示 | NOT RUN |
| T11 | 已覆盖 | NOT RUN |
| T12 | 已覆盖 | NOT RUN |
| T13 | 已覆盖 | NOT RUN |
| T14 | 已覆盖 | NOT RUN |
| T15 | 部分覆盖;materialization/renderer 源码有覆盖,GPU/context loss 未运行 | NOT RUN |
| T16 | 部分覆盖;120 次 Core Store 双向滚动/clear 及 byte count 已覆盖,Runtime 切换/GPU 泄漏未运行 | NOT RUN |
| T17 | 部分覆盖;bridge 静态检查,自动化成功/失败序列与配套消费构建未运行 | NOT RUN |
当前结果与下一步
- 当前结果:源码已实施,等待 RDC 阶段 B 独立构建和测试;没有 PASS 结论。
git diff --check:通过(只代表空白/patch 格式检查)。- 未完成:所有新增 C++ 测试执行、OpenGL/Metal host 构建、Android/RN 同版本配套构建、iOS/Metal 设备验证、窗口拖动/跨天/内存实测、V15 pipeline、commit/push。
- 剩余阻塞:当前仅为 RDC 尚未运行本轮实现;
.13不能与新增 C++ Frame layout 配对,需后续同源码新版本构建。 - 下一责任:RDC 按 B→C 顺序执行并反馈真实日志;Android、iOS 设备与 Test Host 验收在后续配套阶段完成。当前停止于 Codex 源码交付,不进入 V15 pipeline。
2026-09-27 RDC 独立构建与定向测试补充(覆盖“本轮 NOT RUN”的后续事实)
- Codex
turn.completed/ exit 0 后,RDC 先执行 B;初次 runner 无 ninja PATH、Source 测试访问 private store、两处 fixture Grid 不合法,均已按首个真实错误做定向修复,记录见docs/报告/STEP-098_RDC定向验收报告_v1.md。 - B OpenGL Core/Binding/Ingress 编译 PASS,19/19 GTest PASS。
- C1 OpenGL Host 扩展
Particle*.*:Source.RasterArray*119/119 PASS。 - C2 Metal Host 编译 PASS,同 filter 119/119 PASS。
- 源级测试不等于 Android RN consumer/iOS 真机 GPU、内存/交互通过;V15 Pipeline 此时尚未启动。下一关必须为同源码发布构建和分端实测。