7.3 KiB
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
必做项
- Renderer-internal dynamic boundary。
- LayerGroup before/from、forward/reverse 与 original ordinal。
- Renderer-owned underlay cache 与 OpenGL/Metal compositor。
- full-render fallback 与 legacy ordering 保护。
- 7 个 Renderer debug counters。
- Native 定向测试代码与 CMake 注册。
- 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
- 保留
Renderer::render → createRenderTree、source update/prepare、layer prepare、updateLayers/processChanges、LayerGroup tweaker/upload。 - 先按原顺序处理 independent RenderTargets。
- cache invalid 时,把 boundary 前 LayerGroups 以原始 ordinal/depth 映射分别执行 opaque reverse 与 translucent forward,绘制到透明 clear 的 offscreen。
- main framebuffer 仍按原
backgroundColor/depth/stencil语义 clear;background optimized-as-color 路径未改。 - composite cached underlay,再按完整序列 original ordinal 绘制 boundary 及之后的 opaque/translucent groups。
- legacy items、debug overlay、postRender 与 present 保持原位置。
- 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 中新增:
FullRendererFrameRetainedUnderlayBuildRetainedUnderlayReuseRetainedUnderlayFallbackRetainedUnderlayInvalidationRetainedUnderlayStaticGroupDrawRetainedDynamicGroupDraw
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 arm64BUILD SUCCEEDED。git diff --check:成功。- RDC 为 Mac OpenGL test-runner 链接补充
test/gl/gl_functions.test.cppApple 平台条件: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 手工验证项
- 固定 Camera、复杂真实 Style、Particle 约 30 FPS,确认视觉与原路径一致。
- 观察
RetainedUnderlayBuild ≈ 1、RetainedUnderlayReuse和ParticleSimulationAdvance持续增长。 - 确认建 cache 后
RetainedUnderlayStaticGroupDraw不随 Particle FPS 增长,RetainedDynamicGroupDraw持续增长。 - 分别验证 only Particle、WeatherColor + Particle 的两种 layer 顺序。
- pan/zoom/resize 后确认 invalidation/rebuild,不能出现 stale underlay。
- 验证 3D、debug 与 boundary 以下 legacy ordering 会安全回到 full render。
- 对比 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 的唯一当前验收阻塞。