From f6ad5f378e9a0741b7d3c293cb91466ba2770e36 Mon Sep 17 00:00:00 2001 From: Alexander Shalamov Date: Wed, 24 Oct 2018 17:13:27 +0300 Subject: [core] Move RenderTile filtering / sorting logic to render layers --- src/mbgl/renderer/layers/render_symbol_layer.cpp | 19 ++++++++++ src/mbgl/renderer/layers/render_symbol_layer.hpp | 4 ++ src/mbgl/renderer/render_layer.cpp | 39 ++++++++++++++++++-- src/mbgl/renderer/render_layer.hpp | 13 ++++++- src/mbgl/renderer/renderer_impl.cpp | 47 +----------------------- 5 files changed, 71 insertions(+), 51 deletions(-) diff --git a/src/mbgl/renderer/layers/render_symbol_layer.cpp b/src/mbgl/renderer/layers/render_symbol_layer.cpp index df38d64d70..cc084c5e1a 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.cpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.cpp @@ -362,4 +362,23 @@ style::SymbolPropertyValues RenderSymbolLayer::textPropertyValues(const style::S }; } +RenderLayer::RenderTiles RenderSymbolLayer::filterRenderTiles(RenderTiles tiles) const { + auto filterFn = [](auto& tile){ return !tile.tile.isRenderable(); }; + return RenderLayer::filterRenderTiles(std::move(tiles), filterFn); +} + +void RenderSymbolLayer::sortRenderTiles(const TransformState& state) { + // Sort symbol tiles in opposite y position, so tiles with overlapping symbols are drawn + // on top of each other, with lower symbols being drawn on top of higher symbols. + std::sort(renderTiles.begin(), renderTiles.end(), [&state](const auto& a, const auto& b) { + Point pa(a.get().id.canonical.x, a.get().id.canonical.y); + Point pb(b.get().id.canonical.x, b.get().id.canonical.y); + + auto par = util::rotate(pa, state.getAngle()); + auto pbr = util::rotate(pb, state.getAngle()); + + return std::tie(b.get().id.canonical.z, par.y, par.x) < std::tie(a.get().id.canonical.z, pbr.y, pbr.x); + }); +} + } // namespace mbgl diff --git a/src/mbgl/renderer/layers/render_symbol_layer.hpp b/src/mbgl/renderer/layers/render_symbol_layer.hpp index 48e048f271..bd43324712 100644 --- a/src/mbgl/renderer/layers/render_symbol_layer.hpp +++ b/src/mbgl/renderer/layers/render_symbol_layer.hpp @@ -88,6 +88,10 @@ public: float textSize = 16.0f; const style::SymbolLayer::Impl& impl() const; + +protected: + RenderTiles filterRenderTiles(RenderTiles) const final; + void sortRenderTiles(const TransformState&) final; }; template <> diff --git a/src/mbgl/renderer/render_layer.cpp b/src/mbgl/renderer/render_layer.cpp index 44c141c741..652dad0472 100644 --- a/src/mbgl/renderer/render_layer.cpp +++ b/src/mbgl/renderer/render_layer.cpp @@ -10,8 +10,9 @@ #include #include #include -#include #include +#include +#include #include namespace mbgl { @@ -71,8 +72,40 @@ bool RenderLayer::needsRendering(float zoom) const { && baseImpl->maxZoom >= zoom; } -void RenderLayer::setRenderTiles(std::vector> tiles) { - renderTiles = std::move(tiles); +void RenderLayer::setRenderTiles(RenderTiles tiles, const TransformState& state) { + renderTiles = filterRenderTiles(std::move(tiles)); + sortRenderTiles(state); +} + +RenderLayer::RenderTiles RenderLayer::filterRenderTiles(RenderTiles tiles) const { + auto filterFn = [](auto& tile){ return !tile.tile.isRenderable() || tile.tile.holdForFade(); }; + return filterRenderTiles(std::move(tiles), filterFn); +} + +void RenderLayer::sortRenderTiles(const TransformState&) { + std::sort(renderTiles.begin(), renderTiles.end(), [](const auto& a, const auto& b) { return a.get().id < b.get().id; }); +} + +RenderLayer::RenderTiles RenderLayer::filterRenderTiles(RenderTiles tiles, FilterFunctionPtr filterFn) const { + assert(filterFn != nullptr); + RenderTiles filtered; + // We only need clipping when we're drawing fill or line layers. + const bool needsClipping_ = + baseImpl->getTypeInfo()->clipping == LayerTypeInfo::Clipping::Required; + + for (auto& tileRef : tiles) { + auto& tile = tileRef.get(); + if (filterFn(tile)) { + continue; + } + + if (tile.tile.getBucket(*baseImpl)) { + tile.used = true; + tile.needsClipping |= needsClipping_; + filtered.emplace_back(tile); + } + } + return filtered; } void RenderLayer::markContextDestroyed() { diff --git a/src/mbgl/renderer/render_layer.hpp b/src/mbgl/renderer/render_layer.hpp index 8d17e318f2..04753fc674 100644 --- a/src/mbgl/renderer/render_layer.hpp +++ b/src/mbgl/renderer/render_layer.hpp @@ -86,7 +86,10 @@ public: ImageDependencies&) const { return nullptr; } - void setRenderTiles(std::vector>); + + using RenderTiles = std::vector>; + void setRenderTiles(RenderTiles, const TransformState&); + // Private implementation Immutable baseImpl; void setImpl(Immutable); @@ -98,6 +101,12 @@ protected: // in the console to inform the developer. void checkRenderability(const PaintParameters&, uint32_t activeBindingCount); + // Code specific to RenderTiles sorting / filtering + virtual RenderTiles filterRenderTiles(RenderTiles) const; + virtual void sortRenderTiles(const TransformState&); + using FilterFunctionPtr = bool (*)(RenderTile&); + RenderTiles filterRenderTiles(RenderTiles, FilterFunctionPtr) const; + protected: // renderTiles are exposed directly to CrossTileSymbolIndex and Placement so they // can update opacities in the symbol buckets immediately before rendering @@ -111,7 +120,7 @@ protected: RenderPass passes = RenderPass::None; private: - // Some layers may not render correctly on some hardware when the vertex attribute limit of + // Some layers may not render correctly on some hardware when the vertex attribute limit of // that GPU is exceeded. More attributes are used when adding many data driven paint properties // to a layer. bool hasRenderFailures = false; diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index d6572712cd..46ee0ca973 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -331,52 +331,7 @@ void Renderer::Impl::render(const UpdateParameters& updateParameters) { continue; } - const bool symbolLayer = layer->is(); - - auto sortedTiles = source->getRenderTiles(); - if (symbolLayer) { - // Sort symbol tiles in opposite y position, so tiles with overlapping symbols are drawn - // on top of each other, with lower symbols being drawn on top of higher symbols. - std::sort(sortedTiles.begin(), sortedTiles.end(), [&](const RenderTile& a, const RenderTile& b) { - Point pa(a.id.canonical.x, a.id.canonical.y); - Point pb(b.id.canonical.x, b.id.canonical.y); - - auto par = util::rotate(pa, parameters.state.getAngle()); - auto pbr = util::rotate(pb, parameters.state.getAngle()); - - return std::tie(b.id.canonical.z, par.y, par.x) < std::tie(a.id.canonical.z, pbr.y, pbr.x); - }); - } else { - std::sort(sortedTiles.begin(), sortedTiles.end(), - [](const auto& a, const auto& b) { return a.get().id < b.get().id; }); - // Don't render non-symbol layers for tiles that we're only holding on to for symbol fading - sortedTiles.erase(std::remove_if(sortedTiles.begin(), sortedTiles.end(), - [](const auto& tile) { return tile.get().tile.holdForFade(); }), - sortedTiles.end()); - } - - std::vector> sortedTilesForInsertion; - const bool fillLayer = layer->is(); - const bool lineLayer = layer->is(); - - for (auto& sortedTile : sortedTiles) { - auto& tile = sortedTile.get(); - if (!tile.tile.isRenderable()) { - continue; - } - - auto bucket = tile.tile.getBucket(*layer->baseImpl); - if (bucket) { - sortedTilesForInsertion.emplace_back(tile); - tile.used = true; - - // We only need clipping when we're drawing fill or line layers. - if (fillLayer || lineLayer) { - tile.needsClipping = true; - } - } - } - layer->setRenderTiles(std::move(sortedTilesForInsertion)); + layer->setRenderTiles(source->getRenderTiles(), parameters.state); order.emplace_back(RenderItem { *layer, source }); } -- cgit v1.2.1