fix: finalize particle validation drawable
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled

This commit is contained in:
OpenAI Codex
2026-08-29 19:43:38 +08:00
parent 98f1a85c2d
commit 322be84968
4 changed files with 193 additions and 0 deletions

View File

@@ -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 验证。