Files
MapLibreParticleLab/粒子开发记录.md
2026-09-04 14:51:42 +08:00

49 KiB
Raw Blame History

粒子开发记录

2026-08-27 — STEP-000

  • 建立正式 Ubuntu MapLibreParticleLab 工作目录。
  • MapLibre core:18545ca10d296704b2cba675b182ff2c8da24588

2026-08-28 — STEP-000 环境基线冻结

  • Ubuntu 24.04 x86_64 MapLibreParticleLab 主开发环境建立完成。
  • Linux OpenGL Native 构建通过。
  • mbgl-render 构建通过。
  • mbgl-render-test-runner 构建通过。
  • Android OpenGL Debug apackage 构建通过。
  • Android Vulkan Debug apackage 构建通过。
  • OpenGL/Vulkan AAR 均包含 arm64-v8a、armeabi-v7a、x86、x86_64 的 libmaplibre.so。
  • Vulkan Debug AAR 同时包含 Khronos Validation Layer。
  • Android SDK 路径已通过 ANDROID_HOME 与 local.properties 固化。
  • 下一步进入 STEP-001:MapLibre Native 粒子接入点只读调查。

2026-08-29 — 10_架构调查

  • 按 docs/40_任务/10_架构调查指令书_v1.md 完成只读架构调查。
  • 确认当前仓库是 MapLibre Native monorepo,不是 React Native 应用;确认 Android 13.4.1、iOS 6.28.0 和共用 Core 渲染链。
  • 确认 Android OpenGL/Vulkan、iOS OpenGL/Metal、Core CustomLayer/gfx、Camera/Matrix、帧驱动和线程边界;粒子 fixture 目前只有空目录占位,暂无粒子运行时代码。
  • 生成 docs/20_调查/10_架构调查报告_v1.md 和 docs/报告/10_架构调查_Codex完成报告_v1.md。
  • 本次未修改生产代码、原生工程、依赖或项目总则;遵循用户要求未自行创建或修改 Step 文件。

2026-08-29 — 20_架构设计

  • 按 docs/40_任务/20_架构设计指令书_v1.md 完成第一版正式粒子系统总体架构设计。
  • 生成 docs/10_架构/20_粒子系统总体架构设计_v1.md 和 docs/报告/20_架构设计_Codex完成报告_v1.md。
  • 正式主路线冻结为独立 Core RasterParticleLayer/RenderRasterParticleLayer + RasterArraySource + 隔离 mbgl::particle 模块,进入 Style/RenderTree 并使用 MapLibre gfx;CustomLayer/CustomDrawable 不作为产品主宿主。
  • 冻结 WeatherColor/Particle 分层、Field/fixture contract、Wind GLOBAL、海洋场 OCEAN_ONLY 共用 Mask、MapLibre frame driver、同帧 Camera Matrix、GPU resource/context-loss 和平台薄接入原则。
  • 下一阶段选择 30_最小技术验证,集中验证独立 RenderLayer、OpenGL/Vulkan ping-pong/trail/context、Camera/wrap/Mask 和 iOS 薄接入。
  • 最终 FPS、最大粒子数、最佳 texture format、生产 Mask 来源、真实天气协议和生产 Host API 仍未确认。
  • 本次未修改生产代码、依赖、构建配置、项目总则或 Step,未运行构建/测试。

2026-08-29 — 30-01 Core RenderLayer 接入验证(阶段 A)

  • 按 docs/40_任务/30_01_CoreRenderLayer接入验证指令书_v1.md 完成最小验证代码准备。
  • 新增 source-less ParticleValidationLayer/RenderParticleValidationLayer,经正式 Style/LayerManager/RenderTree/LayerGroup/translucent pass 链接入;代码明确标记 VALIDATION ONLY。
  • 新增默认 false 的 RenderLayer repaint hook;ACTIVE 通过 MapLibre 自身 needsRepaint → Map::onUpdate → Android requestRender 链持续帧,STATIC 停止验证层额外请求。
  • 验证 Drawable 在真实 pass 内读取当前 PaintParameters/TransformParameters/TransformState 的 viewport、zoom、bearing、pitch 和 projection matrix 摘要。
  • Android Test App 新增 Particle Core Layer Validation 页面,提供 ACTIVE/STATIC 切换和蓝/黄普通 Style Layer 顺序参照。
  • Linux OpenGL 重新配置通过;本任务新增/直接修改的 5 个 Core 对象精确编译通过。全量增量因公共头触发 321 个对象重编译,在 41/321 无错误时主动停止,未宣称全量 PASS。
  • 遵循指令书未运行 Android/Gradle/npm/ADB;等待用户手工 Android OpenGL 编译、运行、手势、resize 与日志证据。
  • 当前结论为 WAITING_MANUAL_VALIDATION;不得进入下一项 GPU ping-pong/Trail 验证。

2026-08-29 — 30-01 Core RenderLayer 接入验证(阶段 B 修复轮次 1)

  • 用户 Android OpenGL 实机日志暴露 RenderParticleValidationLayer::update() 的 DrawableBuilder 生命周期错误:当前 Drawable 未完成就调用 clearDrawables(),RenderThread 随后触发 SIGSEGV。
  • 对照 DrawableBuilder::flush(context) 与仓库既有 Drawable 使用方式,在 clearDrawables() 前补充 builder->flush(context),使 custom validation Drawable 完成后再转移给 LayerGroup。
  • 未以空指针判断跳过 Drawable;Tweaker 仍必须进入真实 translucent render pass 并读取同帧 Transform。
  • Linux OpenGL 对应目标对象编译通过;C++ 格式和 git diff --check 通过。
  • 未运行 Android/Gradle/npm/ADB,等待用户在新提交上重新手工编译和实机运行。
  • 当前结论仍为 WAITING_MANUAL_VALIDATION;未扩大到粒子、GPU ping-pong、Trail、Mask、Vulkan 或 iOS。

2026-08-29 — 30-01 Android Test App APK 版本标识

  • 在 Test App 主菜单列表顶部增加当前 APK 构建身份显示。
  • 显示 versionName/versionCode、renderer flavor、build type 和构建时 Git revision 前 10 位,均来自 BuildConfig,不写死版本。
  • 版本条用于人工验证时区分旧 APK 与当前源码构建,避免只凭安装时间或文件名判断。
  • git diff --check 与 Android XML 标准库解析通过;按用户要求未执行任何编译。
  • 等待用户手工构建、安装后确认设备端显示。

2026-08-29 — 30-02 GPU Ping-Pong 与 Context Recreation(前置阻塞)

  • 开始执行 docs/40_任务/30_02_GPU_PingPong与ContextRecreation验证指令书_v1.md 并首先检查硬前置门槛。
  • 30-01 最新技术报告与完成报告均仍为 WAITING_MANUAL_VALIDATION,不存在正式 PASS 记录或 PASS commit。
  • 按 30-02 指令书第 2 节停止:未创建 State A/B、Trail A/B、RenderTarget、Shader、ping-pong、generation 或 context recreation 验证代码。
  • State A/B、Trail A/B、gfx 同步、resize、disable/enable 和 context recreation 均未验证,无 PASS/FAIL 技术结论。
  • 当前 30-02 状态为 BLOCKED;不允许进入 30-03。
  • 阻塞报告:docs/60_测试/30_02_GPU_PingPong与ContextRecreation最小技术验证报告_v1.md。
  • Codex 完成报告:docs/报告/30_02_GPU_PingPong与ContextRecreation验证_Codex完成报告_v1.md。

