diff --git a/docs/60_测试/30_01_CoreRenderLayer接入最小技术验证报告_v2.md b/docs/60_测试/30_01_CoreRenderLayer接入最小技术验证报告_v2.md new file mode 100644 index 000000000..9f71fabd8 --- /dev/null +++ b/docs/60_测试/30_01_CoreRenderLayer接入最小技术验证报告_v2.md @@ -0,0 +1,110 @@ +# 30-01 Core RenderLayer 接入最小技术验证报告 v2 + +日期:2026-08-29 + +当前状态:`WAITING_MANUAL_VALIDATION` + +本版本记录用户 Android OpenGL 实机运行暴露的 DrawableBuilder 生命周期错误及其最小修复。修复后的 Android 编译和实机运行尚待用户重新执行,因此不得标记 PASS。 + +## 1. 本轮范围 + +本轮只修复 `RenderParticleValidationLayer::update()` 创建验证 Drawable 时遗漏 `DrawableBuilder::flush(context)` 的问题。 + +未实现粒子、速度场、GPU ping-pong、Trail、Land/Ocean Mask、Vulkan 或 iOS;未改变 Style 注册、RenderTree、LayerGroup、Transform 或 repaint 架构。 + +## 2. Android 实机失败事实 + +根据用户提供的 Android 实机日志结论,旧实现执行顺序为: + +```text +getCurrentDrawable(true) +→ 直接配置 custom Drawable 与 Tweaker +→ clearDrawables() +→ drawables.front() +→ LayerGroup::addDrawable() +→ RenderThread SIGSEGV +``` + +`getCurrentDrawable(true)` 只创建并保留 `currentDrawable`。`clearDrawables()` 只转移 builder 的已完成 `drawables` 容器,不负责完成当前 Drawable。旧实现因此从空容器取得 `front()`,产生未定义行为,并使空或无效 Drawable 进入 `LayerGroup::addDrawable()` 路径。 + +## 3. 仓库实现对照 + +当前 `gfx::DrawableBuilder::flush(gfx::Context&)` 在存在 `currentDrawable` 时,无论验证 Drawable 是否包含普通顶点,都会把当前 Drawable 移入已完成 `drawables` 容器。 + +仓库中的 Background、Raster、Fill、Line、Symbol、Heatmap 等 DrawableBuilder 使用方式均遵循: + +```text +配置 builder/current Drawable +→ builder->flush(context) +→ builder->clearDrawables() +→ LayerGroup::addDrawable(...) +``` + +验证 Drawable 的 custom 标志、translucent pass 与 Tweaker 直接配置在当前 Drawable 上;`flush(context)` 保留这些配置并完成所有权转移。 + +## 4. 最小修复 + +修复后的顺序为: + +```cpp +auto& drawable = builder->getCurrentDrawable(true); +drawable->setIsCustom(true); +drawable->setRenderPass(RenderPass::Translucent); +drawable->addTweaker(...); +builder->flush(context); +auto drawables = builder->clearDrawables(); +group->addDrawable(std::move(drawables.front())); +``` + +没有增加空指针判断或跳过 Drawable。验证 Drawable 仍会加入真实 source-less LayerGroup,并由 Tweaker 在 translucent render pass 内取得同帧 `PaintParameters` 和 Transform。 + +## 5. Codex 验证 + +- Linux OpenGL 精确对象编译:PASS。 + +```bash +CCACHE_DISABLE=1 cmake --build build-linux-opengl \ + --target CMakeFiles/mbgl-core.dir/src/mbgl/renderer/layers/render_particle_validation_layer.cpp.o \ + -- -j3 +``` + +- `clang-format --dry-run --Werror`:PASS。 +- `git diff --check`:PASS。 +- 首次对象编译因沙箱内 `ccache` 缓存目录只读而在编译器启动前失败;设置 `CCACHE_DISABLE=1` 后同一目标通过,不是源码编译失败。 +- Android/Gradle/ADB:未执行,遵循任务书限制。 + +## 6. 用户重新验证 + +手工编译: + +```bash +cd /mnt/sda1/MapLibreParticleLab +source /root/.maplibre-particle-env +cd platform/android +RENDERER=opengl BUILDTYPE=Debug JOBS=3 make android-x86-64 +``` + +打开 Test App:`Custom Layer` → `Particle Core Layer Validation`。 + +采集日志: + +```bash +adb logcat | grep ParticleValidation +``` + +必须重新确认: + +- 页面不再在 RenderThread 崩溃; +- validation Drawable create 后 Tweaker 真正输出 `render frame=... pass=translucent`; +- ACTIVE 帧持续增长; +- STATIC 停止验证层额外帧; +- pan、zoom、bearing、pitch、resize 的同帧 Transform 日志更新; +- 普通地图渲染和 Style order 不受影响。 + +## 7. 当前结论 + +DrawableBuilder 生命周期错误已按仓库正式 `flush(context) → clearDrawables()` 用法修复,Linux 任务对象编译通过。修复后的 Android OpenGL 实机证据尚未回填。 + +当前唯一合法结论:`WAITING_MANUAL_VALIDATION`。 + +不得进入 GPU State A/B、Trail、Mask、Vulkan 或 iOS 验证。 diff --git a/docs/报告/30_01_CoreRenderLayer接入验证_Codex完成报告_v2.md b/docs/报告/30_01_CoreRenderLayer接入验证_Codex完成报告_v2.md new file mode 100644 index 000000000..964b777ab --- /dev/null +++ b/docs/报告/30_01_CoreRenderLayer接入验证_Codex完成报告_v2.md @@ -0,0 +1,73 @@ +# 30-01 Core RenderLayer 接入验证 Codex 完成报告 v2 + +日期:2026-08-29 + +任务:根据 Android 实机日志修复 `RenderParticleValidationLayer::update()` 的 DrawableBuilder 生命周期错误 + +执行阶段:B(实机失败后的最小修复轮次) + +当前结论:`WAITING_MANUAL_VALIDATION` + +## 1. 前置读取 + +已复核 `AGENTS.md`、`PARTICLE_BASELINE.md`、`docs/00_项目总则/`、`docs/00_项目规范/`、当前 STEP-000、30-01 指令书、架构调查/设计及其完成报告、30-01 v1 技术验证/完成报告和 `粒子开发记录.md`。 + +已直接读取当前 `DrawableBuilder::getCurrentDrawable()`、`flush(context)`、`clearDrawables()`、`LayerGroup::addDrawable()` 以及 Background、Raster、Fill、CustomLayer 等现有 Drawable 使用方式。 + +## 2. Git 基线 + +- 分支:`particle/main`。 +- 本轮开始 HEAD:`98f1a85c2dafa4478866a6bae8ec6aed5cf2b29e`。 +- 开始时工作区无修改。 +- origin:`ssh://git@192.168.200.230:2222/tei/MapLibreParticleLab.git`。 +- 远端分支:`particle/main`。 +- 开始时本地与 `origin/particle/main` 同步。 +- submodule:已查询,无本轮修改。 +- 主要变更 commit:实质提交后回填。 +- commit message:`fix: finalize particle validation drawable`。 +- push:实质提交后回填。 + +## 3. 根因 + +旧代码通过 `getCurrentDrawable(true)` 创建 `currentDrawable`,直接配置 custom/pass/Tweaker 后调用 `clearDrawables()`。后者只转移 completed `drawables`,不会完成 `currentDrawable`,因此返回空容器;随后 `drawables.front()` 产生未定义行为,最终在 RenderThread 的 LayerGroup 路径触发 SIGSEGV。 + +## 4. 修复内容 + +在 `clearDrawables()` 前增加一次 `builder->flush(context)`。`flush` 把当前 Drawable 移入 completed 容器,随后其有效所有权才交给 `LayerGroup`。 + +没有添加“为空就跳过”的防御分支。验证 Drawable、Tweaker、translucent pass、同帧 Transform 和 ACTIVE/STATIC repaint 验证链全部保留。 + +## 5. 实际修改文件 + +- `src/mbgl/renderer/layers/render_particle_validation_layer.cpp` +- `docs/60_测试/30_01_CoreRenderLayer接入最小技术验证报告_v2.md` +- `docs/报告/30_01_CoreRenderLayer接入验证_Codex完成报告_v2.md` +- `粒子开发记录.md` + +未创建或修改 Step:30-01 指令书第 21 节明确要求本任务不主动修改 `docs/50_Step记录/`。 + +## 6. 构建与检查 + +- Linux OpenGL 目标对象 `render_particle_validation_layer.cpp.o`:PASS。 +- `clang-format --dry-run --Werror`:PASS。 +- `git diff --check`:PASS。 +- 首次目标对象命令受沙箱只读 `ccache` 缓存阻塞;`CCACHE_DISABLE=1` 后通过。 +- Android/Gradle/npm/ADB:未执行,遵循 30-01 指令书的用户手工 Android 验证边界。 + +## 7. 范围核对 + +- 正式粒子功能:未实现。 +- GPU ping-pong/Trail/Mask:未涉及。 +- Vulkan/iOS:未涉及。 +- RasterLayer、Renderer 主循环或平台 timer:未修改。 +- 依赖、SDK、NDK、Gradle、MapLibre baseline:未修改。 + +## 8. 未完成与阻塞 + +- 修复后的 Android OpenGL 手工编译待用户。 +- 修复后的 Android 实机运行、Tweaker render-pass 日志、Transform、ACTIVE/STATIC、pan/zoom/bearing/pitch/resize 待用户。 +- 因缺少修复后运行证据,30-01 仍不能标记 PASS,也不能进入后续 GPU/Mask/Vulkan/iOS 验证。 + +## 9. 下一步 + +用户在本次 push 后重新手工编译、安装并运行验证页面,回传 `ParticleValidation` 日志。只有全部运行条件满足后,再更新最终技术结论。 diff --git a/src/mbgl/renderer/layers/render_particle_validation_layer.cpp b/src/mbgl/renderer/layers/render_particle_validation_layer.cpp index 4ff2da96a..ac833e3a8 100644 --- a/src/mbgl/renderer/layers/render_particle_validation_layer.cpp +++ b/src/mbgl/renderer/layers/render_particle_validation_layer.cpp @@ -120,6 +120,7 @@ void RenderParticleValidationLayer::update(gfx::ShaderRegistry&, drawable->setIsCustom(true); drawable->setRenderPass(RenderPass::Translucent); drawable->addTweaker(std::make_shared(getID(), active, getLayerIndex())); + builder->flush(context); auto drawables = builder->clearDrawables(); group->addDrawable(std::move(drawables.front())); ++stats.drawablesAdded; diff --git a/粒子开发记录.md b/粒子开发记录.md index 0654fd62e..4ee492466 100644 --- a/粒子开发记录.md +++ b/粒子开发记录.md @@ -45,3 +45,12 @@ - Linux OpenGL 重新配置通过;本任务新增/直接修改的 5 个 Core 对象精确编译通过。全量增量因公共头触发 321 个对象重编译,在 41/321 无错误时主动停止,未宣称全量 PASS。 - 遵循指令书未运行 Android/Gradle/npm/ADB;等待用户手工 Android OpenGL 编译、运行、手势、resize 与日志证据。 - 当前结论为 `WAITING_MANUAL_VALIDATION`;不得进入下一项 GPU ping-pong/Trail 验证。 + +## 2026-08-29 — 30-01 Core RenderLayer 接入验证(阶段 B 修复轮次 1) + +- 用户 Android OpenGL 实机日志暴露 `RenderParticleValidationLayer::update()` 的 DrawableBuilder 生命周期错误:当前 Drawable 未完成就调用 `clearDrawables()`,RenderThread 随后触发 SIGSEGV。 +- 对照 `DrawableBuilder::flush(context)` 与仓库既有 Drawable 使用方式,在 `clearDrawables()` 前补充 `builder->flush(context)`,使 custom validation Drawable 完成后再转移给 LayerGroup。 +- 未以空指针判断跳过 Drawable;Tweaker 仍必须进入真实 translucent render pass 并读取同帧 Transform。 +- Linux OpenGL 对应目标对象编译通过;C++ 格式和 `git diff --check` 通过。 +- 未运行 Android/Gradle/npm/ADB,等待用户在新提交上重新手工编译和实机运行。 +- 当前结论仍为 `WAITING_MANUAL_VALIDATION`;未扩大到粒子、GPU ping-pong、Trail、Mask、Vulkan 或 iOS。