Files
MapLibreParticleLab/docs/40_任务/粒子连续渲染静态底图缓存与动画快路径优化规划_v1.md
tei e70b795098
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
docs: preserve particle task history and RDC workflow rules
2026-09-23 11:57:44 +09:00

5.1 KiB
Raw Blame History

MapLibreParticleLab 粒子连续渲染静态底图缓存与动画快路径优化规划 v1

1. 目标

STEP-086 已确认:Particle / WeatherColor 的 needsRepaint 会通过全局 repaint 让完整 MapLibre scene 连续出帧。React 不会每帧重新提交 PBF,但 Native Renderer 会重复进入 source/layer orchestration,并重新提交静态 PBF/fill/line/symbol draw。

本规划目标:

  • 地图真实变化时仍走 Full Frame。
  • Camera、Style、Tile 稳定且只有 WeatherColor/Particle 动画时,复用 Static Underlay。
  • NavSea / React 不参与 Renderer cache 管理。
  • 不改变 NavSea ↔ Particle C-001 公共边界。

2. 当前关键代码

必须以当前 origin/particle/main 实际代码为准,重点包括:

  • src/mbgl/renderer/layers/render_particle_validation_layer.cpp
  • src/mbgl/renderer/layers/render_weather_color_layer.cpp
  • src/mbgl/renderer/render_orchestrator.cpp/.hpp
  • src/mbgl/renderer/renderer.cpp
  • src/mbgl/renderer/renderer_impl.cpp/.hpp
  • src/mbgl/map/map_impl.cpp
  • 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

3. 核心结构

不增加永久 public static/dynamic layer flag。采用 Renderer 内部 retained dynamic boundary:

  • WeatherColor 是 boundary candidate。
  • RasterParticle 是 boundary candidate。
  • 同时存在时取最小 layerIndex。
  • boundary 之前连续 LayerGroup 前缀作为 Static Underlay。
  • boundary 及之后继续实时绘制。
  • 没有 boundary 时完全保持原 Renderer。

Layer 顺序、parameters.currentLayer、depthRangeSize、opaque/translucent 原始 ordinal 必须保持,不允许对子集从 0 重新编号而改变透明/depth 语义。

4. Static Underlay Cache

建议 Renderer-owned helper:

  • src/mbgl/renderer/retained_underlay_cache.hpp
  • src/mbgl/renderer/retained_underlay_cache.cpp

职责:

  • offscreen renderable / texture
  • viewport size
  • boundary
  • valid/invalid
  • invalidation reason
  • build/reuse/fallback 计数
  • compositor resources

不改变 Heatmap/Hillshade RenderTarget 现有行为;复用现有 gfx::OffscreenTexture / RenderTarget / Drawable / shader abstraction。

5. Texture Composite

使用独立语义的 RetainedUnderlayCompositeShader:

  • viewport/fullscreen quad
  • sample cached RGBA texture
  • 正确 premultiplied alpha
  • 不做 map transform / color ramp / Particle 业务

不要长期复用 LocationIndicatorTexturedShader。

6. STEP-088

先只消除静态地图重复 GPU draw,仍保留:

  • Map::Impl::onUpdate
  • UpdateParameters
  • createRenderTree
  • source update / TilePyramid update
  • source/layer prepare
  • updateLayers
  • LayerGroup tweaker/upload

Render 阶段:

  1. cache invalid:boundary 前 LayerGroups render 到 offscreen。
  2. cache valid:跳过 boundary 前静态 draw。
  3. main framebuffer clear。
  4. composite cached underlay。
  5. boundary 及之后 WeatherColor/Particle/动态 overlay 正常绘制。
  6. present。

7. STEP-089

在 STEP-088 实机通过后再做 production invalidation:

  • Camera center/zoom/bearing/pitch
  • viewport/pixelRatio
  • style/layer add/remove/reorder/change
  • source/tile/bucket/drawable 变化
  • sprite/image/glyph
  • symbol placement/fade
  • context/surface recreation
  • 3D/terrain/custom/debug fallback
  • OpenGL/Metal 一致生命周期

8. STEP-090 条件步骤

只有 STEP-089 后真实 NavSea profile 仍证明主要 CPU 落在:

  • Map::Impl::onUpdate
  • createRenderTree
  • Vector/PBF source update
  • TilePyramid update
  • source/layer prepare 才进入 Animation-only fast path。

如果 STEP-089 已满足性能目标,不执行 STEP-090。

9. STEP-088 安全边界

PoC reuse 至少要求:

  • 2D
  • Camera fingerprint 连续一致
  • viewport 不变
  • style loaded
  • boundary 不变
  • context/resource 正常

以下至少 fallback full render:

  • has3D
  • Debug Overdraw
  • cache texture/compositor 创建失败
  • viewport resize
  • boundary change
  • context 不可用
  • legacy RenderItem ordering 无法证明安全
  • 其他不能证明 cache 正确的状态

原则:不确定就 full render,不用 stale cache 换性能。

10. 观测

复用 include/mbgl/particle/renderer_debug_counters.hpp,建议增加:

  • FullRendererFrame
  • RetainedUnderlayBuild
  • RetainedUnderlayReuse
  • RetainedUnderlayFallback
  • RetainedUnderlayInvalidation
  • RetainedUnderlayStaticGroupDraw
  • RetainedDynamicGroupDraw

固定 Camera + Particle 约 30 FPS 时,理想:

  • RetainedUnderlayBuild ≈ 1
  • RetainedUnderlayReuse 持续增长
  • ParticleSimulationAdvance 持续增长
  • StaticGroupDraw 建 cache 后不随 Particle FPS 增长
  • DynamicGroupDraw 持续增长

11. 不允许

  • React RAF 驱动
  • Host renderFastFrame/cacheMapNow/invalidateBasemap API
  • NavSea 手工管理 renderer cache
  • 修改 C-001
  • 永久 public static/dynamic flag
  • 改变 Style layer ordering
  • STEP-088 就跳过 source/update/prepare
  • Android/iOS 不同 renderer semantics
  • stale cache

12. 执行顺序

  1. STEP-088:PoC + observability
  2. 用户 Android/NavSea 真机验证
  3. STEP-089:production invalidation/fallback
  4. 用户再次 profile
  5. 只有 CPU orchestration 仍是瓶颈时才 STEP-090