2026-08-29 — 30-01 Core RenderLayer 接入验证(用户验收 PASS 回填)

  • 用户已完成 Android OpenGL 构建和 Particle Core Layer Validation 实际运行验收,明确确认结果为 OK/PASS。
  • 30-01 正式状态由 WAITING_MANUAL_VALIDATION 更新为 PASS;Core RenderLayer 接入、ACTIVE/STATIC repaint、同帧 Transform 及 pan/zoom/bearing/pitch/resize 验证范围均由用户确认满足要求。
  • 本次只回填验收状态:未重新修改 30-01 代码、未重新编译、未重新运行 Android、未执行 ADB。
  • 30-01 正式完成,允许重新开始 30-02。
  • 30-02 v1 的 BLOCKED 历史记录继续保留;它反映当时 30-01 正式 PASS 尚未回填,不代表 GPU/gfx 架构验证失败。

2026-08-29 — 30-02 GPU Ping-Pong 与 Context Recreation(阶段 A)

  • 30-01 正式状态为 PASS,此前 30-02 v1 的历史 BLOCKED 前置原因已解除;开始重新执行 30-02 指令书。
  • validation-only State A/B 已使用两套固定尺寸独立 GPU RenderTarget 实现;每帧 read/write 反向选择,无 CPU 完整状态复制。
  • Trail A/B 已使用两套 viewport 尺寸真实 RenderTarget 实现 previous fade/marker → next,并把 next 合成到 MapLibre 主 translucent pass。
  • 静态确认只注册当帧 write target,read target 不作为当帧附件;RenderTarget 顺序为 State → Trail,主 pass 后续 composite,slot 在 composite Tweaker 到达时提交。
  • resize 只重建 Trail A/B 并保留 State A/B;disable/remove 会停止并释放或重置资源;context lost 记录旧 generation discard,新资源使用递增 generation。
  • 复用 Particle Core Layer Validation,保留 ACTIVE/STATIC 并增加 DISABLE/ENABLE;没有修改通用 gfx API、正式粒子、Mask、Vulkan 或 iOS。
  • 静态格式、JSON、shader 注册链与 diff 检查通过;遵守用户要求未编译,未运行 Gradle/Android/ADB。
  • 当前状态为 WAITING_MANUAL_VALIDATION:State/Trail 实际 GPU 交替、OpenGL 同步、resize、disable/enable 和真实 context recreation 均等待用户手工运行证据。
  • 不允许进入 30-03;若无法确认真实 context recreation,最终应按指令书标记 BLOCKED。
  • 技术报告:docs/60_测试/30_02_GPU_PingPong与ContextRecreation最小技术验证报告_v2.md。
  • Codex 完成报告:docs/报告/30_02_GPU_PingPong与ContextRecreation验证_Codex完成报告_v2.md。

2026-08-30 — 30-02 T3 STATIC freeze 实机缺陷修复

  • 用户 Android OpenGL 手工验证确认:STATIC 静止时 State/Trail 停止,但 STATIC 拖动地图触发 MapLibre redraw 时仍继续推进,停止拖动后再停止;原 T3 正式判定为 FAIL。
  • 原因是 needsRepaint=false 只停止 validation 主动请求帧,而原 update() 在地图手势帧中仍无条件注册 State/Trail RenderTarget、设置 pending,并由 composite Tweaker提交 slot/frame。
  • 最小修复在 RenderParticleValidationLayer 增加 STATIC frozen-composite 路径:地图主 pass 仍正常 redraw 并显示最后 commit 的 Trail,但不注册离屏 target、不执行 State/Trail update、不 fade/加 marker、不 swap、不增加 simulation frame/index。
  • STATIC 下不因 resize 重建/清空 Trail;恢复 ACTIVE 后才继续原 ping-pong 与 resize 生命周期。
  • 仅修改 validation RenderLayer .cpp/.hpp 和本轮文档;未修改 Test App、shader、通用 gfx、正式粒子、Mask、Vulkan 或 iOS。
  • C++ 格式、diff 与 GPU scheduling/commit 静态控制流检查通过;按用户要求未编译,未运行 Android/Gradle/ADB。
  • 修复后的 T3 等待用户在 commit 364b8f381e27eee36c4895084b2f0578a023fa61 上重新手工验证;30-02 总体状态仍为 WAITING_MANUAL_VALIDATION,不允许进入 30-03。
  • 技术报告:docs/60_测试/30_02_GPU_PingPong与ContextRecreation最小技术验证报告_v3.md。
  • Codex 完成报告:docs/报告/30_02_GPU_PingPong与ContextRecreation验证_Codex完成报告_v3.md。

2026-08-30 — 30-02 Android Rotation 状态恢复定向修复

  • 用户确认此前 STATIC 的 pan/zoom/bearing/pitch 手势回归已经通过,DISABLE / ENABLE 正常;但旋转导致 Activity recreation 后 STATIC 错误恢复为 ACTIVE。
  • 根因是 Test App 没有将 active/enabled 写入 Bundle,且 onCreate() 无条件恢复 ACTIVE + ENABLED 并重置 camera。
  • 仅在 ParticleCoreLayerValidationActivity.kt 新增 Bundle key、保存/恢复 validation control mode;recreation 复用恢复后的统一 loadValidationStyle(),且只在首次进入设置默认 camera。
  • 未修改 Manifest、C++、gfx、RenderLayer、shader、GPU ping-pong、GPU 状态、Gradle 或依赖;未使用 configChanges、方向锁定、SharedPreferences、全局变量或 GPU 序列化。
  • git diff --check 与状态控制静态检查通过;按要求未运行 Gradle、Android 编译或 ADB。
  • R1 STATIC、R2 ACTIVE、R3 DISABLED rotation 与 R4 STATIC gesture 回归等待用户实机验证;30-02 保持 WAITING_MANUAL_VALIDATION,不允许进入 30-03。
  • 技术报告:docs/60_测试/30_02_GPU_PingPong与ContextRecreation最小技术验证报告_v4.md。
  • Codex 完成报告:docs/报告/30_02_GPU_PingPong与ContextRecreation验证_Codex完成报告_v4.md。

2026-08-30 — 30-02 正式关闭(EGL Context Recreation Accepted Risk)

  • 用户已完成并确认 30-02 的 Android OpenGL 实机结果;ACTIVE/STATIC、GPU ping-pong、STATIC 手势冻结、DISABLE/ENABLE 与 rotation control-mode 恢复纳入正式结论。
  • 30-02 正式状态为 PASS,并正式关闭;允许进入 30-03。
  • 真实 EGL Context recreation 没有独立实机验证证据,明确标记为 Accepted Risk / 未验证项;用户已明确决定该风险不阻塞后续阶段。
  • 未伪造 context-loss PASS,也未重写 v1 BLOCKED、v2、v3 或 v4 历史报告。
  • 本次只回填报告与开发记录;未修改代码,未重新编译,未运行 Gradle、Android 或 ADB。
  • 技术报告:docs/60_测试/30_02_GPU_PingPong与ContextRecreation最小技术验证报告_v5.md。
  • Codex 完成报告:docs/报告/30_02_GPU_PingPong与ContextRecreation验证_Codex完成报告_v5.md。

