123 lines
7.3 KiB
Markdown
123 lines
7.3 KiB
Markdown
# 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 的唯一当前验收阻塞。
|