summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Shalamov <alexander.shalamov@mapbox.com>2018-10-24 17:13:27 +0300
committerAlexander Shalamov <alexander.shalamov@mapbox.com>2018-11-19 14:06:21 +0200
commitf6ad5f378e9a0741b7d3c293cb91466ba2770e36 (patch)
tree9c15b4f46a84460822dbdb0b760dd46758b102f9
parent006ee8b0034eab7096c53a7ca4eddf7226880161 (diff)
downloadqtlocation-mapboxgl-f6ad5f378e9a0741b7d3c293cb91466ba2770e36.tar.gz
[core] Move RenderTile filtering / sorting logic to render layers
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.cpp19
-rw-r--r--src/mbgl/renderer/layers/render_symbol_layer.hpp4
-rw-r--r--src/mbgl/renderer/render_layer.cpp39
-rw-r--r--src/mbgl/renderer/render_layer.hpp13
-rw-r--r--src/mbgl/renderer/renderer_impl.cpp47
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 });
}