2026-08-30 — 30-03 Camera / World Wrap 与 Land/Ocean Mask(阶段 A)

  • 30-02 已正式 PASS,EGL Context recreation 作为用户接受的未验证风险不阻塞,故开始 30-03。
  • validation composite 改为使用当前 PaintParameters::matrixForTile() 的 canonical z0 world quad;ACTIVE/STATIC 继续区分 simulation update 与 Camera redraw。
  • 通过 UnwrappedTileID.wrap 绘制中心和相邻 MapLibre world copy;仅中心 copy commit,避免 world copy 额外推进 30-02 GPU simulation。
  • 增加反经线两侧 deterministic anchors C/D,并以全球 canonical mask UV 复用 MapLibre wrap,不建立第二套 world 状态机。
  • 增加 validation-only shared 16×16 synthetic coastal mask,GLOBAL、OCEAN_ONLY_A/B 复用同一 GPU texture;Camera/consumer 切换不重建,context-destroy 通知后按新 generation 重建。
  • Android Test App 复用既有入口,增加 GLOBAL/OCEAN A/OCEAN B/DATELINE/WORLD WRAP 最小控制;未运行 Android 编译、Gradle 或 ADB。
  • Linux OpenGL 受影响 Core 对象精确编译、C++ 格式与 diff 检查通过;用户 T1–T13 实机验证仍待执行。
  • 当前状态:WAITING_MANUAL_VALIDATION;不允许进入 iOS 最小验证。
  • 技术报告:docs/60_测试/30_03_Camera_WorldWrap与LandOceanMask最小技术验证报告_v1.md。
  • Codex 完成报告:docs/报告/30_03_Camera_WorldWrap与LandOceanMask验证_Codex完成报告_v1.md。

2026-08-31 — 30-03 Camera / World Wrap 与 Land/Ocean Mask(最终 PASS)

  • 用户已完成 Android OpenGL 手工验收,T1–T13 全部记录为 PASS;30-03 正式状态更新为 PASS。
  • 已确认本最小验证范围内的 Camera 同帧地理锁定、ACTIVE/STATIC camera redraw 分离、world wrap、双向反经线连续性,以及 shared Land/Ocean Mask 的 GLOBAL / OCEAN_ONLY_A / OCEAN_ONLY_B 语义。
  • Rotation/Viewport 自动恢复问题 为已知问题;用户接受延期,明确在下一个任务修复。本轮不声称该问题已修复,也不将其伪造为已验证功能。
  • 真实 EGL context recreation 的独立设备证据、正式 fixture adapter、正式 NoData fail-closed 和生产 coastline 数据仍未完成;EGL 风险沿用 30-02 的 Accepted Risk / 未验证 边界。
  • 30-03 已允许进入下一阶段;下一任务优先处理 Rotation/Viewport 自动恢复延期项。

2026-08-31 — 40-01 Android 离线 Fixture 到正式粒子渲染最小闭环(Stage A)

  • 30-03 后进入 Android 第一条离线 fixture 粒子闭环;Rotation/Viewport 自动恢复技术债已纳入本任务。
  • 新增 backend-neutral OfflineFixtureParticleAdapter 和 ParticleFieldSnapshot,以 v1 metadata、binary length 与 SHA-256 把 uniform-east、uniform-north、vortex 解码为正式 Field;不使用在线数据或 Android UI 依赖。
  • GPU field texture 接入既有 State A/B;Trail A/B 改为读取 State write texture,fixture 切换递增 field/gpu field generation 并清理旧 trail;Mask 继续走既有 shared GLOBAL/OCEAN_ONLY 路线。
  • STATIC 不再阻止 resource bootstrap:Activity/context recreation 后会建立 field/mask/trail/state 并做零步 first composite,simulationFrame 不增加;Activity 保存 active/enabled/mask/fixture 选择。
  • Linux OpenGL 受影响 Core 对象、C++ format、diff、fixture checksum 和 adapter smoke test 均通过;未运行 Gradle/ADB/实机验证。
  • 当前结论:WAITING_MANUAL_VALIDATION。用户仍需完成 Android OpenGL T1-T12,尤其 T1 rotation 无按钮恢复;iOS、Vulkan、真实数据、生产 mask 和性能均未覆盖,尚不建议进入下一 Android 子任务。
  • Stage A 实现提交 0b076c6d52fffb2ee4411cac64f06d43cea260c8 已成功 push 到 origin/particle/main。

2026-08-31 — 40-01 Stage A 正式链、Android fixture 边界与 NoData 修正

  • 纠正此前实现仍借用 source-less ParticleValidationLayer 的偏差:新增正式 RasterArraySource -> RenderRasterArraySource -> RasterParticleLayer (Source::Required) -> RenderRasterParticleLayer,并让正式 RenderLayer 复用既有 GPU field、State A/B、Trail A/B、Mask、Camera/World Wrap/Antimeridian 与生命周期。
  • Android Test App 的 Style 现在创建 raster-array / raster-particle,fixture 由 APK assets/integration/particle-fixtures/ 的 asset:// URI 提供;Core adapter 仅接收 FileSource bytes。Linux smoke helper 继续读取仓库 fixture,生成工具验证并同步两端完全相同的 metadata/field 内容。
  • ParticleFieldSnapshot 将 cell validity 独立于 fixture validity:合法 NoData cell 产生 invalid mask,GPU texture alpha 表示该 mask;State sample 命中 NoData 后确定性 respawn,不将 -9999 当普通速度;NaN/Inf 仍拒绝。新增 nodata deterministic fixture。
  • STATIC/context recreation 的 zero-step bootstrap 未推翻:新资源自动建立并首帧 composite,bootstrap commit 不增加 simulation frame。
  • Linux Core 精确编译、format/diff、fixture generator、adapter/asset parity 检查在最终收尾复跑;未运行 Gradle、APK、ADB 或 T1-T12。最终状态仍只能是 WAITING_MANUAL_VALIDATION,等待 GPT 再次复审远端代码。

2026-09-01 — 40-01 RasterArray OfflineDownload 穷尽接入

  • Android OpenGL 实际 C++ 编译暴露 OfflineDownload 的 required-resource-count 与 resource-queue 两处 SourceType 穷尽 switch 漏掉 RasterArray。
  • 根据当前实现,RasterArraySource 只从平台 FileSource 获取确定性 fixture metadata/field bytes;40-01 Android 输入固定为 APK asset://integration/particle-fixtures/...,且 Source Impl 不包含 tileset、zoom range 或 OfflineDownload 托管资源 contract。因此两处都以显式 SourceType::RasterArray no-op 表达语义,不虚报资源数、不进入下载队列。
  • 不增加 default:;全仓非 vendor 的 SourceType switch 已复核,本次仅修复新增枚举的直接遗漏。Linux/Core offline_download.cpp.o 精确编译(-Werror)、clang-format --dry-run --Werror 与 git diff --check 均通过;未运行 Gradle 或 ADB,40-01 继续为 WAITING_MANUAL_VALIDATION。

