#include #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { Renderer::Renderer(gfx::RendererBackend& backend, float pixelRatio_, const std::optional& localFontFamily_) : impl(std::make_unique(backend, pixelRatio_, localFontFamily_)) {} Renderer::~Renderer() { gfx::BackendScope guard{impl->backend}; impl.reset(); } void Renderer::markContextLost() { impl->clearPreparedRenderTree(); impl->orchestrator.markContextLost(); } void Renderer::setObserver(RendererObserver* observer) { impl->setObserver(observer); impl->orchestrator.setObserver(observer); } void Renderer::render(const std::shared_ptr& updateParameters) { MLN_TRACE_FUNC(); assert(updateParameters); impl->synchronizeRetainedUnderlayState(updateParameters->retainedUnderlayState); const bool styleChanged = impl->styleLoaded && !updateParameters->styleLoaded; impl->styleLoaded = updateParameters->styleLoaded; if (!impl->dynamicTextureAtlas || styleChanged) { if (styleChanged) impl->clearPreparedRenderTree(); auto& context = impl->backend.getContext(); impl->dynamicTextureAtlas = std::make_unique(context); } if (impl->tryRenderParticleFastFrame(updateParameters)) return; // A full createRenderTree may replace RenderLayer/RenderSource instances. // Drop the old prepared tree first so its reference-based render items can // never outlive the orchestrator objects they describe. impl->clearPreparedRenderTree(); if (auto renderTree = impl->orchestrator.createRenderTree(updateParameters, impl->dynamicTextureAtlas)) { renderTree->prepare(); impl->render(*renderTree, updateParameters, false); impl->commitPreparedRenderTree(std::move(renderTree), updateParameters); } else { impl->clearPreparedRenderTree(); } } std::vector Renderer::queryRenderedFeatures(const ScreenLineString& geometry, const RenderedQueryOptions& options) const { return impl->orchestrator.queryRenderedFeatures(geometry, options); } std::vector Renderer::queryRenderedFeatures(const ScreenCoordinate& point, const RenderedQueryOptions& options) const { return impl->orchestrator.queryRenderedFeatures({point}, options); } std::vector Renderer::queryRenderedFeatures(const ScreenBox& box, const RenderedQueryOptions& options) const { return impl->orchestrator.queryRenderedFeatures( {box.min, {box.max.x, box.min.y}, box.max, {box.min.x, box.max.y}, box.min}, options); } AnnotationIDs Renderer::queryPointAnnotations(const ScreenBox& box) const { if (!LayerManager::annotationsEnabled) { return {}; } RenderedQueryOptions options; options.layerIDs = {{AnnotationManager::PointLayerID}}; auto features = queryRenderedFeatures(box, options); return getAnnotationIDs(features); } AnnotationIDs Renderer::queryShapeAnnotations(const ScreenBox& box) const { if (!LayerManager::annotationsEnabled) { return {}; } auto features = impl->orchestrator.queryShapeAnnotations( {box.min, {box.max.x, box.min.y}, box.max, {box.min.x, box.max.y}, box.min}); return getAnnotationIDs(features); } AnnotationIDs Renderer::getAnnotationIDs(const std::vector& features) const { if (!LayerManager::annotationsEnabled) { return {}; } std::set set; for (auto& feature : features) { assert(feature.id.is()); assert(feature.id.get() <= std::numeric_limits::max()); set.insert(static_cast(feature.id.get())); } AnnotationIDs ids; ids.reserve(set.size()); std::ranges::move(set, std::back_inserter(ids)); return ids; } std::vector Renderer::querySourceFeatures(const std::string& sourceID, const SourceQueryOptions& options) const { return impl->orchestrator.querySourceFeatures(sourceID, options); } FeatureExtensionValue Renderer::queryFeatureExtensions(const std::string& sourceID, const Feature& feature, const std::string& extension, const std::string& extensionField, const std::optional>& args) const { return impl->orchestrator.queryFeatureExtensions(sourceID, feature, extension, extensionField, args); } void Renderer::setFeatureState(const std::string& sourceID, const std::optional& sourceLayerID, const std::string& featureID, const FeatureState& state) { impl->orchestrator.setFeatureState(sourceID, sourceLayerID, featureID, state); } void Renderer::getFeatureState(FeatureState& state, const std::string& sourceID, const std::optional& sourceLayerID, const std::string& featureID) const { impl->orchestrator.getFeatureState(state, sourceID, sourceLayerID, featureID); } FeatureState Renderer::getFeatureState(const std::string& sourceID, const std::optional& sourceLayerID, const std::string& featureID) const { FeatureState state; getFeatureState(state, sourceID, sourceLayerID, featureID); return state; } void Renderer::removeFeatureState(const std::string& sourceID, const std::optional& sourceLayerID, const std::optional& featureID, const std::optional& stateKey) { impl->orchestrator.removeFeatureState(sourceID, sourceLayerID, featureID, stateKey); } void Renderer::dumpDebugLogs() { impl->orchestrator.dumpDebugLogs(); } void Renderer::collectPlacedSymbolData(bool enable) { impl->orchestrator.collectPlacedSymbolData(enable); } const std::vector& Renderer::getPlacedSymbolsData() const { return impl->orchestrator.getPlacedSymbolsData(); } void Renderer::setTileCacheEnabled(bool enable) { impl->orchestrator.setTileCacheEnabled(enable); } bool Renderer::getTileCacheEnabled() const { return impl->orchestrator.getTileCacheEnabled(); } void Renderer::reduceMemoryUse() { gfx::BackendScope guard{impl->backend}; impl->clearPreparedRenderTree(); impl->reduceMemoryUse(); impl->orchestrator.reduceMemoryUse(); } void Renderer::clearData() { impl->clearPreparedRenderTree(); impl->orchestrator.clearData(); } #if MLN_RENDER_BACKEND_OPENGL void Renderer::enableAndroidEmulatorGoldfishMitigation(bool enable) { impl->orchestrator.enableAndroidEmulatorGoldfishMitigation(enable); } #endif } // namespace mbgl