[core] Sort symbol render tiles prior to rendering

This commit is contained in:
Bruno de Oliveira Abinader
2016-10-31 09:25:38 +02:00
parent ce14037b55
commit e9f849e4d0
3 changed files with 30 additions and 6 deletions

View File

@@ -125,7 +125,7 @@ void Painter::render(const Style& style, const FrameData& frame_, View& view, Sp
spriteAtlas = style.spriteAtlas.get();
lineAtlas = style.lineAtlas.get();
RenderData renderData = style.getRenderData(frame.debugOptions);
RenderData renderData = style.getRenderData(frame.debugOptions, state.getAngle());
const std::vector<RenderItem>& order = renderData.order;
const std::unordered_set<Source*>& sources = renderData.sources;

View File

@@ -353,7 +353,7 @@ bool Style::isLoaded() const {
return true;
}
RenderData Style::getRenderData(MapDebugOptions debugOptions) const {
RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const {
RenderData result;
for (const auto& source : sources) {
@@ -362,6 +362,9 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const {
}
}
const bool isLeft = std::abs(angle) > M_PI_2;
const bool isBottom = angle < 0;
for (const auto& layer : layers) {
if (!layer->baseImpl->needsRendering(zoomHistory.lastZoom)) {
continue;
@@ -395,8 +398,29 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const {
continue;
}
for (auto& pair : source->baseImpl->getRenderTiles()) {
auto& tile = pair.second;
auto& renderTiles = source->baseImpl->getRenderTiles();
const bool symbolLayer = layer->is<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::vector<std::reference_wrapper<RenderTile>> sortedTiles;
std::transform(renderTiles.begin(), renderTiles.end(), std::back_inserter(sortedTiles),
[](auto& pair) { return std::ref(pair.second); });
if (symbolLayer) {
std::sort(sortedTiles.begin(), sortedTiles.end(),
[isLeft, isBottom](const RenderTile& a, const RenderTile& b) {
bool sortX = a.id.canonical.x > b.id.canonical.x;
bool sortW = a.id.wrap > b.id.wrap;
bool sortY = a.id.canonical.y > b.id.canonical.y;
return
a.id.canonical.y != b.id.canonical.y ? (isLeft ? sortY : !sortY) :
a.id.wrap != b.id.wrap ? (isBottom ? sortW : !sortW) : (isBottom ? sortX : !sortX);
});
}
for (auto& tileRef : sortedTiles) {
auto& tile = tileRef.get();
if (!tile.tile.isRenderable()) {
continue;
}
@@ -404,7 +428,7 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions) const {
// We're not clipping symbol layers, so when we have both parents and children of symbol
// layers, we drop all children in favor of their parent to avoid duplicate labels.
// See https://github.com/mapbox/mapbox-gl-native/issues/2482
if (layer->is<SymbolLayer>()) {
if (symbolLayer) {
bool skip = false;
// Look back through the buckets we decided to render to find out whether there is
// already a bucket from this layer that is a parent of this tile. Tiles are ordered

View File

@@ -90,7 +90,7 @@ public:
bool hasClass(const std::string&) const;
std::vector<std::string> getClasses() const;
RenderData getRenderData(MapDebugOptions) const;
RenderData getRenderData(MapDebugOptions, float angle) const;
std::vector<Feature> queryRenderedFeatures(const QueryParameters&) const;