Files
MapLibreParticleLab/docs/50_Step记录/STEP-088_静态底图缓存PoC与Renderer观测_v1.md
tei c58d370e71
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
docs: record STEP-088 retained underlay poc
2026-09-21 22:57:53 +09:00

123 lines
7.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# STEP-088 静态底图缓存 PoC 与 Renderer 观测 v1
## 状态
进行中
`IMPLEMENTED / WAITING FOR ANDROID VALIDATION`
## 目标
在固定 Camera、Style/Tile 稳定、2D 且存在 WeatherColor/RasterParticle 动态层时,把动态边界之前的连续普通 LayerGroup 前缀缓存为 retained underlay。Particle Tick 仍进入现有 MapLibre update/createRenderTree/prepare/upload 主链,但绘制阶段复用静态底图纹理,只实时绘制动态边界及其上方内容。
## 基线
- 分支:`particle/main`
- 起始 HEAD:`f47469d2ab77cdb959ecfe4081dc571fa1ab78f9`
- 实现提交:`8b9ab303228c307612c47f7f3379ad06206ea14e`
- 当前版本坐标:`13.4.1-particle.10`
## 必做项
- [x] Renderer-internal dynamic boundary。
- [x] LayerGroup before/from、forward/reverse 与 original ordinal。
- [x] Renderer-owned underlay cache 与 OpenGL/Metal compositor。
- [x] full-render fallback 与 legacy ordering 保护。
- [x] 7 个 Renderer debug counters。
- [x] Native 定向测试代码与 CMake 注册。
- [x] Mac OpenGL/Metal 编译及 4/4 定向测试由 RDC 完成。
- [ ] Android/NavSea 实机视觉、counters 与性能验证。
## 允许与禁止范围
允许修改 Renderer/Core/gfx backend/shader/CMake/Native test 和本 Step 文档;必要的 `test/gl/gl_functions.test.cpp` macOS 平台条件小修纳入本次。禁止 Android/NavSea/React 业务修改、Host API、C-001、STEP-089、STEP-090、production 全量 invalidation 与 animation-only fast path。
## 当前问题
STEP-086 已确认 Particle/WeatherColor 的 `needsRepaint()` 会唤醒完整 MapLibre frame。固定 Camera 下仍重复执行 source/layer orchestration、prepare、LayerGroup opaque/translucent draw 与 present;复杂 NavSea Style 因而持续重复提交大量静态 fill/line/symbol/PBF draw。
## 实现结构
- `RenderLayer` 新增仅 Renderer 内部使用的 `startsRetainedDynamicRange()`;WeatherColor 与 RasterParticle 返回 true,不增加 Host/public API。
- `RenderOrchestrator` 保存最小动态 boundary,并提供 before/from、forward/reverse 的 LayerGroup 分段 visitor;callback 保留完整序列 original ordinal。
- Renderer-owned `RetainedUnderlayCache` 持有 RGBA offscreen texture、depth/stencil renderable、compositor LayerGroup、key、valid 状态和 build/reuse/fallback/invalidation 数据。
- 新增独立 `RetainedUnderlayCompositeShader`,OpenGL/Metal 均为 fullscreen textured quad,只采样 premultiplied RGBA,不做 map transform、color ramp 或 Particle 业务。
- OpenGL OffscreenTexture 补齐可选 depth/stencil attachment;通用 gfx Context 的四参数 offscreen 接口由 OpenGL、Metal、Vulkan、WebGPU 后端显式覆盖。
- legacy `RenderLayer::render()` 当前仅 LocationIndicator 需要保护;若它位于 boundary 以下则 full-render fallback。
## Boundary
- WeatherColor 与 RasterParticle 都是 candidate。
- 两者同时存在时取实际 ordered layer 序列中的最小 index。
- only Particle 时使用 Particle index。
- 无 candidate 时 retained path disabled,完整原 Renderer 路径不变。
- 不依赖 React layer ID/name,不由 Host/NavSea 传入。
## Underlay Cache Flow
1. 保留 `Renderer::render → createRenderTree`、source update/prepare、layer prepare、`updateLayers/processChanges`、LayerGroup tweaker/upload。
2. 先按原顺序处理 independent RenderTargets。
3. cache invalid 时,把 boundary 前 LayerGroups 以原始 ordinal/depth 映射分别执行 opaque reverse 与 translucent forward,绘制到透明 clear 的 offscreen。
4. main framebuffer 仍按原 `backgroundColor/depth/stencil` 语义 clear;background optimized-as-color 路径未改。
5. composite cached underlay,再按完整序列 original ordinal 绘制 boundary 及之后的 opaque/translucent groups。
6. legacy items、debug overlay、postRender 与 present 保持原位置。
7. fixed key 且安全条件连续成立时复用;viewport、camera matrix 或 boundary 改变时重新 build。
## Fallback
以下状态不复用缓存:无 boundary、静态前缀为空、style 尚未 loaded、3D、任意 debug options、静态层 transition/repaint、placement/fade、boundary 以下 legacy ordering、offscreen/compositor 创建失败。不能建立安全资源时计数并回到完整绘制路径。
## Renderer 观测
在既有 debug-only counters 中新增:
- `FullRendererFrame`
- `RetainedUnderlayBuild`
- `RetainedUnderlayReuse`
- `RetainedUnderlayFallback`
- `RetainedUnderlayInvalidation`
- `RetainedUnderlayStaticGroupDraw`
- `RetainedDynamicGroupDraw`
`NDEBUG` 下仍为 no-op;未增加 Host API,也未增加逐帧日志。
## 构建与测试
以下由 RDC / 普通 Terminal 在当前 STEP-088 实现上完成:
- `cmake --build build-step088-opengl --target mbgl-test-runner -j3`:成功。
- STEP-088 定向测试:4/4 成功,覆盖 boundary、LayerGroup range/original ordinal、build/reuse/resize/boundary invalidation、3D/resource failure fallback。
- `cmake --build build-ios --config Debug --target mbgl-core -j3`:iOS/Metal device arm64 `BUILD SUCCEEDED`。
- `git diff --check`:成功。
- RDC 为 Mac OpenGL test-runner 链接补充 `test/gl/gl_functions.test.cpp` Apple 平台条件:macOS 不引用仅 iPhone/Simulator 提供的 `glInvalidateFramebuffer` / `glInvalidateSubFramebuffer`。
Codex 收尾阶段按新规则未再启动任何 build/test。Android Gradle、AAR/APK、ADB、Android 设备、NavSea 实机与 Jest 均未执行。
## PoC 限制
- 本 Step 只消除稳定场景下静态前缀的重复 GPU draw;没有跳过 Map update、createRenderTree、source/TilePyramid update、prepare、tweaker 或 upload。
- production 级 style/layer/source/tile/bucket/drawable、sprite/image/glyph、context/surface 等完整 invalidation 属于 STEP-089;本 PoC 只允许在固定 Camera、Style/Tile 稳定条件下判断 reuse。
- 未做 animation-only CPU fast path;STEP-090 未执行。
- 未做通用任意 static/dynamic RenderGraph,也未修改 NavSea、React 或 C-001。
## 用户 Android/NavSea 手工验证项
1. 固定 Camera、复杂真实 Style、Particle 约 30 FPS,确认视觉与原路径一致。
2. 观察 `RetainedUnderlayBuild ≈ 1`、`RetainedUnderlayReuse` 和 `ParticleSimulationAdvance` 持续增长。
3. 确认建 cache 后 `RetainedUnderlayStaticGroupDraw` 不随 Particle FPS 增长,`RetainedDynamicGroupDraw` 持续增长。
4. 分别验证 only Particle、WeatherColor + Particle 的两种 layer 顺序。
5. pan/zoom/resize 后确认 invalidation/rebuild,不能出现 stale underlay。
6. 验证 3D、debug 与 boundary 以下 legacy ordering 会安全回到 full render。
7. 对比 Particle OFF/ON 的 draw calls、RenderThread CPU、main/JS CPU 与画面叠放顺序。
## 当前结果与下一步
STEP-088 实现与 Mac OpenGL/Metal、Native 定向测试已完成;Android/NavSea 运行态证据尚缺。因此当前不满足进入 STEP-089 的验收条件,不得进入 STEP-089/090。下一步仅由用户/RDC 完成上述 Android/NavSea 手工验证并回传事实。
## 必做输出与阻塞
- Step 记录:本文。
- Codex 完成报告:`docs/报告/STEP-088_静态底图缓存PoC与Renderer观测_Codex完成报告_v1.md`。
- 开发记录:已追加 `粒子开发记录.md`。
- 阻塞:Android/NavSea 实机验证尚未执行;这是关闭 STEP-088 和进入 STEP-089 的唯一当前验收阻塞。