2026-09-01 — 40-01 RasterArray Source RenderItem 空指针修复

  • Android OpenGL 首次实机启动确认 field fixture 已加载、RasterParticleLayer 已 evaluate 后,RenderThread 在 State A/B 创建前因 Renderer::Impl::render() fault addr 0x0 崩溃。
  • 调用链确认:loaded + needsRendering 使 RenderRasterArraySource enabled;RenderOrchestrator 要求 enabled source 返回合法 RenderItem;RenderTree 无条件解引用。原 createRenderItem() 返回空指针违反该既有契约。
  • RasterArray source 改为按 ImageSource 的 prepare/create 生命周期提供 no-op RenderItem(无 upload、无 render pass、无 debug drawable、无 particle draw);不改全局 RenderOrchestrator,不增加第二套粒子 renderer,粒子 GPU 路径仍由 RenderRasterParticleLayer 负责。
  • Linux/Core render_source.cpp.o 与新增 source test object 均以 -Werror 精确编译;format、diff 与全部 RenderSource createRenderItem() return audit 通过。未运行完整 Linux 测试二进制、Android Gradle、ADB 或真机测试,40-01 继续为 WAITING_MANUAL_VALIDATION。

2026-09-01 — 40-01 Android ACTIVE / STATIC simulation lifecycle 修复

  • 实机日志中反复出现的 ParticleValidation30_02: disabled reset generation=... 唯一来自 RenderRasterParticleLayer::markLayerRenderable(false)。调用链复核确认:RenderOrchestrator::createRenderTree() 在逐一处理每个 source 时为不匹配 source 的 layer 给出临时 false;同一 render tree 随后处理匹配的 raster-array source 又恢复 true。该 false 不是持久 disabled 生命周期事件。
  • 原 override 在这个临时回调中移除 target、清空注册、执行 ParticleGpuResources::resetSequence();因此 committedFrame(正式 simulationFrame)每帧回到 0,stateRead/trailRead 每帧回到 A、seed 标记变 false,ACTIVE 永远 schedule/commit frame 1,STATIC 每帧重新走 zero-step bootstrap。
  • 已移除 markLayerRenderable(false) 的错误 reset;layer 仍保留 base renderable 状态。State/Trail 资源只在 field/fixture generation 改变、Trail viewport 重建、context lost 后资源重建、或 layer removal 时按已有路径失效/清理。ParticleGpuResources 仍由 RenderRasterParticleLayer::gpuResources 持有,跨 render() 持久存在。
  • ACTIVE 现在连续按 A→B、B→A 交换并让 committedFrame 递增;STATIC 在未 seed(初次或真实资源事件)时只做一次 zero-step bootstrap,已有状态时只走 FrozenComposite,不注册离屏 target、不 commit;STATIC→ACTIVE 复用既有 slot/frame 继续 simulation。没有改变 pass 次序 State,Trail,Composite、hazard=SAFE、fixture/resourceGeneration contract 或 public API。
  • 日志现在在 ACTIVE/STATIC transition 输出 generation、fixture、frame 与 read slot;schedule/pass/commit 输出前 3 帧及每 60 帧,避免长期高频洪水,同时可明确验收 1→2→3 与 A/B 交替。
  • Linux OpenGL render_particle_validation_layer.cpp.o 精确编译、clang-format 与 git diff --check:PASS。40-01 保持 WAITING_MANUAL_VALIDATION,等待用户用新 APK 完成 GLOBAL ACTIVE、ACTIVE→STATIC、STATIC→ACTIVE 手工验收。

2026-09-01 — 40-01 Formal RasterParticle Trail Composite 显示修复

  • 实机已证明 generation 稳定、simulationFrame 连续递增、State/Trail A/B ping-pong 与 hazard=SAFE 正常;画面静止不再是 lifecycle/repaint/clock 问题。
  • 根因位于最终 Composite:Trail pass 确实从最新 State write 画入 Trail A/B,但 Composite 仅将 Trail RGB 计算为 alpha intensity,最终 RGB 始终是 30-03 legacy 的 stripe/anchor。因此正式 field simulation 没有成为屏幕主体。
  • ParticleGpuResources::formalDisplay 由 RasterParticleLayer 的 formal source 身份设置,并通过现有 UBO u_mask.z 传入 shader。正式 FORMAL_PARTICLE Composite 输出当前 Trail RGB 与由其 intensity 导出的 premultiplied alpha;legacy ParticleValidationLayer 继续走未改变的 VALIDATION stripe/anchor/world-wrap 分支。
  • ParticleRender 新增一次性 displayMode 日志;既有低频 schedule 日志补充 trailStateSource、compositeTrailSource 和 displayMode,可证明 State write → Trail write → Composite Trail write 的数据关系,而不每帧刷屏。
  • shaders/particle_gpu_validation.fragment.glsl 为唯一 shader source,使用 node shaders/generate_shader_code.mjs 正常生成 OpenGL header;二次生成哈希一致。生成器同时规范化 src/mbgl/shaders/shader_source.cpp,该生成物一并保留以保证生成后工作树稳定。
  • Linux OpenGL 受影响 RenderLayer object、相关 source.test.cpp.o 均精确编译;C++ format、diff check 通过。按任务边界未运行 Android Gradle、ADB 或真机;40-01 继续为 WAITING_MANUAL_VALIDATION,下一轮只验收 GLOBAL + ACTIVE + uniform-east 的可见 eastward 运动。

2026-09-01 — 40-01 Formal RasterParticle 显式 State Seed 修复

  • 实机日志确认 formal display、State/Trail/Composite slot wiring、simulation frame 与 hazard 均正确,但正式粒子仍不可见。RenderTarget::render() 的既有全局 clear 是 opaque black (0,0,0,1);未修改该 MapLibre contract。
  • 原 State shader 用 previous.a < 0.5 判断是否第一次 seed,但新 State target alpha 为 1,导致全部 16×16 texel 从 (0,0) 而非各自 v_uv 开始。uniform-east 只推动 x,marker 聚集在 canonical world 顶缘、常在当前视口外。
  • ParticleGpuResources::stateSeeded 现在是唯一权威。State pass 把 !stateSeeded 通过现有 UBO 的 u_mask.w 传入;shader 仅以该 flag 选择 v_uv 或 previous.rg,不再以 texture alpha 推断生命周期。Field alpha 仍仅表示 NoData validity。
  • ACTIVE 第一次 State pass 与 STATIC zero-step bootstrap 都对每个 texel 进行 v_uv seed;Composite commit 后 stateSeeded=true,之后继续 read texture。新 resources、context recreation 和 fixture/field resetSequence() 保持重新 seed;普通 ACTIVE、Camera、STATIC 与 transient source renderability 不会 seed。
  • 新增低频 ParticleRender: stateSeed=INITIALIZE|CONTINUE 日志,含 generation、State A/B 与 fixture。shader source/header generator parity、生成器幂等、Linux Core 与 Source test object 编译、format 和 diff 均通过;未运行 Android Gradle/ADB/真机,状态仍为 WAITING_MANUAL_VALIDATION。

