docs: close STEP-092 native validation
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled

This commit is contained in:
tei
2026-09-24 12:18:03 +09:00
parent 4908244d2d
commit 8a5d88008c
3 changed files with 273 additions and 0 deletions

View File

@@ -0,0 +1,99 @@
# 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 结论。

View File

@@ -0,0 +1,165 @@
# STEP-092 Continuous Range 可退化分段 Retained Cache Codex 完成报告 v2
## 1. 执行结论
**PASS:Codex 实现 + RDC 独立 Mac Native 验证闭环完成。**
本报告是在 v1 PARTIAL 基础上的验证收尾版。RDC 已完成 OpenGL test-runner 编译、定向 Native tests、Metal-only iOS 静态 SDK 编译,并修复两处真实验证问题后重新通过。Android Gradle/APK/ADB/实体机与 Metal GPU frame capture 未执行,均明确保留为未执行项。
## 2. Git 基线与提交
- 仓库:`/Users/tei/dev/MapLibreParticleLab`
- branch:`particle/main`
- Starting HEAD:`b29e564944197072a0effaec36ca95c48fe0649b`
- Codex implementation:`a9eaec6b65cc26aa70e03002bdc1326c46cad245`
- Codex v1 docs:`b89c8c8cb4d941abdcd704b278284e209ba7399b`
- RDC validation fix:`4908244d2`,message:`fix: close STEP-092 native validation issues`
- 文档收尾提交在本报告写入后产生,最终 HEAD / remote HEAD 由收尾回读确认。
## 3. Codex 实现范围
C++ Renderer:
- explicit Continuous Range config / resolution
- 0/1/2 retained range cache
- Bottom / Continuous / Top render slicing
- Fast Path gate
- diagnostics 与 invalidation
跨端 API:
- C++ Map API
- Android Java/JNI
- iOS ObjC++
- RN TypeScript / Android / iOS bridge
核心语义:
- `[startLayerId,endLayerId]` 为闭区间。
- single-layer Continuous 合法。
- hidden endpoint 仍决定 topology。
- Style Layer 顺序是唯一 Z-order。
- explicit valid 与 legacy boundary 排他。
- explicit invalid fail closed。
- Opaque reverse / Translucent forward 与 global ordinal 保持。
## 4. RDC 第一次 OpenGL 编译
命令:
`cmake --build build-step088-opengl --target mbgl-test-runner -j3`
结果:FAIL。
首个真实错误:
- `renderer_impl.cpp:873-874`
- `RenderItem` 无 `index` 成员。
原因:
- `layerRenderItems` 实际类型是 `std::set<LayerRenderItem>`;
- 代码把当前元素绑定为 `const RenderItem&` 后又读取派生类 `index`。
## 5. RDC 第二次 OpenGL 编译
第一次局部修复改为 `LayerRenderItem&` 后继续编译,新的真实错误为:
- `LayerRenderItem::hasRenderPass` private
- `LayerRenderItem::render` private
最终修复:
- `LayerRenderItem& layerItem` 专门读取 `index`;
- 再绑定 `const RenderItem& item = layerItem` 调用公开虚接口。
第三轮 OpenGL build:
- exit code:0
- target:`mbgl-test-runner`
- 结果:PASS。
## 6. Native directed tests
过滤器:
`ContinuousLayerRange.*:RetainedDynamicBoundary.*:RetainedLayerGroupRange.*:RetainedUnderlayCache.*:RetainedUnderlayRevision.*:ParticleFastPath.*`
第一轮:
- 29 tests / 6 suites
- PASS 28
- FAIL 1
唯一失败:
`RetainedUnderlayCache.RuntimeControlDisablesAndReenablesMapScopedCache`
实际值:
- disabled.invalidation = 3
- expected = 2
根因:
- baseline 中 `setEnabled(false)` 已记录一次 aggregate `runtime-disabled` invalidation;
- STEP-092 新增 range cache 同步路径再次调用 aggregate `invalidate()`;
- 因而同一 disable 事件被重复计入 aggregate diagnostics。
RDC 修复:
- disable 时不再重复调用 aggregate `recordInvalidation`;
- 保持 legacy aggregate 计数语义;
- 仍为实际 Bottom/Top cache 记录独立 `recordRangeInvalidation`。
第二轮:
- 29/29 PASS
- exit code:0
- 全部 6 suites PASS。
## 7. Metal / iOS 验证
后端真实性:
- `MLN_WITH_METAL=ON`
- `MLN_WITH_OPENGL=OFF`
- Xcode project 定义 `MLN_RENDER_BACKEND_METAL=1`
命令:
`cmake --build build-ios --target ios-sdk-static -- -quiet`
结果:
- exit code:0
- PASS
- 仅有既有 EAGL deprecated、bundle identifier / script phase warning。
因此本轮不是“iOS target 名称推断”,而是实际 Metal-only 配置下完成原生编译与链接。
## 8. GPU resource lifecycle / composite 核验
RDC 审计的实际代码路径:
- RendererImpl 常驻 Bottom/Top cache holder,但 GPU 资源不在构造时创建。
- `prepareResources()` 只在对应 decision 为 Build/Reuse 时进入。
- Range 不存在时 key/decision 为 Disabled,不执行 `prepareResources()`。
- `createOffscreenTexture(..., UnsignedByte, true, true)` 仅在 texture 不存在或 viewport 变化时执行。
- 同 viewport 复用已有 texture。
- `compositeLayerGroup` 存在时不重建 compositor。
- build render target clear color:透明 `0,0,0,0`。
- composite:`gfx::ColorMode::alphaBlended()`。
- `alphaBlended()` 使用 `src=One`、`dst=OneMinusSrcAlpha`,符合 premultiplied-alpha。
- OpenGL 与 Metal Composite Shader 均直接采样 retained RGBA texture。
- Renderer final 顺序:Bottom composite → Continuous render → Top composite。
- Native test 已验证四种 topology、0/1/2 cache decision、reuse/invalidation 与 absent cache fast gate。
这些结果共同证明当前源码中不存在固定分配两个 retained GPU target,也不存在 stable frame 每帧重建同尺寸 texture/compositor 的路径。
## 9. RDC 实际修改
1. `src/mbgl/renderer/renderer_impl.cpp`
- 修复 legacy `LayerRenderItem` index 访问与基类虚接口调用。
2. `src/mbgl/renderer/retained_underlay_cache.cpp`
- 修复 runtime disable aggregate invalidation 重复计数;
- 保留 Bottom/Top range invalidation diagnostics。
RDC 修复提交:
- `4908244d2`
- `fix: close STEP-092 native validation issues`
- push:SUCCESS。
## 10. 未执行项目
- Android Gradle / AAR / APK:未执行。
- ADB / 安装 / Android 实体机视觉:未执行。
- iOS 实机 GPU runtime:未执行。
- Metal frame capture / GPU resource counter:未执行。
- Jest:未新增、未执行。
当前仓库未提供一个可直接运行的 STEP-092 Metal GPU runtime test target,因此未将 Metal compile PASS 描述成 frame-capture PASS。
## 11. 最终验收判断
STEP-092 的规定架构、四种 Range、0/1/2 retained cache、global layerIndex、Opaque/Translucent、Fast Path、diagnostics、RN/Android/iOS API、Native directed tests、OpenGL Native build、Metal-only iOS build、资源生命周期路径、文档和 Git 闭环均已完成。
结论:**CLOSED / PASS(Mac Native 范围)**。