Files
MapLibreParticleLab/docs/60_测试/40_01_Android离线Fixture到正式粒子渲染最小闭环验证报告_v1.md
2026-08-31 12:17:06 +08:00

4.5 KiB
Raw Blame History

40-01 Android 离线 Fixture 到正式粒子渲染最小闭环验证报告 v1

状态

WAITING_MANUAL_VALIDATION。30-01、30-02、30-03 的正式记录均为 PASS,30-03 允许进入本任务。本报告只记录 Codex 的 Stage A 事实,不把未执行的 Android 编译或设备视觉验收写为 PASS。

基线与范围

  • 分支:particle/main
  • 开始 HEAD:1ec44701146925dec9a87618e3f90bee9a12073f
  • 平台范围:Android OpenGL;未修改 iOS、Vulkan、NavSea 或在线数据链。
  • Test App 继续使用既有 Particle Core Layer Validation 入口,但其 Style 现在创建正式 raster-array source 和 raster-particle layer;Core adapter 不依赖 Kotlin/Android UI 或 Android asset API。

已实现的 Stage A 链路

APK asset://integration/particle-fixtures/{uniform-east,uniform-north}/
  -> RasterArraySource -> RenderRasterArraySource
  -> ParticleFieldSnapshot -> GPU field texture
  -> RasterParticleLayer (Source::Required) -> RenderRasterParticleLayer
  -> State A/B field sampling -> Trail A/B -> canonical world composite / shared coastal mask
  • fixture contract 使用 metadata.json + field.f32,校验 schema、id、WIND/GLOBAL、EPSG:4326、bounds、grid registration/order、interleaved UV、little-endian float32、NoData 声明、长度和 SHA-256。Android asset 由 Test App 打包,Core 只接收 FileSource 返回的 metadata/field bytes;Linux helper 才读取仓库 particle-fixtures/。
  • uniform-east、uniform-north 和 vortex 均为确定性 16x16 fixture;不会在每帧解析或上传。切换 fixture 时递增 fieldGeneration/gpuFieldGeneration,清空旧 trail;Camera 操作不触发 field upload。
  • shader 的 State pass 实际采样 GPU field texture,Trail pass 从 State write texture 读取粒子位置,未使用 Kotlin/CPU 每帧粒子循环。field texture alpha 表示 cell validity;NoData cell 上传为 alpha=0,State pass 在该 sample 上确定性 respawn 到 seed position,绝不将 -9999 clamp 成速度。
  • STATIC 不再因资源缺失提前返回。新的 context/resource generation 会建立 field、mask、trail 和 state;STATIC 首帧走零步 bootstrap,提交 state/trail slot 但不增加 simulationFrame,之后保持 frozen composite。
  • Activity Bundle 保存/恢复 active、enabled、mask mode 与 fixture mode;GPU runtime state 不写入 Bundle。

Codex 可执行检查

检查 结果
ninja -C build-linux-opengl 受影响 Core 对象 PASS:正式 raster_array_source.cpp、raster_particle_layer.cpp、raster_particle_layer_factory.cpp、render_source.cpp、RenderRasterParticleLayer 实现、adapter 与 source conversion
clang-format --dry-run --Werror PASS
git diff --check PASS
python3 tools/generate_particle_fixture_f32.py 后 metadata JSON 与 SHA-256 PASS
adapter smoke test PASS:uniform-east、uniform-north、vortex 分别加载为 16x16;nodata 为合法 16x16 field 且恰有 1 个 invalid cell
APK asset parity PASS:四份 Android asset 的 metadata 与 field bytes 均与仓库 fixture 完全相同

首次整库构建尝试被 sandbox 默认 ccache 目录只读中断;以 CCACHE_DIR=/tmp/maplibre-particle-ccache 重新执行上述受影响对象检查后通过。这不是代码编译失败。

用户手工 Android OpenGL 验收

未执行。已核对当前模块提供 opengl flavor,用户应在提交后执行:

cd platform/android
./gradlew :MapLibreAndroidTestApp:assembleOpenglDebug

随后按任务书执行 T1-T12,尤其验证 STATIC + OCEAN A/B rotation 无按钮恢复、east/north 方向差异、field/mask generation 在 Camera 操作中稳定,以及 disable/enable、world wrap 和双向 antimeridian。日志筛选关键字:ParticleField|ParticleGPU|ParticleMask|ParticleRender|ParticleValidation。

未覆盖与风险

  • T1-T12 Android 设备验收、截图和 OpenGL shader 实机链接尚未执行。
  • 独立 EGL context-loss 设备证据沿用 30-02 的 Accepted Risk;本实现已按 resource generation 重建 CPU field 的 GPU texture。
  • iOS、Metal、Android Vulkan、真实数据、生产 coastline/mask、最终粒子数和性能指标均不在本 Stage A 范围。
  • Android T1-T12 和实机 OpenGL shader 链接尚未执行;NoData 已有 deterministic fixture/static smoke 覆盖,但没有实机视觉证据。

下一步

等待用户提供 Android OpenGL build 与 T1-T12 实际结果;仅在收到证据后进入任务书定义的 Stage B。