diff --git a/include/mbgl/gfx/drawable_atlases_tweaker.hpp b/include/mbgl/gfx/drawable_atlases_tweaker.hpp index d014e220e..c9e6a86c6 100644 --- a/include/mbgl/gfx/drawable_atlases_tweaker.hpp +++ b/include/mbgl/gfx/drawable_atlases_tweaker.hpp @@ -26,9 +26,13 @@ public: isText(isText_) {} ~DrawableAtlasesTweaker() override = default; + void init(Drawable&) override; + void execute(Drawable&, const PaintParameters&) override; protected: + void setupTextures(Drawable&); + TileAtlasTexturesPtr atlases; std::string iconName; std::string glyphName; diff --git a/include/mbgl/gfx/drawable_custom_layer_host_tweaker.hpp b/include/mbgl/gfx/drawable_custom_layer_host_tweaker.hpp index df6799fb0..1a6ca0bdd 100644 --- a/include/mbgl/gfx/drawable_custom_layer_host_tweaker.hpp +++ b/include/mbgl/gfx/drawable_custom_layer_host_tweaker.hpp @@ -21,6 +21,8 @@ public: : host(host_) {} ~DrawableCustomLayerHostTweaker() override = default; + void init(Drawable&) override{}; + void execute(Drawable&, const PaintParameters&) override; protected: diff --git a/include/mbgl/gfx/drawable_tweaker.hpp b/include/mbgl/gfx/drawable_tweaker.hpp index 83e37a538..97b8ff1ef 100644 --- a/include/mbgl/gfx/drawable_tweaker.hpp +++ b/include/mbgl/gfx/drawable_tweaker.hpp @@ -20,6 +20,9 @@ protected: public: virtual ~DrawableTweaker() = default; + /// Called as the drawable gets added to the layer + virtual void init(Drawable&) = 0; + /// Called just before rendering virtual void execute(Drawable&, const PaintParameters&) = 0; }; diff --git a/include/mbgl/gfx/vertex_attribute.hpp b/include/mbgl/gfx/vertex_attribute.hpp index 9c6889510..9510e9161 100644 --- a/include/mbgl/gfx/vertex_attribute.hpp +++ b/include/mbgl/gfx/vertex_attribute.hpp @@ -290,8 +290,8 @@ public: if (auto& binder = binders.template get()) { using Attribute = typename DataDrivenPaintProperty::Attribute; using Type = typename Attribute::Type; // ::mbgl::gfx::AttributeType - using Value = typename Type::Value; // std::array using InterpType = ZoomInterpolatedAttributeType; + using Value = typename Type::Value; // std::array using InterpValue = typename InterpType::Value; // std::array const auto vertexCount = binder->getVertexCount(); diff --git a/include/mbgl/renderer/layer_group.hpp b/include/mbgl/renderer/layer_group.hpp index 1721ca733..aa9e80811 100644 --- a/include/mbgl/renderer/layer_group.hpp +++ b/include/mbgl/renderer/layer_group.hpp @@ -57,6 +57,9 @@ public: virtual std::size_t clearDrawables() = 0; + /// Add a drawable + void addDrawable(gfx::UniqueDrawable&); + /// Called before starting each frame virtual void preRender(RenderOrchestrator&, PaintParameters&) {} /// Called during the upload pass diff --git a/src/mbgl/gfx/drawable_atlases_tweaker.cpp b/src/mbgl/gfx/drawable_atlases_tweaker.cpp index 63f142c1f..b3acb1fc5 100644 --- a/src/mbgl/gfx/drawable_atlases_tweaker.cpp +++ b/src/mbgl/gfx/drawable_atlases_tweaker.cpp @@ -7,7 +7,7 @@ namespace mbgl { namespace gfx { -void DrawableAtlasesTweaker::execute(gfx::Drawable& drawable, const PaintParameters&) { +void DrawableAtlasesTweaker::setupTextures(gfx::Drawable& drawable) { if (const auto& shader = drawable.getShader()) { if (const auto samplerLocation = shader->getSamplerLocation(glyphName)) { if (const auto iconSamplerLocation = shader->getSamplerLocation(iconName)) { @@ -21,5 +21,13 @@ void DrawableAtlasesTweaker::execute(gfx::Drawable& drawable, const PaintParamet } } +void DrawableAtlasesTweaker::init(gfx::Drawable& drawable) { + setupTextures(drawable); +} + +void DrawableAtlasesTweaker::execute(gfx::Drawable& drawable, const PaintParameters&) { + setupTextures(drawable); +} + } // namespace gfx } // namespace mbgl diff --git a/src/mbgl/renderer/layer_group.cpp b/src/mbgl/renderer/layer_group.cpp index 39f001455..e621bb870 100644 --- a/src/mbgl/renderer/layer_group.cpp +++ b/src/mbgl/renderer/layer_group.cpp @@ -1,6 +1,7 @@ #include #include +#include #include #include @@ -8,6 +9,13 @@ namespace mbgl { +void LayerGroupBase::addDrawable(gfx::UniqueDrawable& drawable) { + // init their tweakers + for (const auto& tweaker : drawable->getTweakers()) { + tweaker->init(*drawable); + } +} + struct LayerGroup::Impl { using DrawableCollection = std::set; DrawableCollection drawables; @@ -24,6 +32,7 @@ std::size_t LayerGroup::getDrawableCount() const { } void LayerGroup::addDrawable(gfx::UniqueDrawable&& drawable) { + LayerGroupBase::addDrawable(drawable); impl->drawables.emplace(std::move(drawable)); } diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index 059bd2940..acfdfea86 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -748,8 +748,7 @@ constexpr auto fadeOpacityAttribName = "a_fade_opacity"; constexpr auto texUniformName = "u_texture"; constexpr auto iconTexUniformName = "u_texture_icon"; -std::vector updateTileAttributes(gfx::Context& context, - const SymbolBucket::Buffer& buffer, +std::vector updateTileAttributes(const SymbolBucket::Buffer& buffer, const bool isText, const SymbolBucket::PaintProperties& paintProps, const SymbolPaintProperties::PossiblyEvaluated& evaluated, @@ -836,7 +835,7 @@ void updateTileDrawable(gfx::Drawable& drawable, // See `Placement::updateBucketDynamicVertices` gfx::VertexAttributeArray attribs; - updateTileAttributes(context, buffer, isText, paintProps, evaluated, attribs); + updateTileAttributes(buffer, isText, paintProps, evaluated, attribs); drawable.setVertexAttributes(std::move(attribs)); } @@ -933,9 +932,20 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders, } }; - addRenderables(bucket.icon, SymbolType::IconRGBA); - addRenderables(bucket.sdfIcon, SymbolType::IconSDF); - addRenderables(bucket.text, SymbolType::Text); + const auto& atlases = tile.getAtlasTextures(); + if (!atlases) { + continue; + } + + if (bucket.hasIconData() && atlases->icon) { + addRenderables(bucket.icon, SymbolType::IconRGBA); + } + if (bucket.hasSdfIconData() && atlases->icon) { + addRenderables(bucket.sdfIcon, SymbolType::IconSDF); + } + if (bucket.hasTextData() && atlases->glyph) { + addRenderables(bucket.text, SymbolType::Text); + } } // We'll be processing renderables across tiles, potentially out-of-order, so keep @@ -973,8 +983,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders, const auto vertexCount = buffer.vertices().elements(); gfx::VertexAttributeArray attribs; - const auto uniformProps = updateTileAttributes( - context, buffer, isText, bucketPaintProperties, evaluated, attribs); + const auto uniformProps = updateTileAttributes(buffer, isText, bucketPaintProperties, evaluated, attribs); const auto textHalo = evaluated.get().constantOr(Color::black()).a > 0.0f && evaluated.get().constantOr(1); @@ -1014,17 +1023,13 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders, builder->setRenderPass(passes); builder->setCullFaceMode(gfx::CullFaceMode::disabled()); builder->setDepthType(gfx::DepthMaskType::ReadOnly); - builder->setColorMode(passes == RenderPass::Translucent ? gfx::ColorMode::alphaBlended() - : gfx::ColorMode::unblended()); + builder->setColorMode( + ((mbgl::underlying_type(passes) & mbgl::underlying_type(RenderPass::Translucent)) != 0) + ? gfx::ColorMode::alphaBlended() + : gfx::ColorMode::unblended()); builder->setVertexAttrName(posOffsetAttribName); } - builder->clearTweakers(); - builder->addTweaker(isText ? tileInfo.textTweaker : tileInfo.iconTweaker); - builder->setRawVertices({}, vertexCount, gfx::AttributeDataType::Short4); - builder->setDrawableName(layerPrefix + std::string(suffix)); - builder->setVertexAttributes(attribs); - const auto shader = std::static_pointer_cast( shaderGroup->getOrCreateShader(context, uniformProps, posOffsetAttribName)); if (!shader) { @@ -1032,6 +1037,12 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders, } builder->setShader(shader); + builder->clearTweakers(); + builder->addTweaker(isText ? tileInfo.textTweaker : tileInfo.iconTweaker); + builder->setRawVertices({}, vertexCount, gfx::AttributeDataType::Short4); + builder->setDrawableName(layerPrefix + std::string(suffix)); + builder->setVertexAttributes(attribs); + // TODO: texture filtering // const bool linear = parameters.state.isChanging() || transformed || // !partiallyEvaluatedTextSize.isZoomConstant; const auto filterType = linear ? diff --git a/src/mbgl/renderer/renderer.cpp b/src/mbgl/renderer/renderer.cpp index 8a82c522e..8fb96a85a 100644 --- a/src/mbgl/renderer/renderer.cpp +++ b/src/mbgl/renderer/renderer.cpp @@ -32,8 +32,7 @@ void Renderer::render(const std::shared_ptr& updateParameters) assert(updateParameters); if (auto renderTree = impl->orchestrator.createRenderTree(updateParameters)) { renderTree->prepare(); - impl->preRender(*renderTree, updateParameters); - impl->render(*renderTree); + impl->render(*renderTree, updateParameters); } } diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 90452bd24..61ba71d7e 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -66,9 +66,9 @@ void Renderer::Impl::setObserver(RendererObserver* observer_) { observer = observer_ ? observer_ : &nullObserver(); } -void Renderer::Impl::preRender([[maybe_unused]] const RenderTree& renderTree, - [[maybe_unused]] const std::shared_ptr& updateParameters) { - [[maybe_unused]] auto& context = backend.getContext(); +void Renderer::Impl::render(const RenderTree& renderTree, + [[maybe_unused]] const std::shared_ptr& updateParameters) { + auto& context = backend.getContext(); // Blocks execution until the renderable is available. backend.getDefaultRenderable().wait(); @@ -92,23 +92,11 @@ void Renderer::Impl::preRender([[maybe_unused]] const RenderTree& renderTree, const auto& renderTreeParameters = renderTree.getParameters(); staticData->has3D = renderTreeParameters.has3D; -#if MLN_DRAWABLE_RENDERER - // update layers - if (staticData && staticData->shaders) { - orchestrator.updateLayers( - *staticData->shaders, context, renderTreeParameters.transformParams.state, updateParameters, renderTree); - } -#endif -} - -void Renderer::Impl::render(const RenderTree& renderTree) { if (renderState == RenderState::Never) { observer->onWillStartRenderingMap(); } observer->onWillStartRenderingFrame(); - auto& context = backend.getContext(); - const auto& renderTreeParameters = renderTree.getParameters(); PaintParameters parameters{context, pixelRatio, @@ -127,22 +115,6 @@ void Renderer::Impl::render(const RenderTree& renderTree) { const auto& sourceRenderItems = renderTree.getSourceRenderItems(); const auto& layerRenderItems = renderTree.getLayerRenderItems(); -#if MLN_DRAWABLE_RENDERER - // Run changes - orchestrator.processChanges(); - - // Run layer tweakers to update any dynamic elements - orchestrator.observeLayerGroups([&](LayerGroupBase& layerGroup) { - if (const auto& tweaker = layerGroup.getLayerTweaker()) { - tweaker->execute(layerGroup, renderTree, parameters); - } - }); - - // Give the layers a chance to do setup - // orchestrator.observeLayerGroups([&](LayerGroup& layerGroup) { layerGroup.preRender(orchestrator, parameters); - // }); -#endif - // - UPLOAD PASS ------------------------------------------------------------------------------- // Uploads all required buffers and images before we do any actual rendering. { @@ -158,15 +130,41 @@ void Renderer::Impl::render(const RenderTree& renderTree) { staticData->upload(*uploadPass); renderTree.getLineAtlas().upload(*uploadPass); renderTree.getPatternAtlas().upload(*uploadPass); + } #if MLN_DRAWABLE_RENDERER + // - LAYER GROUP UPDATE ------------------------------------------------------------------------ + // Updates all layer groups and process changes + if (staticData && staticData->shaders) { + orchestrator.updateLayers( + *staticData->shaders, context, renderTreeParameters.transformParams.state, updateParameters, renderTree); + } + + // Run changes + orchestrator.processChanges(); + + // Run layer tweakers to update any dynamic elements + orchestrator.observeLayerGroups([&](LayerGroupBase& layerGroup) { + if (layerGroup.getLayerTweaker()) { + layerGroup.getLayerTweaker()->execute(layerGroup, renderTree, parameters); + } + }); + + // Give the layers a chance to do setup + // orchestrator.observeLayerGroups([&](LayerGroup& layerGroup) { layerGroup.preRender(orchestrator, parameters); + // }); + + // Upload layer groups + { + const auto uploadPass = parameters.encoder->createUploadPass("layerGroup-upload"); + // Give the layers a chance to upload orchestrator.observeLayerGroups([&](LayerGroupBase& layerGroup) { layerGroup.upload(*uploadPass); }); // Give the render targets a chance to upload orchestrator.observeRenderTargets([&](RenderTarget& renderTarget) { renderTarget.upload(*uploadPass); }); -#endif } +#endif // - 3D PASS // ------------------------------------------------------------------------------------- diff --git a/src/mbgl/renderer/renderer_impl.hpp b/src/mbgl/renderer/renderer_impl.hpp index cffd861ab..91259f4d8 100644 --- a/src/mbgl/renderer/renderer_impl.hpp +++ b/src/mbgl/renderer/renderer_impl.hpp @@ -26,9 +26,7 @@ private: void setObserver(RendererObserver*); - void preRender(const RenderTree&, const std::shared_ptr&); - - void render(const RenderTree&); + void render(const RenderTree&, const std::shared_ptr&); void reduceMemoryUse(); diff --git a/src/mbgl/renderer/tile_layer_group.cpp b/src/mbgl/renderer/tile_layer_group.cpp index b835603bd..4d670988e 100644 --- a/src/mbgl/renderer/tile_layer_group.cpp +++ b/src/mbgl/renderer/tile_layer_group.cpp @@ -77,6 +77,7 @@ std::vector TileLayerGroup::removeDrawables(mbgl::RenderPas void TileLayerGroup::addDrawable(mbgl::RenderPass pass, const OverscaledTileID& id, gfx::UniqueDrawable&& drawable) { assert(impl->drawablesByTile.size() == impl->sortedDrawables.size()); if (drawable) { + LayerGroupBase::addDrawable(drawable); [[maybe_unused]] const auto result = impl->sortedDrawables.insert(drawable.get()); assert(result.second); impl->drawablesByTile.insert(std::make_pair(TileLayerGroupTileKey{pass, id}, std::move(drawable)));