diff options
author | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2018-10-24 17:13:27 +0300 |
---|---|---|
committer | Alexander Shalamov <alexander.shalamov@mapbox.com> | 2018-11-19 14:06:21 +0200 |
commit | f6ad5f378e9a0741b7d3c293cb91466ba2770e36 (patch) | |
tree | 9c15b4f46a84460822dbdb0b760dd46758b102f9 /src | |
parent | 006ee8b0034eab7096c53a7ca4eddf7226880161 (diff) | |
download | qtlocation-mapboxgl-f6ad5f378e9a0741b7d3c293cb91466ba2770e36.tar.gz |
[core] Move RenderTile filtering / sorting logic to render layers
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/renderer/layers/render_symbol_layer.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/renderer/layers/render_symbol_layer.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/renderer/render_layer.cpp | 39 | ||||
-rw-r--r-- | src/mbgl/renderer/render_layer.hpp | 13 | ||||
-rw-r--r-- | 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<float> pa(a.get().id.canonical.x, a.get().id.canonical.y); + Point<float> 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 <mbgl/renderer/layers/render_symbol_layer.hpp> #include <mbgl/renderer/layers/render_heatmap_layer.hpp> #include <mbgl/renderer/paint_parameters.hpp> -#include <mbgl/style/types.hpp> #include <mbgl/renderer/render_tile.hpp> +#include <mbgl/style/types.hpp> +#include <mbgl/tile/tile.hpp> #include <mbgl/util/logging.hpp> namespace mbgl { @@ -71,8 +72,40 @@ bool RenderLayer::needsRendering(float zoom) const { && baseImpl->maxZoom >= zoom; } -void RenderLayer::setRenderTiles(std::vector<std::reference_wrapper<RenderTile>> 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<std::reference_wrapper<RenderTile>>); + + using RenderTiles = std::vector<std::reference_wrapper<RenderTile>>; + void setRenderTiles(RenderTiles, const TransformState&); + // Private implementation Immutable<style::Layer::Impl> baseImpl; void setImpl(Immutable<style::Layer::Impl>); @@ -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<RenderSymbolLayer>(); - - 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<float> pa(a.id.canonical.x, a.id.canonical.y); - Point<float> 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<std::reference_wrapper<RenderTile>> sortedTilesForInsertion; - const bool fillLayer = layer->is<RenderFillLayer>(); - const bool lineLayer = layer->is<RenderLineLayer>(); - - 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 }); } |