From ba488f87027b3a53e7eb031e26c263c39a26bdc0 Mon Sep 17 00:00:00 2001 From: OpenAI Codex Date: Sat, 29 Aug 2026 21:27:45 +0800 Subject: [PATCH] docs: record 30-02 manual validation handoff --- ...ong与ContextRecreation最小技术验证报告_v2.md | 112 ++++++++++++++++ ...g与ContextRecreation验证_Codex完成报告_v2.md | 126 ++++++++++++++++++ 粒子开发记录.md | 14 ++ 3 files changed, 252 insertions(+) create mode 100644 docs/60_测试/30_02_GPU_PingPong与ContextRecreation最小技术验证报告_v2.md create mode 100644 docs/报告/30_02_GPU_PingPong与ContextRecreation验证_Codex完成报告_v2.md diff --git a/docs/60_测试/30_02_GPU_PingPong与ContextRecreation最小技术验证报告_v2.md b/docs/60_测试/30_02_GPU_PingPong与ContextRecreation最小技术验证报告_v2.md new file mode 100644 index 000000000..0000f8553 --- /dev/null +++ b/docs/60_测试/30_02_GPU_PingPong与ContextRecreation最小技术验证报告_v2.md @@ -0,0 +1,112 @@ +# 30-02 GPU Ping-Pong 与 Context Recreation 最小技术验证报告 v2 + +日期:2026-08-29 + +当前状态:`WAITING_MANUAL_VALIDATION` + +## 1. 前置状态与本轮范围 + +- 30-01 已由用户完成 Android OpenGL 实机验收并正式记录为 `PASS`;PASS 回填提交为 `b34b0a3e22f91a0101b0bbd02190e3384f6ef2ae`。 +- 历史 v1 报告的 `BLOCKED` 保留不改;它记录的是当时 30-01 正式状态尚未回填,不是 GPU/gfx 失败。 +- 本轮只准备 Android OpenGL 的 30-02 validation-only Stage A;未实现正式粒子、真实 Field、Mask、Vulkan 或 iOS。 + +## 2. 静态源码确认 + +以下是 Codex 可从源码确认的实现事实,不等同于设备运行结论: + +- `RenderParticleValidationLayer` 建立固定 `16x16` 的 State A/B 两套独立 `RenderTarget`,每帧从 read slot 采样并写入另一个 slot。 +- Trail A/B 是两套与当前 viewport 同尺寸的真实 `RenderTarget`;Trail pass 读取 previous trail,执行 `0.965` fade 并加入移动 marker,随后由主 translucent pass 合成。 +- 正常帧只把 State write 与 Trail write 注册到当帧 render-target list;read target 不作为当帧附件,从结构上避免同一 texture 同时采样和写入。 +- 首帧或 Trail resize 后,新的 read target 先以空 group 清屏;注册顺序为 State 初始化/写入、Trail 初始化/写入,主 LayerGroup 随后合成最新 Trail。 +- ping-pong slot 在主 pass 的 Drawable Tweaker 到达时提交;此时当帧离屏 State/Trail pass 已按 `RenderOrchestrator` 的 render-target 顺序完成编码。 +- 每帧只更新小型 UBO;没有 CPU 回读或复制完整 State/Trail 数据。 +- viewport 改变时只重建 Trail A/B,State A/B 保持固定尺寸和当前状态。 +- layer 不可渲染时移除已注册 target 并重置 slot/frame;layer remove 会移除 target;context lost 会记录旧 generation 被丢弃,新的 RenderLayer/resource set 使用递增 generation。 +- shader 只注册到当前 OpenGL backend;没有修改 Vulkan、Metal 或 iOS shader/backend。 +- 没有修改 `RenderTarget`、`CommandEncoder` 或其他通用 gfx API;使用现有 `createRenderTarget`、render-target 顺序、pass end/present 与 texture sampling 链。 + +## 3. DrawableBuilder 生命周期 + +所有新 Drawable 都严格执行:配置 builder → `flush(context)` 完成当前 Drawable → `clearDrawables()` 转移已完成对象 → `LayerGroup::addDrawable()`。没有恢复 30-01 曾出现的“未 finalize 就 clear”错误,也没有通过空指针跳过 render pass。 + +## 4. 验证日志 + +日志关键字:`ParticleValidation30_02`。状态变化与第 1 帧/每 60 帧记录: + +- resource `generation`; +- State/Trail A/B create、resize、destroy/context-lost; +- `frame`、State read/write、Trail read/write; +- `order=State,Trail,Composite`; +- `hazard=SAFE` / `distinct=true` / `cpuStateCopy=false`; +- viewport、zoom、bearing、pitch; +- Test App ACTIVE、STATIC、DISABLED 状态。 + +日志是待用户采集的验证接口;本报告未伪造任何设备日志。 + +## 5. 静态检查结果 + +- shader manifest JSON 解析:PASS。 +- shader 源生成并确认 OpenGL generated header、BuiltIn、manifest 注册存在:PASS。 +- C++ `clang-format --dry-run --Werror`:PASS。 +- `git diff --check`:PASS。 +- shader ID、UBO、attribute、texture、GL ShaderInfo 与 GL backend 注册符号一致性检索:PASS。 +- Android XML:已人工检查结构;环境缺少 `xmllint`/Ruby XML parser,未宣称解析器 PASS。 +- 编译、Gradle、Android 构建、安装、ADB、设备运行:均未执行,遵守用户“不编译”和指令书限制。 + +## 6. 用户手工编译与安装 + +当前 Makefile 的 x86_64 Test App OpenGL 命令为: + +```bash +cd /mnt/sda1/MapLibreParticleLab +source /root/.maplibre-particle-env +cd platform/android +RENDERER=opengl BUILDTYPE=Debug JOBS=3 make android-x86-64 +``` + +预期 APK: + +```text +platform/android/MapLibreAndroidTestApp/build/outputs/apk/opengl/debug/MapLibreAndroidTestApp-opengl-debug.apk +``` + +如需命令行安装,必须由用户手工执行: + +```bash +adb -s 192.168.1.146 install -r platform/android/MapLibreAndroidTestApp/build/outputs/apk/opengl/debug/MapLibreAndroidTestApp-opengl-debug.apk +``` + +## 7. 用户手工运行步骤 + +1. 打开 Test App,在主菜单顶部确认 APK 版本/Git revision,再进入 `Custom Layer` → `Particle Core Layer Validation`。 +2. 过滤日志:`adb -s 192.168.1.146 logcat | grep -E 'ParticleValidation30_02|ParticleValidation'`。 +3. T1 初始创建:确认 State A/B、Trail A/B create,generation 初值和 `frame=1` commit;地图与蓝/黄顺序参照正常。 +4. T2 ACTIVE:保持至少 120 帧;确认 State 与 Trail 均 A/B 交替、frame 增长、轨迹 marker 移动/衰减且地图正常。 +5. T3 STATIC:点击 STATIC 并静置,确认 validation 不再主动推进;随后 pan/zoom/rotate/pitch,确认地图事件可触发 redraw,停止操作后不再持续推进。 +6. T4 resize:旋转屏幕或改变模拟器窗口尺寸;确认 `Trail A/B resize old=... new=... StatePreserved=true`,State A/B 没有重新 create,地图无异常。 +7. T5 disable/enable:点击 DISABLE,确认 layer/resource destroy 且停止;点击 ENABLE,确认新 generation 建立、slot/frame 从初始状态恢复,无 crash。 +8. T6 context/surface recreation:保持 App 进程存活,先 Home/Recent Apps 切出再返回;若没有出现 `context lost discard`,启用开发者选项“不保留活动”后离开并返回验证 Activity,或旋转触发 Activity/Surface 重建。仅界面重现不算成功,必须捕获旧 generation 的 `context lost discard`/destroy 和新 generation create。 +9. T7 recreation 后继续 ACTIVE 至少 120 帧;确认新 generation 的 ping-pong 恢复、Trail 从清空重新积累、无旧 generation 后续 commit、地图正常、无 crash/stale framebuffer。 +10. 保存完整关键日志和可见现象,回传给 Codex 进入阶段 B。 + +可选手工启动命令: + +```bash +adb -s 192.168.1.146 shell am start -n org.maplibre.android.testapp/.activity.particle.ParticleCoreLayerValidationActivity +``` + +## 8. 当前证据边界与未验证项 + +- 用户手工编译结果:未提供。 +- Android OpenGL 实际运行结果:未提供。 +- State/Trail 实机持续交替:未验证。 +- 当前 OpenGL driver 的 pass 同步/hazard:静态设计成立,尚无实机证据。 +- resize、disable/enable:尚无实机证据。 +- 真实 EGL context/surface recreation、旧资源失效与新 generation 恢复:尚无实机证据。 +- crash、framebuffer corruption、地图回归:尚无实机证据。 + +因此当前不能判定 PASS,也未发现可据以判定 FAIL 的运行证据;正式状态只能是 `WAITING_MANUAL_VALIDATION`。 + +## 9. 30-03 状态 + +不允许进入 30-03。必须先由用户完成上述 Android OpenGL 手工验证,并在阶段 B 将 30-02 正式更新为 `PASS`;若无法确认真实 context recreation,则按指令书判定 `BLOCKED`。 diff --git a/docs/报告/30_02_GPU_PingPong与ContextRecreation验证_Codex完成报告_v2.md b/docs/报告/30_02_GPU_PingPong与ContextRecreation验证_Codex完成报告_v2.md new file mode 100644 index 000000000..e0f32d023 --- /dev/null +++ b/docs/报告/30_02_GPU_PingPong与ContextRecreation验证_Codex完成报告_v2.md @@ -0,0 +1,126 @@ +# 30-02 GPU Ping-Pong 与 Context Recreation 验证 Codex 完成报告 v2 + +日期:2026-08-29 + +执行结论:`WAITING_MANUAL_VALIDATION` + +## 1. 前置状态与 Git 基线 + +- 30-01 正式状态:`PASS`。 +- 30-01 PASS 回填 commit:`b34b0a3e22f91a0101b0bbd02190e3384f6ef2ae`。 +- 本任务开始分支:`particle/main`。 +- 本任务开始 HEAD:`b34b0a3e22f91a0101b0bbd02190e3384f6ef2ae`。 +- 开始时本地与 `origin/particle/main` 同步,工作区干净。 +- 历史阻塞 commit `25072cff1b3a538af361b572cd7e79cd4a471b07` 与 30-02 v1 BLOCKED 报告均完整保留。 + +## 2. 前置材料读取 + +已读取 `AGENTS.md`、`PARTICLE_BASELINE.md`、`docs/00_项目总则/`、`docs/00_项目规范/`、当前 STEP-000、30-02 指令书、架构调查/设计、30-01 最新 PASS 技术报告与完成报告、30-02 v1 历史阻塞报告及 `粒子开发记录.md`。按指令书未创建或修改 Step。 + +## 3. 实际修改文件 + +Core validation 与 shader: + +- `src/mbgl/renderer/layers/render_particle_validation_layer.cpp/.hpp` +- `shaders/particle_gpu_validation.vertex.glsl` +- `shaders/particle_gpu_validation.fragment.glsl` +- `shaders/manifest.json` +- `include/mbgl/shaders/gl/particle_gpu_validation.hpp` +- `include/mbgl/shaders/particle_gpu_validation_ubo.hpp` +- `include/mbgl/shaders/gl/shader_info.hpp` +- `include/mbgl/shaders/shader_defines.hpp` +- `include/mbgl/shaders/shader_manifest.hpp` +- `include/mbgl/shaders/shader_source.hpp` +- `src/mbgl/shaders/gl/shader_info.cpp` +- `src/mbgl/shaders/shader_source.cpp` +- `src/mbgl/gl/renderer_backend.cpp` + +Android Test App: + +- `platform/android/MapLibreAndroidTestApp/src/main/java/org/maplibre/android/testapp/activity/particle/ParticleCoreLayerValidationActivity.kt` +- `platform/android/MapLibreAndroidTestApp/src/main/res/layout/activity_particle_core_layer_validation.xml` +- `platform/android/MapLibreAndroidTestApp/src/main/res/values/strings.xml` + +文档:本 v2 完成报告、对应 v2 技术报告,并追加 `粒子开发记录.md`。 + +## 4. State A/B 实现与创建链 + +`ParticleGpuValidationResources` 持有两套固定 `16x16`、RGBA unsigned-byte `RenderTarget`。创建链为 `gfx::Context::createRenderTarget` → 现有 `RenderTarget`/`OffscreenTexture` → 独立 texture;每个 target 各有一个 validation-only `LayerGroup`。State shader 从 read slot 采样并将确定性演进结果写到相反 slot,没有 CPU full-state copy。 + +## 5. Trail A/B 与 composite + +Trail A/B 是两套 viewport 尺寸的真实 `RenderTarget`。Trail pass 采样 previous trail,执行 fade 加移动 marker,写 next trail。主 RenderLayer 的 translucent Drawable 随后采样本帧 next trail并以预乘 alpha 合成到 MapLibre 主 pass;没有 MapView 外部 Overlay。 + +## 6. ping-pong swap、pass 顺序与 hazard + +- 正常帧只注册 State write 和 Trail write;对应 read target 不进入当帧 render-target list。 +- 初次创建/resize 时,新的 read target 以空 LayerGroup 先清屏。 +- `RenderOrchestrator` 按添加顺序访问 RenderTarget;本层添加顺序保证 State 在 Trail 前,主 LayerGroup composite 在所有 offscreen target 后。 +- Drawable Tweaker 在主 translucent pass 到达时提交 A/B slot 交换,因此下一帧才把本帧输出作为 read。 +- Tweaker 同时比较 source/target texture identity,异常时输出 `HAZARD`;正常节流日志输出 `distinct=true`。 +- 该结论目前是源码/调度顺序确认;Android OpenGL driver 的实际同步语义仍待用户实机日志与画面确认。 + +## 7. Android OpenGL backend 事实 + +新增 shader 只加入 OpenGL `RendererBackend::initShaders`、GL `ShaderInfo` 与生成的 GL source。没有添加 Vulkan/Metal/WebGPU shader,也没有把 raw OpenGL 调用写入 Core validation 逻辑。 + +## 8. resize、disable/enable、context lifecycle 与 generation + +- resize:仅销毁并重建 Trail A/B;State A/B 不重建,日志标记 `StatePreserved=true`。 +- disable:renderability 关闭时移除 target、清空验证 Drawable、重置 frame/slot;当前 Test App 的 DISABLE 通过移除 validation layer 强制完整 resource destroy。 +- enable:Test App 重新加入 validation layer,新 resource generation 从初始 slot/frame 创建。 +- context/surface:Android OpenGL 现有 surface lifecycle 会通知 renderer context lost;本 RenderLayer 的 `markContextDestroyed()` 记录旧 generation discard,RenderLayer 重建时进程内 atomic generation 递增。 +- generation 机制只服务验证日志,不是正式粒子资源管理 API。 + +## 9. Test App 入口 + +继续复用 `Custom Layer` → `Particle Core Layer Validation`,保留 30-01 ACTIVE/STATIC,并增加 DISABLE/ENABLE。主菜单既有 APK version/renderer/build type/Git revision 标识保持不变。没有创建第二套 Test App 或产品 UI。 + +## 10. 手工编译与运行 + +手工编译命令: + +```bash +cd /mnt/sda1/MapLibreParticleLab +source /root/.maplibre-particle-env +cd platform/android +RENDERER=opengl BUILDTYPE=Debug JOBS=3 make android-x86-64 +``` + +APK 预期路径:`platform/android/MapLibreAndroidTestApp/build/outputs/apk/opengl/debug/MapLibreAndroidTestApp-opengl-debug.apk`。 + +完整 T1–T7 手工运行步骤、带 `adb -s 192.168.1.146` 的安装/启动/logcat 示例见技术报告 v2 第 6–7 节。 + +## 11. 检查与未执行项 + +- shader manifest JSON:PASS。 +- shader 生成/注册链静态一致性:PASS。 +- C++ clang-format:PASS。 +- `git diff --check`:PASS。 +- Android XML:人工结构检查;环境无 XML parser,未宣称工具 PASS。 +- Android/Gradle/ADB/APK 构建安装:未执行。 +- 任何 C++/Android 编译:未执行,遵守用户“不要编译”。 +- 用户实机日志、画面、resize、context recreation:尚未提供。 + +## 12. 修改边界 + +- 通用 gfx API:未修改;现有 API 足以表达本验证。 +- 正式生产 Particle/Field/Mask:未实现。 +- 依赖、SDK、NDK、Gradle、MapLibre baseline:未修改。 +- Vulkan/iOS/Metal、30-03:未开始。 +- Shader/OpenGL backend 的修改仅是注册 validation-only shader,不是通用 renderer 重构。 + +## 13. 当前判定与 30-03 + +Stage A 代码已准备并推送,但所有关键 GPU/context 门槛仍缺用户实际运行证据,因此状态必须为 `WAITING_MANUAL_VALIDATION`,不是 PASS/FAIL。30-03 不允许开始;若用户环境最终无法用日志确认真实 context recreation,则 30-02 应判定 `BLOCKED`。 + +## 14. Git 收尾 + +- 主要变更 commit:`2f1506747b1dad8e89e526058a2951e9734ba99b`。 +- commit message:`test: add particle gpu ping-pong validation`。 +- 主要变更 push:成功。 +- 公开远端:`origin`(`ssh://git@192.168.200.230:2222/tei/MapLibreParticleLab.git`)。 +- 远端分支:`particle/main`。 +- 主要变更远端可见 HEAD:`2f1506747b1dad8e89e526058a2951e9734ba99b`。 +- 本文档与开发记录的收尾 commit 及最终远端 HEAD:按指令书的自引用处理规则,在最终回复中记录。 +- 未提交的无关本地改动:无。 diff --git a/粒子开发记录.md b/粒子开发记录.md index ea10c6dee..41774fc47 100644 --- a/粒子开发记录.md +++ b/粒子开发记录.md @@ -80,3 +80,17 @@ - 本次只回填验收状态:未重新修改 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`。