Files
MapLibreParticleLab/docs/30_设计/STEP-085_V4_Renderer性能修复设计_v1.md
tei 70f112ea27
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
fix: close STEP-085 V4 renderer efficiency
2026-09-19 22:16:36 +09:00

3.9 KiB
Raw Permalink Blame History

STEP-085 V4 Renderer 性能修复设计 v1

状态:IMPLEMENTED / WAITING_FOR_RDC_NATIVE_BUILD

目标与根因

V4 的 RasterArraySource 通过独立的 field-keyed window 产出已经 materialize 的 T0/T1/MIX。旧 renderer 将 V4 误当作“没有 timeline”,从而产生两项错误:WeatherColor 的 needsRepaint() 永远为 true;Particle 也永远请求下一帧,并在 prepare() 将包含大 vector/scalar/valid 数组的 snapshot 按值复制。

本设计保持 V3 timeline、V4 Runtime Field Window、QBIN 和所有 RN/Host 公共接口不变,只在 Source 内部和共用 renderer seam 修复 cadence/lifetime。

共用 cadence 语义

新增 Source-owned RasterArrayRendererCadence。它只负责 visual simulation 的 deadline,不携带 field、不会变更 T0/T1/MIX,也不会调用 ForecastClock。

targetFps Core cadence platform wake
AUTO 每个 MapLibre animation frame 可消费一次 沿用平台 animation-frame 语义
30 约 33.3ms 才允许一次 simulation Android Handler / iOS NSTimer 约 34ms 请求一次 repaint
60 约 16.7ms 才允许一次 simulation Android Handler / iOS NSTimer 约 17ms 请求一次 repaint

RenderRasterParticleLayer::needsRepaint() 仅对 active、visible、field-ready 的 V4 Particle 在 deadline 到期时返回 true。因 camera 而来的额外 frame 仍可 composite 当前 trail,但 consumeIfDue() 未成功时不建 State/Trail pass、不推进 ping-pong、不衰减 trail。Forecast PAUSE 不影响该 visual cadence。

Android/iOS runtime timer 仅是已有 facade 的“下一帧 wake”薄层;deadline 与是否推进由共用 C++ Source cadence 判定。hidden、clear、disable 和 dispose 都停止 V4 Particle wake。

WeatherColor idle 与 drawable

V4 WeatherColor 在 PAUSE、field/window/stops/opacity/transform 不变时 needsRepaint()==false。它不再以 sourceTimeline == nullptr 作为“永远动画”的代理。

稳定状态下 WeatherColor drawable 复用既有 LayerGroup drawable。T0/T1 texture、mix、opacity、color stops 与 value source 由 Resources/Tweaker 在 render 时更新 UBO;仅 wrap 集合变化才 clearDrawables() 后重建。该方案保留 gfx abstraction,未引入 OpenGL/Metal 直接调用。

V4 snapshot lifetime

materialize 仍发生在 Source 的 binding/window 真正变化时,但 Materialized*Projection 与 renderer sourceField/sourceNextField 全部改为 shared_ptr<const ParticleFieldSnapshot>。Source Impl 的不可变副本持有 projection,RenderLayer 只复制 shared handle;稳定 window 的 prepare() 不再深复制 scalar/vector/valid arrays。旧 V3 optional snapshot 路径仍在 Source 变化时构造独立 handle,未改变其 API。

Debug/Validation observability

include/mbgl/particle/renderer_debug_counters.hpp 在非 release 建立低成本 relaxed atomic 累计器,release 编译为 no-op。覆盖:两 layer 的 needsRepaint/update、particle simulation advance、WeatherColor/Particle drawable rebuild、field texture upload、GPU resource create/release-reset、trail create/resize、V4 projection materialize 与 field-window revision。它不逐帧写普通日志,也不暴露给 NavSea。

ForecastClock 审查

全仓确认 RasterArraySource::advanceForecastClock(elapsedMs) 只有定义,当前 Android WeatherRuntime、iOS MLNParticleFieldRuntime 与 RN bridge 均没有 production caller。故 V4 PLAY 自动推进尚无 owner;本 Step 不将 cadence timer 偷接成第二个 forecast clock。Host 显式 setEncodedForecastTime 继续触发 window refresh;自动 forecast playback 应单独设计 owner 后处理。

生命周期边界

本 Step 不改变 detach()、dispose、Host clear/destroy contract,也不对 retained allocation/Native Heap 归因。计数器和减少 repaint/copy/rebuild 仅为后续 RDC 采样提供证据。