11 KiB
STEP-088 静态底图缓存 PoC 与 Renderer 可观测性 Codex 任务 v1
1. 任务目标
基于最新 origin/particle/main 实际代码,实现第一阶段 Retained Static Underlay PoC。
核心目标:
- Camera 固定、Style/Tile 稳定、存在 WeatherColor/Particle 时,把动态层之前连续普通 LayerGroup 前缀 render 到 offscreen texture。
- 后续 Particle Tick 继续走当前 onUpdate/createRenderTree,但不再重复 draw 静态前缀,而复用 cached underlay texture。
- Particle simulation/render 继续按 cadence 正常。
- 增加 Renderer 可观测性。
- 本任务只执行 STEP-088,不得执行 STEP-089/090。
2. 执行基线
直接在主仓库: /Users/tei/dev/MapLibreParticleLab
目标主线: origin/particle/main
执行前:
- git fetch origin particle/main。
- 确认本地 HEAD、origin/particle/main、git status。
- 不 reset/clean,不覆盖用户既有未提交修改。
- 如存在无关本地修改,只修改、stage、commit STEP-088 相关文件。
- 以当前实际代码为准,不得凭旧版本猜接口。
必须阅读:
- docs/40_任务/粒子连续渲染静态底图缓存与动画快路径优化规划_v1.md
- 本任务书
- docs/20_调查/STEP-086_Particle连续渲染唤醒MapLibre整图成本调查_v1.md
- docs/00_项目总则/
- docs/00_项目规范/
- 根目录 AGENTS.md(如存在)
3. 开工前只读确认
必须确认并在完成报告记录:
- RenderRasterParticleLayer::needsRepaint()
- RenderWeatherColorLayer::needsRepaint()
- Renderer::render()
- RenderOrchestrator::createRenderTree()
- RenderOrchestrator::hasTransitions()
- renderer_impl.cpp 的 updateLayers/processChanges
- LayerGroup tweaker/upload
- visitRenderTargets
- main clear
- opaque/translucent pass
- present
- RenderTarget / OffscreenTexture
- Heatmap/Hillshade offscreen + texture composite 样板
涉及文件至少:
- src/mbgl/renderer/layers/render_particle_validation_layer.cpp
- src/mbgl/renderer/layers/render_weather_color_layer.cpp
- src/mbgl/renderer/renderer.cpp
- src/mbgl/renderer/render_orchestrator.cpp/.hpp
- src/mbgl/renderer/renderer_impl.cpp/.hpp
- include/mbgl/renderer/render_target.hpp
- src/mbgl/renderer/render_target.cpp
- src/mbgl/renderer/layers/render_heatmap_layer.cpp
- src/mbgl/renderer/layers/render_hillshade_layer.cpp
4. 修改一:retained dynamic boundary
重点修改:
- src/mbgl/renderer/render_layer.hpp
- src/mbgl/renderer/layers/render_weather_color_layer.hpp
- src/mbgl/renderer/layers/render_raster_particle_layer.hpp
增加仅 Renderer 内部使用的虚函数,语义类似: virtual bool startsRetainedDynamicRange() const { return false; }
WeatherColor 与 RasterParticle override=true。
规则:
- 两者同时存在取最小实际 layerIndex。
- only Particle 使用 Particle index。
- 无 candidate 时完全走原 Renderer。
- 禁止根据 React layer ID/name 字符串硬编码。
- 禁止让 NavSea/Host 传 boundary。
- 不新增 public API。
5. 修改二:RenderOrchestrator LayerGroup 分段访问
重点修改:
- src/mbgl/renderer/render_orchestrator.hpp
- src/mbgl/renderer/render_orchestrator.cpp
必要时小改:
- include/mbgl/renderer/layer_group.hpp
- src/mbgl/renderer/layer_group.cpp
需要:
- 查询 retained dynamic boundary。
- 遍历 boundary 之前 groups。
- 遍历 boundary 及之后 groups。
- forward/reverse 都支持。
- callback 能获得完整原始 LayerGroup 序列 ordinal。
可采用 before/from visitor 或更通用 indexed/range visitor。
关键: parameters.currentLayer、depthRangeSize、opaque/translucent ordering 必须与完整遍历等价。 不得让 dynamic subset 从 0 重新编号导致 depth/transparency 变化。
6. 修改三:Renderer-owned RetainedUnderlayCache
优先新增:
- src/mbgl/renderer/retained_underlay_cache.hpp
- src/mbgl/renderer/retained_underlay_cache.cpp
并在 CMakeLists.txt 真实 source list 注册。
至少维护:
- offscreen renderable / texture
- viewport size
- boundary
- valid
- buildCount
- reuseCount
- fallbackCount
- last invalidation reason
不要修改 Heatmap/Hillshade RenderTarget 原有语义。
STEP-088 至少保证:
- resource 创建失败 -> full-render fallback
- viewport resize -> invalid
- boundary change -> invalid
- has3D -> fallback
- Debug Overdraw 等明显不兼容模式 -> fallback
- context 不可用 -> 不复用
- Camera fingerprint 连续相同、style loaded、2D、boundary stable 才允许 reuse
任何不能证明安全的状态都 full render。
7. 修改四:Renderer::Impl 分离 Static Underlay / Dynamic Range
重点:
- src/mbgl/renderer/renderer_impl.hpp
- src/mbgl/renderer/renderer_impl.cpp
STEP-088 必须保留:
- Renderer::render -> createRenderTree
- source update/prepare
- layer prepare
- updateLayers
- LayerGroup tweaker/upload
只修改真正 draw 阶段。
目标流程:
- existing independent RenderTargets。
- cache invalid 时,boundary 前 LayerGroups render 到 offscreen 并 mark valid。
- main clear。
- composite cached underlay texture。
- boundary 及之后 opaque/translucent 正常 render。
- legacy items 按安全规则。
- debug。
- present。
Underlay offscreen 优先透明 clear。 main framebuffer 保持原 backgroundColor/depth/stencil 语义。 必须确认 background layer optimized-as-color 路径。
8. Legacy RenderItems
renderer_impl.cpp translucent pass 仍有 legacy layerRenderItems。
必须确认是否有 boundary 以下 legacy item。
- 无法安全按 layerIndex 切分时不纳入 cache。
- 可能破坏 ordering 时 fallback full render。
- 不得静默改变顺序。
9. 修改五:cached texture compositor
不要正式复用 LocationIndicatorTexturedShader。
建议新增: RetainedUnderlayCompositeShader
职责:
- viewport/fullscreen quad
- sample cached RGBA
- 正确 premultiplied alpha
- 不做 color ramp
- 不做 map transform
- 不做 Particle 业务
按当前真实 shader 注册规则检查/修改至少:
- include/mbgl/shaders/shader_source.hpp
- src/mbgl/shaders/shader_source.cpp
- include/mbgl/shaders/shader_defines.hpp
- include/mbgl/shaders/shader_manifest.hpp
- include/mbgl/shaders/gl/shader_info.hpp
- src/mbgl/shaders/gl/shader_info.cpp
- src/mbgl/gl/renderer_backend.cpp
- src/mbgl/mtl/renderer_backend.cpp
- cmake/opengl.cmake
- cmake/metal.cmake
- 新增 GL/Metal compositor shader 文件
如当前 shader codegen 要求生成文件,按真实 codegen 走。 Android OpenGL 与 iOS Metal 语义都要完整。
10. Renderer Debug Counters
修改:
- include/mbgl/particle/renderer_debug_counters.hpp
至少新增:
- FullRendererFrame
- RetainedUnderlayBuild
- RetainedUnderlayReuse
- RetainedUnderlayFallback
- RetainedUnderlayInvalidation
- RetainedUnderlayStaticGroupDraw
- RetainedDynamicGroupDraw
要求:
- NDEBUG 下 no-op
- 不增加 Host API
- 不每帧刷大量日志
允许有限首次日志:cache enabled/build/fallback reason。
11. Native 定向测试
不新增或运行 Jest。
至少覆盖: Boundary:
- 无 Weather/Particle -> disabled
- only Particle
- Weather + Particle 不同顺序
LayerGroup range:
- before/from
- forward/reverse
- original ordinal
Cache:
- first build
- reuse
- resize invalid
- boundary change invalid
- unsupported 3D fallback
Failure:
- compositor/resource 创建失败 -> safe fallback/no crash
测试放当前 renderer test 真实结构,不新造孤立测试框架。
12. Mac 编译与验证
本任务采用仓库 AGENTS.md 的固定闭环:
Codex 写代码 → RDC 执行编译/测试 → 失败则把错误证据交回 Codex 修复 → RDC 再验证
Codex 本轮负责:
- 完成 Renderer / OpenGL / Metal 相关源码与测试代码实现;
- 给出 RDC 需要执行的精确命令;
- 不自行启动、等待或轮询长时间编译/测试;
- RDC 返回失败日志后,继续分析并修复代码。
由 RDC / 普通 Terminal 实际执行:
- 编译受影响 Renderer C++ target;
- 编译 OpenGL compositor shader 相关 target;
- 编译 Metal compositor shader 相关 target;
- 运行直接相关 C++ 定向测试;
- git diff --check。
RDC 返回结果时:
- 成功:返回 exit code、耗时、target 摘要;
- 失败:返回首个真实 error、相关 target、必要上下文和完整日志路径;
- 不把完整大型 build log 反复送入 Codex。
明确禁止 Codex 执行:
- CMake / Ninja / Bazel 长时间编译;
- OpenGL / Metal 长时间构建等待;
- Android Gradle build;
- AAR/APK build/install;
- ADB;
- Android App 启动/清数据;
- Android 真机/虚拟机;
- Jest。
Android 最终由用户手工验证。
13. PoC 验收证据
理想 fixed Camera + Particle ~30 FPS:
- RetainedUnderlayBuild ≈ 1
- RetainedUnderlayReuse 持续增长
- ParticleSimulationAdvance 持续增长
- RetainedUnderlayStaticGroupDraw 建 cache 后不随 Particle FPS 增长
- RetainedDynamicGroupDraw 持续增长
如 Mac 无法跑完整 Particle runtime:
- 完成 Native 定向/静态验证
- 给出用户最少 Android 手工验证项
- 最终状态必须:IMPLEMENTED / WAITING FOR ANDROID VALIDATION
- 不得写 CLOSED / PASS
14. 本任务明确不做
- production 全部 tile/style/placement invalidation
- Map::Impl::onUpdate fast path
- 跳过 createRenderTree
- 跳过 source->update
- 跳过 TilePyramid::update
- 跳过普通 prepare
- 新 Host API
- NavSea React 修改
- AIS 专项优化
- 通用任意 static/dynamic RenderGraph
- STEP-089
- STEP-090
15. 文档输出
必须生成:
- docs/50_Step记录/STEP-088_静态底图缓存PoC与Renderer观测_v1.md
- docs/报告/STEP-088_静态底图缓存PoC与Renderer观测_Codex完成报告_v1.md
如同主题已有,递增版本,不覆盖旧报告。
Step 记录至少写:
- 当前问题
- 实现结构
- boundary
- underlay cache flow
- PoC 限制
- 用户 Android 手工验证项
完成报告必须写:
- 起始 HEAD / 最终 HEAD
- 修改文件
- boundary 实现位置
- LayerGroup 分段实现位置
- cache/compositor 实现位置
- debug counters
- 测试/编译结果
- Android 未执行项
- fallback
- 是否满足进入 STEP-089 条件
- final commit hash
- commit message
- push result
- remote branch
- Final HEAD
16. Git 收尾
完成后:
- 只 stage/commit STEP-088 相关文件。
- 不提交当前主仓库既有无关 dirty/untracked 内容。
- commit message 建议:feat: add retained underlay render cache poc
- push 到 origin/particle/main。
- push 前 fetch;远端前进时安全整合本任务。
- push 失败不得声称完成。
- 最终确认任务提交已在 origin/particle/main。
17. 最终响应
直接逐项报告:
- 已完成
- 未完成
- 无法验证
不要再输出实施计划。