2026-09-02 — 40-01 RasterArray Source 重建 Field Identity 修复

  • 用户实机确认 GLOBAL ACTIVE uniform-east、ACTIVE→STATIC→ACTIVE 均通过;点击 uniform-north 后仍 eastward。Android Test App 已正确重建 raster-array source,根因不在 UI 或 shader/ping-pong。
  • RasterArraySource::tryLoad() 原有 generation 是 source 实例成员;Style 用同一 source ID 重建时 east 与 north 都可得到 generation 1。RenderRasterParticleLayer 正式路径又只比较 generation,因此错误保留 east GPU field texture。
  • runtime generation 改为 raster_array_source.cpp 的 process-wide atomic 单调 revision;它只表达运行时 snapshot identity,不混用 metadata dataVersion,也不使用时间或随机数。source load 日志现在含 fixtureId、generation、dataVersion。
  • renderer 使用 shared fieldIdentityChanged() 三元判断:generation、fixtureID、dataVersion 任一改变都会重新上传 field texture 并保留既有 resetSequence()、State re-seed、Trail clear 路径;三者相同不重复上传。fixture switch 日志记录 from/to、old/new generation、gpuFieldGeneration、trail clear 与 state seed。
  • 新增定向 C++ 测试:两个独立 RasterArraySource 实例加载 east/north 得到不同 generation;同 generation 的 east/north 仍判定 identity changed;同 fixture/generation/dataVersion 不判定变更,dataVersion 改变则判定变更。
  • Linux OpenGL 的 RasterArraySource、RenderLayer 与 source.test.cpp 精确编译,format/diff 均通过;未运行 Android Gradle/ADB/真机,40-01 继续 WAITING_MANUAL_VALIDATION。下一轮只验收 GLOBAL + ACTIVE + uniform-east 后切 uniform-north 的方向变化。

2026-09-02 — 40-01 Stage B Android OpenGL 最终关闭

  • 用户完成 Android OpenGL x86_64 手工验收,40-01 正式状态更新为 PASS。
  • GLOBAL + ACTIVE + UNIFORM EAST、ACTIVE→STATIC→ACTIVE、UNIFORM EAST→UNIFORM NORTH→UNIFORM EAST、STATIC OCEAN A/B Rotation 自动恢复、ACTIVE Rotation、Pan/Zoom/Bearing/Pitch、World Wrap、双向 Antimeridian、GLOBAL/OCEAN A/OCEAN B、Shared Mask reuse、DISABLE/ENABLE、快速 fixture 切换与最终重复 Rotation 回归全部 PASS。
  • 同一 RenderThread/resource generation 内 GLOBAL/OCEAN_ONLY_A/OCEAN_ONLY_B 复用同一 maskGeneration,日志为 reuse=true;graphics resource 重建后的 generation/maskGeneration 递增属于新 GPU resource,不属于同 generation 内重复创建。
  • 40-01 历史调试链完整保留:OfflineDownload exhaustive switch、RasterArray no-op RenderItem SIGSEGV、Android APK/.cxx 旧 native 缓存、lifecycle reset loop、formal Composite Trail 显示、shader source/generated header 同步、opaque clear State seed、field identity generation collision、Rotation/Viewport STATIC restore 均已解决并由最终手工回归覆盖。
  • 本次仅回填 Stage B 文档,不重新运行 Android Gradle、ADB 或实体机;iOS/Metal、Vulkan、真实数据、生产 mask、性能和独立 EGL context-loss 设备证据仍为范围外,不被 40-01 Android OpenGL PASS 隐含覆盖。

2026-09-02 — 40-02 Android 双时间片 GPU 时间插值(代码阶段)

  • 在 40-01 唯一正式 RasterArraySource -> RasterParticleLayer -> GPU Simulation -> Trail -> Composite 链路上扩展为 T0/T1 两份 immutable Field snapshot;source 通过可选 next-fixture/next-metadata/next-field 从同一 FileSource byte boundary 加载,拒绝 grid/bounds/NoData/Field 语义不兼容的窗口。
  • RasterParticleLayer 新增 raster-particle-time-mix 常量属性;其只更新既有 UBO。State shader 分别从两张 GPU Field texture 解码速度后 GPU mix,没有 CPU 完整中间 Field、第二 Layer 或第二 simulation。
  • Renderer 保持一套 State A/B、Trail A/B、shared Mask 和 Composite;T0/T1 使用两个可复用 GPU Field slot。窗口 A/B -> B/C 通过 generation + fixtureID + dataVersion 识别 B,复用其 texture、只上传 C,保留 simulation/trail;无重叠的新窗口沿用 40-01 的安全 reset/reseed。
  • Android Test App 增加 T0 EAST/T1 NORTH、MIX 0/50/100 与 ADVANCE B→C 入口,原 ACTIVE/STATIC、GLOBAL/OCEAN、Camera、wrap/antimeridian 入口保留。
  • Linux OpenGL 受影响 Core/source-test object、shader generator、C++ format 和 diff check 已通过;未执行 Android Gradle、ADB 或设备操作。40-02 当前只能标记 IMPLEMENTED / WAITING FOR ANDROID VALIDATION,T1–T10 手工 Android OpenGL 验收后才能判 PASS。
  • 实现提交为 4675a8a29dd6fc7b684bfb64913a8c9075ad8583(feat: add GPU particle time interpolation);文档收尾提交另行记录,均只面向 40-02。

2026-09-02 — 40-02A Android Validation 测试界面紧凑化(代码阶段)

  • 仅调整 Android Test App 的 Particle Core Layer Validation UI:底部控制区从 7 个默认大按钮行压缩为 4 行,状态行 36dp、控制行 34dp、padding 4dp,MapView 保持全屏并获得更多粒子观察区域。
  • EAST/NORTH、T0/T1、ADVANCE、MIX、ACTIVE/STATIC、DISABLE/ENABLE、GLOBAL/OCEAN、DATELINE/WORLD WRAP 的 16 个既有 ID/click binding 均保留;状态改为单行 mask/runtime/field/mix 表达,不改变 40-02 业务语义。
  • 未修改 C++ Core、shader、GPU、simulation、trail、composite、mask、Gradle 或 ABI。静态 ID/binding 核对与 diff check 通过;未运行 Android Gradle、ADB 或设备。状态为 IMPLEMENTED / WAITING FOR ANDROID UI VALIDATION。
  • 实现提交为 f4d519ca789c0488d6b9d8259427ac070b15eb63(ui: compact particle validation controls);文档收尾提交另行记录。

2026-09-02 — STEP-043 / 40-02C 最终修正

  • 修正 north-positive V 到 Mercator Y 的最终 displacement 符号;Field canonical contract 未变。
  • MIX 移除 Style reload fallback,未就绪只拒绝并记录日志;GPU reuse 使用已验证 SHA-256 content identity,revision generation 仍独立保留。
  • 状态:IMPLEMENTED / WAITING FOR ANDROID VALIDATION;未运行 Android Gradle/ADB,T1--T10 待用户验收。

2026-09-03 — STEP-043A 源码审查后最小修正

  • texture reuse 现消费 wanted revision;MIX reject 不再改变 timeMix;补充 lifecycle diagnostics 与 Style reason。状态仍为 IMPLEMENTED / WAITING FOR ANDROID VALIDATION。

