fix(map): align TMAP lookup and media cache invalidation

This commit is contained in:
liu weikai committed 2026-10-08 14:15:00 +08:00
1 parent 29026b5724
commit db4de44f81
4 files changed
+26 -7

No files matched your search

+2 -2
View File
@@ -49,7 +49,7 @@ RGB565 瓦片直接建立 LVGL RGB565 图像描述符,跳过 PNG 解码。RGBA
原生像素的队列和显示缓存共享 **3 MiB** 分配预算,包含引用计数头。预算不足时发布可重试事件。该预算不包含工作缓冲、目录、独立标注、其他页面及旧 PNG 解码缓存,因此不能称为整机 PSRAM 上限。大块新分配显式要求 PSRAM,不回退到内部 RAM。
离开地图且没有活动视口后,工作线程释放工作缓冲、包目录及读取工作区。显示缓存是否保留仍遵循已有硬件内存配置;保留的原生像素仍计入预算,缓存淘汰时回收。介质会话改变时重建包目录,并在 UI 地图同步时取消旧代请求、重置地图对象和显示缓存。旧会话的缺失记录不阻挡新卡读取。
离开地图且没有活动视口后,工作线程释放工作缓冲、包目录及读取工作区。显示缓存是否保留仍遵循已有硬件内存配置;保留的原生像素仍计入预算,缓存淘汰时回收。介质会话改变时重建包目录、清除旧 POI 策略,并在 UI 地图同步时取消旧代请求、重置地图对象和显示缓存。旧会话的缺失记录不阻挡新卡读取。工作线程的存在性查询和实际读取都优先访问 TMAP;生成的 POI 载荷大小尚未确定时,存在性查询返回 size=0,不用底图像素大小代替。
详见 [固件资源约束](firmware-resource-budget.md)。
@@ -96,7 +96,7 @@ tmap_source_probe <world.tmap> <china.tmap>
2026-10-08 的当前验证记录:
- `tlora_pager_sx1262` 完整 PlatformIO 构建成功,最终进程退出码 0;生成 `.pio/build/tlora_pager_sx1262/firmware.bin`。
- 构建报告静态 RAM 为 100,172 B / 327,680 B,Flash 为 4,568,221 B / 6,291,456 B。这些数值包含整份固件,不是 TMAP 增量,更不是运行时堆/PSRAM 峰值。
- 构建报告静态 RAM 为 100,172 B / 327,680 B,Flash 为 4,568,385 B / 6,291,456 B。这些数值包含整份固件,不是 TMAP 增量,更不是运行时堆/PSRAM 峰值。
- 使用现有 ESP-IDF ESP32-P4 的真实构建参数及 GCC 14 工具链,对当前地图显示文件、IDF SD 适配器、Reader、搜索和地图源五个编译单元进行交叉编译,全部退出码 0。这不等于 P4 完整固件链接或真机验证。
- LVGL 的原有 PNG 和新增原生显示两项测试、原有地图流水线九项测试通过;原生显示验证完全透明、半透明和不透明 RGBA,并确认 LVGL 解码器仍借用原生像素,而非创建完整像素副本。独立地图源实包探针追加了 CRC 损坏、容量溢出、精确/前缀/片段搜索分批、Busy 与取消验证,全部通过。
- 真机内存和任务栈验收尚待确认测试设备及刷入固件;代码已加入资源统计日志,不能将尚未采集的运行时数值当作已验证结果。
@@ -258,11 +258,17 @@ MapTileLookupResult TmapMapTileSource::lookup(const MapTileRef& ref) const
{
tmap::Tile tile{};
const auto status = select(ref, tile);
return {status == tmap::Status::Ok ? MapTileStatus::Available : status == tmap::Status::Missing ? MapTileStatus::Missing
: MapTileStatus::Error,
ref.layer == MapTileLayer::Poi ? MapTileFormat::PoiRecords : tile.codec == 1 ? MapTileFormat::Rgb565
: MapTileFormat::Rgba8888,
tile.bytes};
MapTileLookupResult info{};
info.status = status == tmap::Status::Ok ? MapTileStatus::Available : status == tmap::Status::Missing ? MapTileStatus::Missing
: MapTileStatus::Error;
if (ref.layer == MapTileLayer::Poi)
info.format = MapTileFormat::PoiRecords; // Generated record count is known only after read.
else if (status == tmap::Status::Ok)
{
info.format = tile.codec == 1 ? MapTileFormat::Rgb565 : MapTileFormat::Rgba8888;
info.size = tile.bytes;
}
return info;
}
MapTileReadResult TmapMapTileSource::read(const MapTileRef& ref, uint8_t* output, size_t capacity) const
{
@@ -744,6 +744,12 @@ class EspMapTileWorkerBackend final : public ui::map_tiles::IMapTileWorkerBacken
ui::map_tiles::MapTileLookupResult lookup(
const ui::map_tiles::MapTileRef& ref) override
{
if (media_session_ != ::platform::esp::arduino_common::storage::sd_media_session()) resetMetadata();
const auto packaged = tmap_source_.lookup(ref);
if (packaged.status != ui::map_tiles::MapTileStatus::Missing) return packaged;
#if defined(TRAIL_MATE_MAP_POI_AVAILABLE)
if (ref.layer == ui::map_tiles::MapTileLayer::Poi) return poi_source_.lookup(ref);
#endif
return source_.lookup(ref);
}
@@ -754,6 +760,7 @@ class EspMapTileWorkerBackend final : public ui::map_tiles::IMapTileWorkerBacken
{
// Always try packages before the legacy missing cache. A new media
// session invalidates the package catalog inside this source.
if (media_session_ != ::platform::esp::arduino_common::storage::sd_media_session()) resetMetadata();
auto packaged = tmap_source_.read(ref, buffer, capacity);
if (packaged.status != ui::map_tiles::MapTileReadStatus::Missing) return packaged;
#if defined(TRAIL_MATE_MAP_POI_AVAILABLE)
@@ -801,12 +808,14 @@ class EspMapTileWorkerBackend final : public ui::map_tiles::IMapTileWorkerBacken
#if defined(TRAIL_MATE_MAP_POI_AVAILABLE)
poi_source_.reset();
#endif
media_session_ = ::platform::esp::arduino_common::storage::sd_media_session();
}
private:
ui::map_tiles::IMapTileSource& source_;
platform::esp::map_tiles::SdTmapStorage tmap_storage_;
ui::map_tiles::TmapMapTileSource tmap_source_{tmap_storage_};
uint32_t media_session_ = 0;
#if defined(TRAIL_MATE_MAP_POI_AVAILABLE)
SdMapTileFileSystem poi_files_;
platform::esp::arduino_common::map_poi::CJsonPoiParser poi_parser_;
+4
View File
@@ -133,9 +133,13 @@ int main(int argc, char** argv)
assert(storage.opens == opens);
auto second = source.read(china, pixels, 256 * 1024);
assert(second.status == MapTileReadStatus::Ready && tmap::Reader::crc32c(pixels, second.size) == 0xa4e01293);
const auto located = source.lookup(china);
assert(located.status == MapTileStatus::Available && located.format == MapTileFormat::Rgb565 && located.size == 131072);
auto poi = china;
poi.layer = MapTileLayer::Poi;
auto annotations = source.read(poi, pixels, 256 * 1024);
const auto poi_info = source.lookup(poi);
assert(poi_info.status == MapTileStatus::Available && poi_info.format == MapTileFormat::PoiRecords && poi_info.size == 0);
assert(annotations.status == MapTileReadStatus::Ready && annotations.format == MapTileFormat::PoiRecords);
assert(ui::map_poi::validPayload(pixels, annotations.size));
const auto* header = reinterpret_cast<const ui::map_poi::TileHeader*>(pixels);