[core] Fix ambiguous condition on the sort criteria

The previous sorting criteria would sometimes allow

C > B, B > A but A > C, making the internal std::sort
code sometimes point to an invalid reference.

Fixes #7737
This commit is contained in:
Thiago Marcos P. Santos
2017-01-16 17:43:33 +02:00
committed by John Firebaugh
parent 76301b252c
commit bd71eb8681

View File

@@ -26,8 +26,10 @@
#include <mbgl/renderer/render_item.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/util/constants.hpp>
#include <mbgl/util/geometry.hpp>
#include <mbgl/util/string.hpp>
#include <mbgl/util/logging.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/math/minmax.hpp>
#include <algorithm>
@@ -409,9 +411,6 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) 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;
@@ -456,13 +455,14 @@ RenderData Style::getRenderData(MapDebugOptions debugOptions, float angle) const
[](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);
[angle](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, angle);
auto pbr = util::rotate(pb, angle);
return std::tie(par.y, par.x) < std::tie(pbr.y, pbr.x);
});
}