2026-09-03 — STEP-043B Android→Core MIX 属性桥接

  • 自定义 raster-particle 没有 Android Java Layer peer,Style.getLayer() 不能作为 Core layer readiness;新增最小 NativeMapView bridge 走正式 Core Layer::setProperty,MIX 仅 bridge 成功后更新状态。

2026-09-03 — 40-02 双时间片 GPU 时间插值 Android 最终验收完成

  • STEP-043B 最终使用 RasterParticleLayer::setTimeMix(float);Android x86_64 OpenGL Debug 编译、安装、启动通过,T1--T10 全部 PASS。
  • A/B→B/C GPU texture reuse、MIX property-only、DISABLE/ENABLE 生命周期通过;uniform-north + vortex 的 MIX 50% 局部低速/近零速是正常逐点插值。
  • 单 ABI APK 约 696.5 MiB 是独立 packaging 技术债,不阻塞本阶段。40-02 / 40-02C / STEP-043B 正式 CLOSED / PASS。

2026-09-03 — 40-03 Android OpenGL 粒子数量容量基线(代码阶段)

  • 正式 RasterParticle GPU 链的粒子数实际由 State A/B render target 网格承载:既有 16x16 即 256 个 State shader texel。新增 raster-particle-particle-count Core 属性与强类型 RasterParticleLayer::setParticleCount(uint32_t),只接受 256..1,048,576 的平方数,确保实际 count 与 State grid 面积一致。
  • Android Validation 页面新增 256、1K、4K、16K、64K、1M 档位;使用既有 Android→Core 薄桥,不建立 Java layer peer、CPU simulation 或第二 GPU simulation。切换只重建 State A/B、执行一次可解释的 PARTICLE_COUNT_CHANGE reset/reseed,Field T0/T1、MIX、interpolation、GPU content reuse、mask 与既有 lifecycle 均不改变。
  • 日志包含请求/实际 count、State grid、State target create/rebuild/release 和拒绝原因;Trail 继续用四个确定性 State texel作低开销可视健康指示,实际并行 simulation 数仍是整个 State 网格。
  • Linux OpenGL 受影响 Core 和新增 Layer test object 精确编译、C++ format、diff check 均通过;未运行 Android Gradle、ADB、APK 或设备,也未加入 Jest。
  • 当前状态只能是 IMPLEMENTED / WAITING FOR ANDROID VALIDATION。用户将以 x86_64 Android OpenGL 逐档填写容量矩阵后,才能确定稳定区间、性能下降区间和压力边界。

2026-09-03 — 40-03 Full Particle Draw 补齐(STEP-044 v2)

  • 暂停 v1 容量验收的根因已补齐:v1 的 State A/B 虽可容纳 N 个 State texel,但 Trail fragment 只读取四个固定 sample,实际 Trail draw 只是全屏 quad,不能证明 N 个粒子已绘制。
  • 正式 RasterParticle Trail 现在先保留既有全屏 fade,再在同一 Trail A/B write target 绘制 N 个 point。particle index 在资源创建/count change 时一次性映射到 State texel (x,y);vertex shader 每帧直接从当前 State write texture fetch RG position,Composite 仍消费 Trail write。没有 CPU readback、每帧 CPU position loop、第二 simulation 或 overlay。
  • 16-bit index buffer 每 segment 最多 65,536 point;1M 使用多个 segment,但继续走同一 State→Trail→Composite GPU path。日志明确输出 trailDrawCount、particleIndexCount 与 fullParticleDraw=true;legacy validation 的四 sample 诊断保留且不再限制正式层。
  • U/V、Mercator dy=-v、T0/T1、MIX、Field reuse、seed/lifecycle 和 Android JNI 均未改变。Linux OpenGL 精确 Core/test object 编译、shader generator 二次幂等、format 与 diff check 通过;未运行 Android Gradle、ADB、设备或 Jest。
  • 状态继续为 IMPLEMENTED / WAITING FOR ANDROID VALIDATION,用户下一轮只验收 256、1K、256→1K→256 的 full draw 正确性,之后才恢复完整容量矩阵。

2026-09-03 — 40-03 Android OpenGL 粒子数量容量基线最终关闭(STEP-044 v3)

  • 40-03 正式 CLOSED / PASS。原 c0d1ad43... 只扩展 State A/B 容量,Trail/render 未 full draw,故验收曾暂停;a0aae48... 完成正式 full particle draw,使 State N -> draw N -> Trail -> Composite 成立。
  • 用户 Android OpenGL 实机确认:256→draw 256、1K→draw 1024、4K→draw 4096、16K→draw 16384、64K→draw 65536、1M→draw 1048576;所有档位日志均为 fullParticleDraw=true,用户确认 1M 运行 OK。T-FULL-01~03(含 256→1K→256 重建回归)全部 PASS。
  • count change 仅重建 State/full draw resources,未引入 Field upload、Style reload 或 MIX 改变;40-02 的 MIX property-only 与时间窗 Field reuse(simulationRebuild=false、trailCleared=false)保持。
  • 已验证容量 ≥ 1M,满足当前项目需求,不再扩展 2M/4M/8M 压测。1M 是本验证设备上的已验证容量,不是理论最大值、硬编码产品默认值或所有 Android 设备的统一保证。
  • 本收尾只回填文档;Codex 未运行 Android Gradle、ADB、设备测试或 Jest,也未修改功能代码。

2026-09-03 — 40-04 Runtime Field 动态更新接口(STEP-045)

  • 正式 Runtime Field 更新入口落在 RasterArraySource:updateRuntimeFieldWindow(ParticleFieldSnapshot) 把 Source 权威窗口由 T0/T1 推进为 T1/newT1,并通过既有 Source observer 通知正式 RasterParticle renderer;没有 Style reload、Source/Layer recreate 或第二套 Field/GPU 系统。
  • RasterArraySource::Impl::field/nextField 继续是唯一正式 T0/T1 权威状态。Android Validation 只通过 MapLibreMap -> NativeMapView -> JNI -> Style::getSource() 薄桥请求 advance;Kotlin/JNI 不保存窗口,不操作 renderer 私有资源。
  • 离线验证初始 A/B 为 uniform-east/uniform-north;Source 自己预加载 C=vortex、D=nodata。候选在真正进入 T1 时才获得 process-wide runtime generation,避免异步 asset 完成顺序造成 stale/non-monotonic revision。
  • 既有 renderer content identity/slot ownership 未改:A/B→B/C 和 B/C→C/D 都复用 OLD_T1 作为 NEW_T0,只上传新 T1,保留 simulation 与 Trail(simulationRebuild=false、trailCleared=false)。MIX 仍是 property-only,不参与 Field update。
  • 重复当前内容明确 NOOP;无效、未加载、不兼容、非单调或无候选更新 fail closed,不污染当前有效窗口。没有每帧 Field copy/hash/upload,也未修改 40-03 full particle draw。
  • Linux/OpenGL 受影响 Core/conversion/source test object 精确编译;定向窗口推进 test object 覆盖已加入,完整 mbgl-test 因 build tree 缺失大量无关依赖未执行,未将其误报为通过。格式与 diff 检查结果在完成报告收尾记录。未执行 Android Gradle、ADB、APK、实体机或 Jest;当前状态仅为 IMPLEMENTED / WAITING FOR ANDROID VALIDATION。
  • 实现提交:45502a53f4fc486bd24cb0008d1ab0ff221e7e63(feat: add runtime particle field updates);文档收尾提交另行记录。

