From 016fd1fff6a33cf795c10d4f5c5413d308383677 Mon Sep 17 00:00:00 2001 From: tei Date: Fri, 25 Sep 2026 13:55:19 +0900 Subject: [PATCH] feat: add generic render segment model --- CMakeLists.txt | 3 + bazel/core.bzl | 3 + include/mbgl/map/map.hpp | 3 + include/mbgl/renderer/render_segment.hpp | 112 ++++++ .../MapLibreParticleRNTestHost/App.tsx | 30 ++ .../weather/WeatherRuntimeBridgeModule.kt | 6 + .../ios/WeatherRuntimeBridge.mm | 10 + .../src/NativeWeatherRuntimeBridge.ts | 2 + .../src/RendererRuntime.ts | 7 +- packages/maplibre-particle-rn/src/index.ts | 7 + packages/maplibre-particle-rn/src/types.ts | 75 ++++ .../src/cpp/native_map_view.cpp | 16 + .../src/cpp/native_map_view.hpp | 4 + .../maplibre/android/maps/MapLibreMap.java | 11 + .../org/maplibre/android/maps/NativeMap.java | 4 + .../maplibre/android/maps/NativeMapView.java | 19 + platform/ios/src/MLNMapView.h | 6 + platform/ios/src/MLNMapView.mm | 17 + src/mbgl/map/map.cpp | 10 + src/mbgl/renderer/render_orchestrator.cpp | 49 ++- src/mbgl/renderer/render_orchestrator.hpp | 4 + src/mbgl/renderer/render_segment_json.hpp | 135 +++++++ src/mbgl/renderer/render_segment_plan.hpp | 172 +++++++++ src/mbgl/renderer/renderer_impl.cpp | 354 ++++++++++-------- src/mbgl/renderer/renderer_impl.hpp | 9 +- src/mbgl/renderer/retained_underlay_cache.cpp | 52 ++- src/mbgl/renderer/retained_underlay_cache.hpp | 3 + .../retained_underlay_runtime_state.hpp | 165 ++++++++ .../renderer/retained_underlay_cache.test.cpp | 283 ++++++++++++++ 29 files changed, 1409 insertions(+), 162 deletions(-) create mode 100644 include/mbgl/renderer/render_segment.hpp create mode 100644 src/mbgl/renderer/render_segment_json.hpp create mode 100644 src/mbgl/renderer/render_segment_plan.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c115a6ad1..278912ad0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -184,6 +184,8 @@ list(APPEND SRC_FILES ${PROJECT_SOURCE_DIR}/src/mbgl/renderer/retained_underlay_cache.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/renderer/retained_underlay_cache.hpp ${PROJECT_SOURCE_DIR}/src/mbgl/renderer/retained_underlay_runtime_state.hpp + ${PROJECT_SOURCE_DIR}/src/mbgl/renderer/render_segment_plan.hpp + ${PROJECT_SOURCE_DIR}/src/mbgl/renderer/render_segment_json.hpp ${PROJECT_SOURCE_DIR}/src/mbgl/renderer/change_request.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layer_group.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/renderer/tile_layer_group.cpp @@ -310,6 +312,7 @@ list(APPEND INCLUDE_FILES ${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer_state.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/renderer/retained_underlay.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/renderer/render_segment.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/program_parameters.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/shader_source.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/storage/database_file_source.hpp diff --git a/bazel/core.bzl b/bazel/core.bzl index 421edebe5..49db81b1f 100644 --- a/bazel/core.bzl +++ b/bazel/core.bzl @@ -293,6 +293,8 @@ MLN_CORE_SOURCE = [ "src/mbgl/renderer/render_orchestrator.cpp", "src/mbgl/renderer/render_orchestrator.hpp", "src/mbgl/renderer/continuous_layer_range.hpp", + "src/mbgl/renderer/render_segment_plan.hpp", + "src/mbgl/renderer/render_segment_json.hpp", "src/mbgl/renderer/render_pass.hpp", "src/mbgl/renderer/render_source.cpp", "src/mbgl/renderer/render_source.hpp", @@ -752,6 +754,7 @@ MLN_CORE_HEADERS = [ "include/mbgl/renderer/renderer_observer.hpp", "include/mbgl/renderer/renderer_state.hpp", "include/mbgl/renderer/retained_underlay.hpp", + "include/mbgl/renderer/render_segment.hpp", "include/mbgl/shaders/program_parameters.hpp", "include/mbgl/storage/database_file_source.hpp", "include/mbgl/storage/file_source.hpp", diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index 20c106f53..93a321e98 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -59,6 +60,8 @@ public: /** Enables or disables the map-scoped retained static underlay optimization. */ void setRetainedUnderlayEnabled(bool); bool setContinuousLayerRange(std::string startLayerId, std::string endLayerId); + bool setRenderSegmentPlan(RenderSegmentPlan); + RenderSegmentDiagnostics getRenderSegmentDiagnostics() const; bool isRetainedUnderlayEnabled() const; RetainedUnderlayDiagnostics getRetainedUnderlayDiagnostics() const; diff --git a/include/mbgl/renderer/render_segment.hpp b/include/mbgl/renderer/render_segment.hpp new file mode 100644 index 000000000..329a3855d --- /dev/null +++ b/include/mbgl/renderer/render_segment.hpp @@ -0,0 +1,112 @@ +#pragma once + +#include +#include +#include +#include + +namespace mbgl { + +enum class RenderSegmentStrategy : uint8_t { Retained, Continuous }; + +inline const char* renderSegmentStrategyText(RenderSegmentStrategy strategy) noexcept { + return strategy == RenderSegmentStrategy::Retained ? "RETAINED" : "CONTINUOUS"; +} + +struct RenderSegmentDefinition { + RenderSegmentStrategy strategy = RenderSegmentStrategy::Continuous; + std::optional startLayerId; + + bool operator==(const RenderSegmentDefinition&) const = default; +}; + +struct RenderSegmentPlan { + uint32_t schemaVersion = 1; + std::vector segments; + + bool operator==(const RenderSegmentPlan&) const = default; +}; + +struct StyleLayerDiagnostics { + int32_t layerIndex = -1; + std::string layerId; + std::string layerType; + bool visible = false; + std::optional sourceId; + std::optional sourceLayer; + + bool operator==(const StyleLayerDiagnostics&) const = default; +}; + +struct RenderSegmentCacheDiagnostics { + std::string cacheState{"disabled"}; + uint64_t contentRevision = 0; + uint64_t build = 0; + uint64_t reuse = 0; + uint64_t invalidation = 0; + std::string lastInvalidationReason{"none"}; + uint64_t textureCreate = 0; + uint64_t compositeCreate = 0; + uint64_t resourceRelease = 0; +}; + +struct RenderSegmentDiagnosticsEntry { + uint32_t segmentIndex = 0; + RenderSegmentStrategy strategy = RenderSegmentStrategy::Continuous; + std::optional configuredStartLayerId; + int32_t beginIndex = -1; + int32_t endExclusive = -1; + std::optional resolvedStartLayerId; + std::optional resolvedEndLayerId; + std::vector layers; + std::optional cache; +}; + +struct RenderSegmentDiagnostics { + uint32_t schemaVersion = 1; + bool enabled = true; + bool configured = false; + bool valid = false; + std::string configSource{"unconfigured/legacy"}; + uint64_t configRevision = 0; + uint64_t topologyRevision = 0; + uint32_t styleLayerCount = 0; + uint32_t segmentCount = 0; + uint32_t retainedSegmentCount = 0; + uint32_t continuousSegmentCount = 0; + bool coverageComplete = false; + bool fallback = false; + std::string lastReason{"not-configured"}; + bool fastPathEligible = false; + bool fastPathActive = false; + std::string fastPathFallbackReason{"no-prepared-tree"}; + uint64_t fastPathHit = 0; + uint64_t fastPathMiss = 0; + uint64_t fullCpuFrame = 0; + std::vector styleLayers; + std::vector segments; +}; + +struct ResolvedRenderSegment { + uint32_t segmentIndex = 0; + RenderSegmentStrategy strategy = RenderSegmentStrategy::Continuous; + std::optional configuredStartLayerId; + int32_t beginIndex = 0; + int32_t endExclusive = 0; + + bool operator==(const ResolvedRenderSegment&) const = default; +}; + +struct ResolvedRenderSegmentPlan { + bool configured = false; + bool valid = false; + std::string configSource{"unconfigured/legacy"}; + uint64_t configRevision = 0; + std::string reason{"not-configured"}; + int32_t layerCount = 0; + std::vector segments; + + bool operator==(const ResolvedRenderSegmentPlan&) const = default; +}; + +} // namespace mbgl diff --git a/integration/react-native/MapLibreParticleRNTestHost/App.tsx b/integration/react-native/MapLibreParticleRNTestHost/App.tsx index f56283df3..5d4890488 100644 --- a/integration/react-native/MapLibreParticleRNTestHost/App.tsx +++ b/integration/react-native/MapLibreParticleRNTestHost/App.tsx @@ -14,6 +14,7 @@ import { FieldRuntime, RendererRuntime, type RetainedUnderlayDiagnostics, + type RenderSegmentDiagnostics, type RuntimeSnapshot, } from "@navsea/maplibre-particle-rn"; import { @@ -67,6 +68,8 @@ export default function App() { const [snapshot, setSnapshot] = useState(initialSnapshot); const [retainedSnapshot, setRetainedSnapshot] = useState(null); + const [segmentSnapshot, setSegmentSnapshot] = + useState(null); const [mapStatus, setMapStatus] = useState("LOADING"); const [weatherStatus, setWeatherStatus] = useState("WAITING"); const [result, setResult] = useState("Waiting for map/style"); @@ -91,6 +94,11 @@ export default function App() { const refreshRetained = useCallback(async (tag: number) => { setRetainedSnapshot(await RendererRuntime.getRetainedUnderlayDiagnostics(tag)); }, []); + const refreshSegments = useCallback(async (tag: number) => { + const value = await RendererRuntime.getRenderSegmentDiagnostics(tag); + setSegmentSnapshot(value); + setResult(JSON.stringify(value, null, 2)); + }, []); const applyVisualToTag = useCallback(async (tag: number) => { const results = await Promise.all([ FieldRuntime.setParticleCount(tag, Number(visual.count)), @@ -384,6 +392,28 @@ export default function App() { onPress={() => reactTag != null && void refreshRetained(reactTag)} /> + + Segments: {segmentSnapshot == null ? "not read" : + `${segmentSnapshot.valid ? "VALID" : "INVALID"} source=${segmentSnapshot.configSource} count=${segmentSnapshot.segmentCount} topology=${segmentSnapshot.topologyRevision}`} + + +