Files
MapLibreParticleLab/docs/50_Step记录/STEP-098_QBIN_V4单帧与八帧滚动缓存_v1.md

9.3 KiB
Raw Blame History

STEP-098 QBIN V4 单帧与八帧滚动缓存

状态:进行中(Codex 源码交付;等待 RDC 独立构建/定向测试及平台验收) 日期:2026-09-26(JST)

目标与基线

  • 目标:单帧真实时刻首显、合法同批双帧插值、每 fieldKey 最多八帧有序滚动,保留现有 RN API 两步调用。
  • 仓库:Mac /Users/tei/dev/MapLibreParticleLab;branch particle/main;开工 HEAD b1239ac3b1554943200e6fbf14321459ccc86527,结束时 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.hpp
  • src/mbgl/particle/field/field_runtime.cpp
  • src/mbgl/particle/field/field_projection_materialization.cpp
  • src/mbgl/particle/ingress/qbin_v2_decoder.cpp
  • src/mbgl/renderer/layers/render_particle_validation_layer.cpp
  • src/mbgl/renderer/layers/render_weather_color_layer.cpp
  • test/particle/field_binding.test.cpp
  • test/particle/field_runtime.test.cpp
  • test/particle/qbin_v2_decoder.test.cpp
  • test/source/raster_array_v4_host_api.test.cpp

文档/记录:

  • docs/30_设计/STEP-098_QBIN_V4单帧与八帧滚动缓存设计_v1.md
  • docs/50_Step记录/STEP-098_QBIN_V4单帧与八帧滚动缓存_v1.md
  • docs/报告/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 此时尚未启动。下一关必须为同源码发布构建和分端实测。