2026-09-03 — 40-04 T-RUNTIME-05 Duplicate NOOP 补验收入口

  • 已有 Runtime API 的 sameFieldGpuContent(currentT1, newT1) NOOP 分支正确,但 Android 只有 ADVANCE(候选耗尽后为 T-RUNTIME-06 reject),无法真实重提当前 T1。
  • 新增 Source-owned repeatRuntimeFieldWindow() 和最小 Android/JNI 薄桥;DUPLICATE T1 只把当前 Impl::nextField 重交正式 update API,在 vortex/nodata 窗口返回 NOOP,不推进 candidate queue,不改变 Source window,也不触发 onSourceChanged()。
  • C++ Source test 在 C/D 后断言 Noop、T0/T1 不变及 source changed count 不增;Linux/OpenGL 精确 Core/test object 编译、format/diff check 通过。Android Gradle、ADB、设备和 Jest 未执行;状态继续 IMPLEMENTED / WAITING FOR ANDROID VALIDATION。

2026-09-03 — 40-04 / STEP-045 Runtime Field 动态更新最终关闭

  • 40-04 / STEP-045 正式 CLOSED / PASS。Android OpenGL 最终统一验证 T-RUNTIME-01~06 全部 PASS。
  • 正式 Runtime Field 接口已证明支持 A/B→B/C→C/D 连续时间窗推进:OLD_T1 复用为 NEW_T0,只上传真正的新 T1,正常推进不重载 Style、不重建 Layer、不重启 simulation、不清 Trail。
  • MIX 保持 property-only;Duplicate 重提当前 T1 返回 NOOP,不产生 Field upload/reset/style reload;候选耗尽 fail-closed,当前 vortex/nodata 窗口继续可用。
  • STYLE_LOAD reason=TIME_WINDOW 仅是用户建立初始窗口的允许初始化;真正 Runtime 操作期间 styleEpoch 稳定。MIX 的 LAYER_CHANGED 不是 Layer recreate,最终 renderLayerInstanceId 保持 1。
  • 40-04 未改变 U/V、dy=-v、GPU interpolation、40-03 full particle draw 或已验证 capacity ≥ 1,048,576;真实网络/GRIB/provider、视觉阶段、WeatherColorLayer、Vulkan、iOS/Metal、生产 mask、APK 技术债仍属范围外,未进入下一阶段。

2026-09-03 — 40-05 / STEP-046 Android OpenGL 正式粒子视觉与运行时渲染控制(代码阶段)

  • 正式 RasterParticleLayer full draw 从固定 blue point 扩展为短 streak:每个 State texel 对应一颗粒子、两个静态 line endpoint,GPU vertex shader 从 current State write 与 T0/T1 插值 Field 求位置、方向和速度;CPU 不持有 live particle position/direction/color,也不做 readback 或第二 simulation。
  • 继续冻结 U=east-positive、V=north-positive 与 Mercator 边界 dy=-v;EAST/NORTH/vortex 的视觉方向与 MIX 后最终速度一致。NoData、NaN 和近零速 fail-closed,不画 streak。
  • 新增 raster-particle-line-width、particle-length、particle-opacity、trail-opacity、trail-fade、speed-color-enabled 等 Core Render/Visual properties。它们经现有 Android→Core JNI boolean bridge 运行时更新,只改 Render/UBO,不 reload Style/Source、不上传 Field、不 reset State/Trail。
  • GPU fragment shader 使用最终插值 speed magnitude 的最小蓝→绿→橙 ramp;COLOR 控制可以回退固定蓝色。该粒子着色与未实现的 WeatherColorLayer 明确分离。
  • Android Validation 页增加 VISUAL DEFAULT、SIZE、LENGTH、OPACITY、TRAIL、FADE、COLOR 集中入口、直接 VORTEX fixture 与 256K 容量档,并保存 Activity 状态;资源日志补充 particleDrawCount=N、streakVertexCount=2N 和低频 visual property snapshot。
  • shader generator 二次幂等、Linux OpenGL Core/style test object 精确编译、format/diff 均通过;未运行 Android Gradle、ADB、真机或 Jest。当前状态只能是 IMPLEMENTED / WAITING FOR ANDROID VALIDATION;用户下一轮以一次 x86_64 APK 编译完成 T1--T8 综合验收后才可关闭。

2026-09-03 — 40-05 / STEP-046 Android OpenGL 正式粒子视觉与运行时渲染控制最终关闭

  • 实施提交 e48fa087e01e9710c5d0c18ab062726226bbb6bd 已由用户完成 Android APK 编译、安装和最终手工验证;T1--T8 全部 PASS,40-05 / STEP-046 正式 CLOSED / PASS。
  • UNIFORM EAST、UNIFORM NORTH、VORTEX 的正式 GPU streak 正常显示;Runtime visual properties、speed color 与 MIX 0/50/100 均正常,MIX 保持 property-only。
  • 40-04 Runtime Field Window 连续推进、OLD_T1 -> NEW_T0 reuse、Duplicate NOOP、fail-closed、无 Style reload / 无无意义 simulation reset / 无 Trail clear 均无回归。
  • pan、zoom、bearing、DATELINE、WORLD WRAP、DISABLE/ENABLE、屏幕/生命周期恢复、GLOBAL/OCEAN A/OCEAN B 均通过;Renderer 持续 State -> Trail -> Composite 且 hazard=SAFE。
  • 容量档 256、1K、4K、16K、64K、256K、1M 在新的 streak + speed color 路径均通过。4K 以上在小 Validation viewport 内趋于高密度铺满是可读性现象,不是功能失败;1M 仍只是当前验证设备上的已验证容量,不是全设备保证或产品默认值。
  • Android logcat 的 TimeStats: RenderEngineTimes are already at its maximum size[64] 是 RenderEngine/虚拟机环境噪声,未伴随粒子 Renderer crash 或中断,不判为本阶段失败。未进入 WeatherColorLayer、真实网络/GRIB、Vulkan、iOS/Metal 或生产 mask 等范围外工作。

2026-09-03 — 40-06 / STEP-047 Runtime Timeline 与 Playback(代码阶段)

  • RasterArraySource 现持有唯一的有界 Timeline runtime:六个离线 immutable snapshot、严格递增逻辑时间、T0/T1、mix、cursor、播放/暂停、0.5x/1x/2x、step、seek、gap/invalid/recover/end。Android 只经薄 JNI 发低频命令,没有 Android timer 或 per-frame JNI。
  • RenderRasterParticleLayer 只读取 Source Core 给出的当前 T0/T1/mix;窗口 revision 变化继续进入既有 Field identity/GPU reuse 路径,自动边界维持 OLD_T1 -> NEW_T0 的重用语义。正常 timeline MIX 不需要 Style reload。
  • Validation UI 收敛为 TIME | VIS | COUNT | MAP | MORE;原有动作均由菜单保留,TIME 提供 load/play/pause/speed/step/seek/gap/invalid/recover。
  • 已加 Source timeline 单元覆盖并运行 Linux/OpenGL Core 精确构建;未运行 Android Gradle、ADB、实体机或 Jest。状态仍为 IMPLEMENTED / WAITING FOR ANDROID VALIDATION,等待 Android x86_64 逐项验收。

