From 3ae7e24498eca85f4cfed20bcc75b19b98306018 Mon Sep 17 00:00:00 2001 From: OpenAI Codex Date: Tue, 1 Sep 2026 12:31:13 +0800 Subject: [PATCH] fix: provide raster array source render item --- ...040_Android离线Fixture正式粒子最小闭环_v1.md | 4 +-- ..._Android粒子最小正式闭环_Codex完成报告_v1.md | 7 +++++ .../sources/render_raster_array_source.hpp | 30 +++++++++++++++++-- test/style/source.test.cpp | 30 +++++++++++++++++++ 粒子开发记录.md | 7 +++++ 5 files changed, 74 insertions(+), 4 deletions(-) diff --git a/docs/50_Step记录/STEP-040_Android离线Fixture正式粒子最小闭环_v1.md b/docs/50_Step记录/STEP-040_Android离线Fixture正式粒子最小闭环_v1.md index 6ec2aa4d9..a11d3c541 100644 --- a/docs/50_Step记录/STEP-040_Android离线Fixture正式粒子最小闭环_v1.md +++ b/docs/50_Step记录/STEP-040_Android离线Fixture正式粒子最小闭环_v1.md @@ -30,10 +30,10 @@ ## 构建与检查 -- Linux OpenGL 受影响 Core 精确对象编译:PASS(`offline_download.cpp.o`,`-Werror`)。 +- Linux OpenGL 受影响 `render_source.cpp.o` 与新增 `source.test.cpp.o` 精确编译:PASS(`-Werror`);`RasterArrayRenderItem` 单测已编译入测试目标,未在本轮执行完整测试二进制。 - `clang-format --dry-run --Werror`、`git diff --check`:PASS;fixture generator 不受本次枚举接入影响,未重跑。 - adapter smoke:`uniform-east`、`uniform-north`、`vortex` 均 valid;`nodata` valid 且有 1 个 invalid cell。 ## 当前结果、阻塞与下一步 -正式 Source/Layer/RenderLayer 已不依赖 source-less `particle-validation` Layer;历史 validation Layer 只保留为既有验证工具。`RasterArraySource` 的当前 contract 为平台 FileSource 读取确定性 fixture bytes(40-01 Android 为 APK `asset://`),不含 tileset 或由 OfflineDownload 管理的 URL/resource;故 OfflineDownload 的资源计数与下载队列均明确 no-op。Linux 精确编译、format、diff 与全仓 SourceType switch 复核已通过;提交与推送待本轮收尾。Android OpenGL APK 手工验收仍由用户执行。 +正式 Source/Layer/RenderLayer 已不依赖 source-less `particle-validation` Layer;历史 validation Layer 只保留为既有验证工具。Android 首次实际启动发现 RasterArray fixture loaded 后的 RenderThread SIGSEGV:当前 `RenderRasterArraySource` 在 enabled 时返回空 RenderItem,而 RenderTree 无条件解引用 source item。已确认应保持全局 RenderSource 契约,并在 RasterArray source 内补合法 no-op RenderItem。Linux 精确编译、format、diff 与 RenderSource RenderItem-return audit 已通过;提交与推送待本轮收尾。Android OpenGL APK 手工验收仍由用户执行。 diff --git a/docs/报告/40_01_Android粒子最小正式闭环_Codex完成报告_v1.md b/docs/报告/40_01_Android粒子最小正式闭环_Codex完成报告_v1.md index 152957a36..763811bf2 100644 --- a/docs/报告/40_01_Android粒子最小正式闭环_Codex完成报告_v1.md +++ b/docs/报告/40_01_Android粒子最小正式闭环_Codex完成报告_v1.md @@ -42,6 +42,13 @@ Stage A 代码与静态检查完成,任务状态为 `WAITING_MANUAL_VALIDATION - 未添加 `default:`;全仓非 vendor 的 `SourceType` switch 复核后,除本文件两个遗漏外均已处理 `RasterArray`。 - Linux/Core 精确编译 `offline_download.cpp.o`(含 `-Werror`)、`clang-format --dry-run --Werror` 与 `git diff --check`:PASS。commit 和 push 结果在本轮交付中报告;状态继续为 `WAITING_MANUAL_VALIDATION`,未运行 Gradle 或 ADB。 +## 4.2 RasterArray Source RenderItem 空指针修复 + +- Android OpenGL 首次启动日志确认 fixture 已成功从 APK asset 加载、粒子 layer 已 evaluate,随后 `Renderer::Impl::render()` 在 State A/B 创建前发生 fault addr `0x0` 的 SIGSEGV。 +- 根因是 loaded + needsRendering 使 `RenderRasterArraySource` enabled,但其 `createRenderItem()` 返回空指针;RenderOrchestrator 将该值放入 source item vector,RenderTree 随后无条件解引用。该全局契约不作容错放宽。 +- 修复在 RasterArray source 内按 ImageSource 生命周期准备并移交合法 no-op RenderItem:无 upload、无 render pass、无 particle draw。正式 GPU particle 绘制仍只属于 `RenderRasterParticleLayer`。 +- Linux/Core `render_source.cpp.o` 和含新增 `RasterArrayRenderItem` 的 `source.test.cpp.o` 均以 `-Werror` 精确编译;`clang-format --dry-run --Werror`、`git diff --check` 与全部 RenderSource `createRenderItem()` return audit 均通过。未运行完整 Linux 测试二进制、Android Gradle、ADB 或真机测试,状态仍为 `WAITING_MANUAL_VALIDATION`。 + ## 5. 已知问题与未完成事项 - Android OpenGL 的 T1-T12 仍待用户执行,T1 rotation 无按钮恢复是硬门槛。 diff --git a/src/mbgl/renderer/sources/render_raster_array_source.hpp b/src/mbgl/renderer/sources/render_raster_array_source.hpp index 409d005c9..67786c9c2 100644 --- a/src/mbgl/renderer/sources/render_raster_array_source.hpp +++ b/src/mbgl/renderer/sources/render_raster_array_source.hpp @@ -1,10 +1,27 @@ #pragma once #include +#include #include #include namespace mbgl { + +class RasterArraySourceRenderData final : public RenderItem { +public: + explicit RasterArraySourceRenderData(std::string name_) + : name(std::move(name_)) {} + +private: + void upload(gfx::UploadPass&) const override {} + void render(PaintParameters&) const override {} + bool hasRenderPass(RenderPass) const override { return false; } + const std::string& getName() const override { return name; } + void updateDebugDrawables(DebugLayerGroupMap&, PaintParameters&) const override {} + + std::string name; +}; + class RenderRasterArraySource final : public RenderSource { public: explicit RenderRasterArraySource(Immutable impl) @@ -18,8 +35,14 @@ public: baseImpl = std::move(value); enabled = needsRendering && isLoaded(); } - std::unique_ptr createRenderItem() override { return {}; } - void prepare(const SourcePrepareParameters&) override {} + std::unique_ptr createRenderItem() override { + assert(renderData); + return std::move(renderData); + } + void prepare(const SourcePrepareParameters&) override { + assert(!renderData); + renderData = std::make_unique(baseImpl->id); + } void updateFadingTiles() override {} bool hasFadingTiles() const override { return false; } std::unordered_map> queryRenderedFeatures( @@ -36,5 +59,8 @@ public: const style::RasterArraySource::Impl& impl() const { return static_cast(*baseImpl); } + +private: + std::unique_ptr renderData; }; } // namespace mbgl diff --git a/test/style/source.test.cpp b/test/style/source.test.cpp index b4019193a..2ce0ffdd0 100644 --- a/test/style/source.test.cpp +++ b/test/style/source.test.cpp @@ -16,12 +16,15 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #include #include #include @@ -126,6 +129,33 @@ TEST(Source, LoadingFail) { test.run(); } +TEST(Source, RasterArrayRenderItem) { + SourceTest test; + + style::RasterArraySource source{"source", "fixture", "metadata", "field"}; + particle::ParticleFieldSnapshot field; + auto impl = Immutable( + makeMutable(source.impl(), std::move(field))); + RenderRasterArraySource renderSource{impl}; + + renderSource.update(impl, {}, true, false, test.tileParameters()); + EXPECT_TRUE(renderSource.isLoaded()); + EXPECT_TRUE(renderSource.isEnabled()); + + TransformParameters transformParameters{test.transformState}; + const MapDebugOptions debugOptions = MapDebugOptions::NoDebug; + renderSource.prepare({.transform = transformParameters, + .debugOptions = debugOptions, + .imageManager = *test.imageManager, + .sourceName = source.getID()}); + + auto item = renderSource.createRenderItem(); + ASSERT_TRUE(item); + EXPECT_EQ(item->getName(), "source"); + EXPECT_FALSE(item->hasRenderPass(RenderPass::Opaque)); + EXPECT_FALSE(item->hasRenderPass(RenderPass::Translucent)); +} + TEST(Source, LoadingCorrupt) { SourceTest test; diff --git a/粒子开发记录.md b/粒子开发记录.md index 31787b179..e8b215a98 100644 --- a/粒子开发记录.md +++ b/粒子开发记录.md @@ -172,3 +172,10 @@ - Android OpenGL 实际 C++ 编译暴露 `OfflineDownload` 的 required-resource-count 与 resource-queue 两处 `SourceType` 穷尽 switch 漏掉 `RasterArray`。 - 根据当前实现,`RasterArraySource` 只从平台 `FileSource` 获取确定性 fixture metadata/field bytes;40-01 Android 输入固定为 APK `asset://integration/particle-fixtures/...`,且 Source Impl 不包含 tileset、zoom range 或 OfflineDownload 托管资源 contract。因此两处都以显式 `SourceType::RasterArray` no-op 表达语义,不虚报资源数、不进入下载队列。 - 不增加 `default:`;全仓非 vendor 的 `SourceType` switch 已复核,本次仅修复新增枚举的直接遗漏。Linux/Core `offline_download.cpp.o` 精确编译(`-Werror`)、`clang-format --dry-run --Werror` 与 `git diff --check` 均通过;未运行 Gradle 或 ADB,40-01 继续为 `WAITING_MANUAL_VALIDATION`。 + +## 2026-09-01 — 40-01 RasterArray Source RenderItem 空指针修复 + +- Android OpenGL 首次实机启动确认 field fixture 已加载、RasterParticleLayer 已 evaluate 后,RenderThread 在 State A/B 创建前因 `Renderer::Impl::render()` fault addr `0x0` 崩溃。 +- 调用链确认:loaded + needsRendering 使 `RenderRasterArraySource` enabled;RenderOrchestrator 要求 enabled source 返回合法 RenderItem;RenderTree 无条件解引用。原 `createRenderItem()` 返回空指针违反该既有契约。 +- RasterArray source 改为按 ImageSource 的 prepare/create 生命周期提供 no-op RenderItem(无 upload、无 render pass、无 debug drawable、无 particle draw);不改全局 RenderOrchestrator,不增加第二套粒子 renderer,粒子 GPU 路径仍由 `RenderRasterParticleLayer` 负责。 +- Linux/Core `render_source.cpp.o` 与新增 source test object 均以 `-Werror` 精确编译;format、diff 与全部 RenderSource `createRenderItem()` return audit 通过。未运行完整 Linux 测试二进制、Android Gradle、ADB 或真机测试,40-01 继续为 `WAITING_MANUAL_VALIDATION`。