Files
MapLibreParticleLab/docs/50_Step记录/STEP-092_ContinuousRange可退化分段RetainedCache_v2.md
tei 8a5d88008c
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
docs: close STEP-092 native validation
2026-09-24 12:18:03 +09:00

4.9 KiB
Raw Permalink Blame History

STEP-092 Continuous Range 可退化分段 Retained Cache v2

状态

CLOSED / PASS(Mac Native 验证闭环)

本版在 v1 的 Codex 实现基础上补入 RDC 独立编译、测试、修复与双后端核验结果。Android Gradle/APK/ADB/实体机与 Metal GPU frame capture 未执行,不伪造为已验证。

Git 基线

  • 分支:particle/main
  • 起始 HEAD:b29e564944197072a0effaec36ca95c48fe0649b
  • Codex implementation:a9eaec6b65cc26aa70e03002bdc1326c46cad245
  • Codex 文档:b89c8c8cb4d941abdcd704b278284e209ba7399b
  • RDC 验证修复:4908244d2(fix: close STEP-092 native validation issues)
  • 最终文档收尾提交在本文件提交后回读,以最终交付结果为准。

已实现架构

  • Style Layer 顺序是唯一 Z-order 事实来源。
  • App/RN 只提交现有 startLayerId / endLayerId 闭区间。
  • Native 基于完整 orderedLayers 解析 index;hidden endpoint 仍参与 topology。
  • startLayerId == endLayerId 为合法 single-layer Continuous。
  • 内部统一为 [continuousBegin, continuousEndExclusive)。
  • 四种结构自然退化:
    • Bottom + Continuous + Top → 3 Render Range / 2 retained caches
    • Bottom + Continuous → 2 Render Range / 1 Bottom cache
    • Continuous + Top → 2 Render Range / 1 Top cache
    • Continuous only → 1 Render Range / 0 retained cache
  • explicit valid 时不混用 legacy boundary;explicit invalid 时 fail closed,不复用 stale index/cache。
  • global layerIndex / ordinal / currentLayer / depthRangeSize 保持全 Style 语义。
  • Opaque reverse、Translucent forward 保持。
  • Particle-only Fast Path 只检查实际存在的 retained ranges。

RDC 编译与测试结果

OpenGL test-runner

第一次编译失败:

  • renderer_impl.cpp:873-874
  • 原因:循环变量被收窄为 RenderItem& 后访问不存在的 index。

第二次编译失败:

  • 改为 LayerRenderItem& 后,hasRenderPass/render 是 private override。

RDC 最终修复:

  • 用 LayerRenderItem 读取 index;
  • 通过 RenderItem& 调用公开虚接口。

第三轮:

  • cmake --build build-step088-opengl --target mbgl-test-runner -j3
  • 结果:PASS,exit code 0。

Native directed tests

命令: build-step088-opengl/mbgl-test-runner --gtest_filter='ContinuousLayerRange.*:RetainedDynamicBoundary.*:RetainedLayerGroupRange.*:RetainedUnderlayCache.*:RetainedUnderlayRevision.*:ParticleFastPath.*'

第一轮:28/29 PASS。 唯一失败:

  • RetainedUnderlayCache.RuntimeControlDisablesAndReenablesMapScopedCache
  • 原因:setEnabled(false) 已记录 aggregate invalidation,STEP-092 range cache 同步又调用 aggregate invalidate(),造成重复计数。

RDC 修复:

  • 保留 legacy aggregate invalidation 只记录一次;
  • 对实际 range cache 单独记录 Bottom/Top invalidation;
  • 不改变 runtime-disabled 语义。

第二轮:29/29 PASS。

覆盖 single/multi range、missing/reversed endpoint、hidden endpoint、reorder/delete、四种 topology、0/1/2 cache decision、explicit/legacy 排他、Fast Path、revision 与 runtime control。

Metal / iOS

  • build-ios/CMakeCache.txt:MLN_WITH_METAL=ON、MLN_WITH_OPENGL=OFF。
  • Xcode target 编译定义包含 MLN_RENDER_BACKEND_METAL=1。
  • cmake --build build-ios --target ios-sdk-static -- -quiet
  • 结果:PASS,exit code 0。
  • 警告仅包括既有 EAGL deprecated、bundle identifier 等,不构成 STEP-092 编译失败。

GPU resource / composite 核验

RDC 对实际源码路径独立核验:

  • Bottom/Top holder 可常驻,但 GPU texture/render target/compositor 只在 prepareResources() 被调用时 lazy 创建。
  • prepareResources() 只在对应 cache decision 为 Build/Reuse 时调用;不存在的 Range 为 Disabled,不调用资源准备。
  • 同 viewport 且已有 offscreenTexture 时不重建 texture;已有 compositeLayerGroup 时不重建 compositor。
  • retained target clear color 为透明 (0,0,0,0)。
  • composite 使用 gfx::ColorMode::alphaBlended(),其因子为 One / OneMinusSrcAlpha,对应 premultiplied-alpha。
  • OpenGL 与 Metal RetainedUnderlayCompositeShader 均直接采样 RGBA texture。
  • Final 顺序为 Bottom composite → Continuous → Top composite。
  • 29 项 directed tests 已验证 0/1/2 cache decision 与 stable reuse/invalidation 语义。

未执行项

  • Android Gradle / AAR / APK / ADB / 安装 / 实体机视觉:未执行。
  • Metal GPU frame capture、iOS 实机 runtime resource counter:未执行;当前仓库无现成可直接运行的 STEP-092 Metal GPU runtime test target。
  • 未执行 Jest。

结论

STEP-092 的 Mac Native 实现、OpenGL 编译、Native directed tests、Metal-only iOS 编译、资源生命周期代码路径、透明 Top composite 与 Git 修复闭环均已通过。未执行的平台实体机/Frame Capture 项保留为后续产品级验证,不改变本 Step 的 Mac Native CLOSED / PASS 结论。