2026-09-04 — 40-06 / STEP-047 Android Round 1 集中修复

  • Round 1 为 PARTIAL / NEEDS FIX:主链、自动 MIX/window reuse 和紧凑 UI 通过,但 timeline 过短、END/seek 语义、异常入口、VIS 可达性与 cache 可观测性不足。
  • Core validation timeline 改为约 200 秒;END PLAY restart、PLAYING/PAUSED seek 状态保持、GAP/INVALID fail-closed 和 RECOVER 保留此前状态。TIME 直接暴露 NORMAL/GAP/INVALID/RECOVER,VIS 将 COLOR 前置并使用明显的 validation 步长。
  • 仍保持 Source 有界 CPU snapshot preload、GPU 仅 T0/T1、相邻窗口 reuse 与 STEP-046 visual property-only。状态为 IMPLEMENTED / WAITING FOR ANDROID RE-VALIDATION。

2026-09-04 — 40-06 / STEP-047 Playback Tick 根因修复

  • Android Round 2 确认 PLAY/SPEED bridge 成功、RenderThread 持续,但 Timeline 只短暂推进。根因是 tick 错接到非持续的 RenderLayer update。
  • tick 已移到每个正式 State drawable frame 的 Core tweaker;没有 Android timer、每帧 JNI、线程或自旋。新增低频 PLAYBACK_TICK heartbeat;状态继续 IMPLEMENTED / WAITING FOR ANDROID RE-VALIDATION。

2026-09-04 — 40-06 / STEP-047 Runtime Timeline 与 Playback 最终关闭

  • Android 最终验收在 1343929474796b1313489ee9fecbf23b949580a7 功能基线上全部 PASS,STEP-047 正式 CLOSED / PASS。
  • Playback tick、Pause/Resume、0.5x/1x/2x、Seek/Step、Gap/Invalid fail-closed 与 Recover、Preload/Cache、OLD_T1 → NEW_T0 reuse、仅上传 NEW_T1、无正常 reset/clear trail、VIS/MAP/MORE 与紧凑 UI 均已验证。
  • snapshots=6/cacheCapacity=8 下没有 CACHE_EVICT 是正常容量现象。状态栏对自动 MIX/WAITING/INVALID 的展示记录为非阻塞 Validation UI observability 技术债;TimeStats 上限信息为 Android RenderEngine 环境噪音。此次仅文档收尾,未修改功能代码。

2026-09-04 — STEP-049 Provider-neutral C++ Field Data Adapter 与 Runtime 输入契约

  • 新增 ParticleFieldDescriptor、ParticleFieldDataAdapter、structured error result 与 provider-neutral ParticleFieldSnapshot;descriptor/payload 边界不携带 provider、URL、token、network 或 Renderer 对象。
  • OfflineFixtureParticleAdapter 保留 fixture-v1 whitelist、metadata/checksum 校验,但最终调用正式 Data Adapter;EAST/NORTH/VORTEX/NODATA validation fixture 继续工作,fixture identity 改为 neutral fieldID。
  • RasterArraySource 继续复用唯一 updateRuntimeFieldWindow();没有第二套 T0/T1、Timeline、Playback、GPU upload policy 或 Renderer 业务语义。OLD_T1 → NEW_T0、NEW_T1-only、Duplicate NOOP、MIX property-only 和 fail-closed 保持。
  • Linux OpenGL mbgl-test-runner 构建通过,adapter + RasterArray 定向 11 项测试通过,git diff --check 通过;未执行 Android Gradle/APK/ADB/设备/Jest。
  • 状态:IMPLEMENTED / WAITING FOR ANDROID VALIDATION,等待用户一次 Android 综合验收后再 docs-only closeout。

2026-09-04 — STEP-049 Timeline 回归修复

  • 根因是 Timeline candidate 在 tryLoadRuntimeField() 以 generation=0 进入正式 Field Adapter;adapter 的非零 generation 校验正确拒绝,Runtime Window 因使用已分配 generation 仍正常。
  • 修复为 candidate decode 前分配 Core 全局 runtime generation,Timeline 构建不再重复改写;未放宽 contract,未新增 adapter、Timeline 或 Window。
  • 新增真实 Source candidate preload → formal adapter → Timeline READY 回归测试,并保留 generation=0/invalid descriptor 负向校验;Linux OpenGL 构建通过,定向测试 12/12 PASS。
  • Validation UI 仅明确显示 TL NOT READY/READY/PLAY/PAUSE/WAIT/INVALID,与 Window 状态分离;未执行 Android Gradle/APK/ADB/Jest。
  • 状态:IMPLEMENTED / WAITING_ANDROID_REVALIDATION,等待用户重新构建 APK 并完成一次综合 Timeline 验收。

2026-09-04 — STEP-049 Android 复验与最终关闭

  • 用户已在 e34f04ba7038c5cb8fba8dc72c0d253cc4f7c85b 基线上完成 Android 综合复验:Timeline READY/PLAY、auto MIX、A/B→B/C→C/D、OLD_T1→NEW_T0 reuse、only NEW_T1 upload、Pause/Resume、Step/Seek、Gap/Recover、Invalid Next/Recover、Duplicate NOOP、Renderer fail-closed 与不黑屏全部 PASS。
  • 正常连续播放保持 simulationRebuild=false、trailCleared=false;Window 内 MIX 不产生 Field upload、simulation reset 或 style reload。
  • Validation UI MIX 百分比文本可能滞后,保留为 NON-BLOCKING observability,不影响 Core/Playback/Window/Renderer/Adapter 结论。
  • 本次为 docs-only 收尾,未执行 Android Gradle/APK/ADB/App/Jest,STEP-049 正式状态更新为 CLOSED / PASS。

2026-09-04 — STEP-051 Local Production-like Field Feed 与 Core Snapshot Submit Bridge

  • Starting HEAD 885e7aebef7fb5d02acaed57f9dcf98b8d9e9ba3;新增 provider-neutral maplibre-particle-field/v1 local metadata feed、四个时间片资源与 LocalParticleFieldFeed,正式复用 ParticleFieldDataAdapter/Snapshot。
  • RasterArraySource::submitInitialRuntimeFieldWindow(T0,T1) 建立薄 Core submit bridge;Timeline 使用 producer validTime,旧 fixture null timestamp 保留兼容 fallback,Window/Playback/Renderer ownership 未改变。
  • 新增 local feed 成功、严格 identity/generation/validTime、Timeline READY/PLAY 与非法 generation 拒绝测试;Linux OpenGL 定向 14/14 PASS。Android/Jest 未执行。
  • Android TIME 入口可加载 production-like resources;MIX 文本滞后仍为 NON-BLOCKING observability,Rotation/Viewport 技术债未扩大处理。
  • 状态:IMPLEMENTED / WAITING_ANDROID_VALIDATION。