5.1 KiB
5.1 KiB
30-02 GPU Ping-Pong 与 Context Recreation 最小技术验证报告 v3
日期:2026-08-30
当前状态:WAITING_MANUAL_VALIDATION
1. 本轮实机发现
用户在 30-02 v2 对应 Android OpenGL APK 上完成 T3 检查并明确报告:
- STATIC 静止时,粒子/Trail 正常停止;
- STATIC 下拖动地图时,MapLibre redraw 会使 State/Trail 继续推进;
- 停止拖动后,State/Trail 再次停止。
因此原实现的 T3 判定为 FAIL。这是明确的设备运行事实;本报告不补写用户未提供的 frame 数值或日志数值。
2. 原因
原实现只在 needsRepaint() 中用 ACTIVE/STATIC 控制验证层是否主动请求下一帧,但 RenderParticleValidationLayer::update() 没有按 ACTIVE/STATIC 区分 GPU 工作。
地图 pan/zoom/bearing/pitch 会合法触发 MapLibre redraw;每次 redraw 都会再次执行原 update(),继而:
- 注册 State write RenderTarget;
- 注册 Trail write RenderTarget;
- 设置
pending=true; - composite Tweaker 调用
commit(); - State/Trail slot 与
committedFrame前进。
所以 needsRepaint=false 只能停止 validation 自己制造的连续帧,不能保证在其他合法地图帧中冻结 GPU simulation。
3. 最小修复
仅修改:
src/mbgl/renderer/layers/render_particle_validation_layer.cppsrc/mbgl/renderer/layers/render_particle_validation_layer.hpp(说明性注释)
修复内容:
update()在已有资源上先撤销上一帧注册的 RenderTarget,然后读取当前 evaluated ACTIVE 状态。- STATIC 分支不注册任何 State/Trail RenderTarget,不创建 State/Trail update Drawable,并清除任何
pendingswap。 - STATIC 只为主 LayerGroup 建立
FrozenCompositeDrawable,采样最后一次已经 commit 的trailReadtexture。 FrozenCompositeTweaker可以在当前 MapLibre translucent pass 更新 composite UBO/texture 并读取当前 viewport、zoom、bearing、pitch,但在调用commit()前明确返回。- STATIC 的 shader frame 值使用当前
committedFrame,不预先计算为下一 simulation frame。 - STATIC 下即使 viewport 改变也不重建、清空或推进 Trail;冻结 texture 由主 pass 重新显示。恢复 ACTIVE 后,既有 ACTIVE resize 路径才重建 Trail。
- 如果 layer 从未有过 ACTIVE/已 commit Trail 就直接处于 STATIC,不创建或清屏离屏资源,也不显示未初始化 texture。
- ACTIVE 路径的 State A/B、Trail A/B、pass 顺序、hazard 约束和 slot commit 保持不变。
4. 静态控制流确认
以下事实已经从修复后源码确认:
AddRenderTargetRequest只存在于 STATIC 提前返回之后的 ACTIVE 路径。- State/Trail
buildQuad()只存在于 ACTIVE 路径。 resources->pending = true只存在于 ACTIVE 路径。- STATIC 进入时强制
resources->pending = false。 FrozenComposite在 Tweaker 内先返回,不可能落入resources->commit()。- STATIC composite 绑定
trailTargets[trailRead],read/write slot 参数相同且没有 target attachment。 - MapLibre redraw 没有被阻止;主 LayerGroup composite 仍会在当前地图 render pass 中执行。
5. 静态检查
- C++
clang-format --dry-run --Werror:PASS。 git diff --check:PASS。- ACTIVE/STATIC、RenderTarget 注册、pending、commit 与
committedFrame控制流检索:PASS。 - 编译、Android、Gradle、ADB、安装与运行:未执行,遵守用户要求。
静态检查只能证明代码路径,不替代 Android OpenGL 重测。
6. T3 重新验证
使用包含修复提交 364b8f381e27eee36c4895084b2f0578a023fa61 的新 APK:
- 进入
Particle Core Layer Validation,保持 ACTIVE,确认 State/Trail 正常交替并记下最近一次commit frame=N、State read slot 与 Trail read slot。 - 点击 STATIC,确认日志出现:
STATIC frozen composite ... frame=N ... offscreenPasses=0 swap=false。 - STATIC 静止至少 3 秒,确认粒子/Trail 不推进。
- STATIC 下连续执行 pan、zoom、bearing、pitch;地图必须正常移动和 redraw,冻结 Trail 可以随主 pass 重新显示。
- 操作期间确认画面中的 marker/fade 不推进;不得出现新的 State pass、Trail pass、slot swap 或 simulation
commit frame增长。 - 停止操作后仍保持冻结。
- 点击 ACTIVE,确认 GPU ping-pong 从冻结的 State/Trail slot 继续,而不是在 STATIC 操作期间跳过 frame/index;继续运行到下一次节流日志,确认 frame 恢复增长。
- 再执行一次 ACTIVE → STATIC → 地图手势 → ACTIVE,排除只在首次切换正确。
用户手工日志命令:
adb -s 192.168.1.146 logcat | grep -E 'ParticleValidation30_02|ParticleValidation'
7. 仍需完成的 30-02 验证
本轮只修复 T3。以下仍沿用 v2 的待验证状态:
- 修复后 T3 Android OpenGL 重测;
- T4 resize;
- T5 disable/enable;
- T6/T7 真实 context/surface recreation 与恢复;
- 无 stale resource/framebuffer corruption/crash;
- 最终完整 PASS 证据。
当前最终状态仍为 WAITING_MANUAL_VALIDATION,不得写 PASS,也不允许进入 30-03。