summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2015-05-20 17:52:00 -0400
committerAnsis Brammanis <brammanis@gmail.com>2015-05-20 17:52:00 -0400
commitd41bfa26796c955da65cccba48f2d9b697b18abf (patch)
treee1ff1d5d5eca8701d303ebfe0b64cc3f8aaa548d /src
parent7abd7950c96a493bf054631332ab2bbcc4aac016 (diff)
downloadqtlocation-mapboxgl-d41bfa26796c955da65cccba48f2d9b697b18abf.tar.gz
redo placement when map rotates
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/map/source.cpp8
-rw-r--r--src/mbgl/map/source.hpp1
-rw-r--r--src/mbgl/map/tile_data.cpp1
-rw-r--r--src/mbgl/map/tile_data.hpp3
-rw-r--r--src/mbgl/map/vector_tile_data.cpp47
-rw-r--r--src/mbgl/map/vector_tile_data.hpp8
-rw-r--r--src/mbgl/renderer/bucket.hpp3
-rw-r--r--src/mbgl/renderer/symbol_bucket.cpp41
-rw-r--r--src/mbgl/renderer/symbol_bucket.hpp43
9 files changed, 125 insertions, 30 deletions
diff --git a/src/mbgl/map/source.cpp b/src/mbgl/map/source.cpp
index e8dc3468d3..7ab0894603 100644
--- a/src/mbgl/map/source.cpp
+++ b/src/mbgl/map/source.cpp
@@ -497,6 +497,8 @@ bool Source::update(MapData& data,
updateTilePtrs();
+ redoPlacement(transformState);
+
updated = data.getAnimationTime();
return allTilesUpdated;
@@ -518,6 +520,12 @@ void Source::updateTilePtrs() {
}
}
+void Source::redoPlacement(const TransformState& transformState) {
+ for (auto& tilePtr : tilePtrs) {
+ tilePtr->data->redoPlacement(transformState.getAngle());
+ }
+}
+
void Source::setCacheSize(size_t size) {
cache.setSize(size);
}
diff --git a/src/mbgl/map/source.hpp b/src/mbgl/map/source.hpp
index 9d3de81b70..2c5ac85f49 100644
--- a/src/mbgl/map/source.hpp
+++ b/src/mbgl/map/source.hpp
@@ -101,6 +101,7 @@ public:
bool enabled;
private:
+ void redoPlacement(const TransformState& transformState);
void emitSourceLoaded();
void emitTileLoaded(bool isNewTile);
diff --git a/src/mbgl/map/tile_data.cpp b/src/mbgl/map/tile_data.cpp
index e9084bdff2..83488ecb9b 100644
--- a/src/mbgl/map/tile_data.cpp
+++ b/src/mbgl/map/tile_data.cpp
@@ -1,6 +1,7 @@
#include <mbgl/map/tile_data.hpp>
#include <mbgl/map/environment.hpp>
#include <mbgl/map/source.hpp>
+#include <mbgl/map/transform_state.hpp>
#include <mbgl/storage/file_source.hpp>
#include <mbgl/util/worker.hpp>
diff --git a/src/mbgl/map/tile_data.hpp b/src/mbgl/map/tile_data.hpp
index 3945a32147..d1ca10ddd4 100644
--- a/src/mbgl/map/tile_data.hpp
+++ b/src/mbgl/map/tile_data.hpp
@@ -21,6 +21,7 @@ class StyleLayer;
class Request;
class Worker;
class WorkRequest;
+class TransformState;
class TileData : private util::noncopyable {
public:
@@ -79,6 +80,8 @@ public:
virtual void parse() = 0;
virtual Bucket* getBucket(StyleLayer const &layer_desc) = 0;
+ virtual void redoPlacement(float) {}
+
const TileID id;
const std::string name;
std::atomic_flag parsing = ATOMIC_FLAG_INIT;
diff --git a/src/mbgl/map/vector_tile_data.cpp b/src/mbgl/map/vector_tile_data.cpp
index f040422e46..f8a928024f 100644
--- a/src/mbgl/map/vector_tile_data.cpp
+++ b/src/mbgl/map/vector_tile_data.cpp
@@ -8,6 +8,9 @@
#include <mbgl/platform/log.hpp>
#include <mbgl/text/collision_tile.hpp>
#include <mbgl/util/pbf.hpp>
+#include <mbgl/util/worker.hpp>
+#include <mbgl/util/work_request.hpp>
+#include <mbgl/style/style.hpp>
using namespace mbgl;
@@ -104,6 +107,48 @@ void VectorTileData::setState(const State& state_) {
TileData::setState(state_);
if (isImmutable()) {
- collision.reset();
+ collision->reset(0, 0);
+ }
+}
+
+void VectorTileData::redoPlacement(float angle) {
+ if (angle != currentAngle) {
+ lastAngle = angle;
+
+ if (getState() != State::parsed || redoingPlacement) {
+ redoWhenDone = true;
+ return;
+ }
+
+ redoingPlacement = true;
+ currentAngle = angle;
+
+ auto callback = std::bind(&VectorTileData::endRedoPlacement, this);
+ workRequest = style.workers.send([this, angle] { workerRedoPlacement(angle); }, callback);
+
+ }
+}
+
+void VectorTileData::workerRedoPlacement(float angle) {
+ collision->reset(angle, 0);
+ for (const auto& layer_desc : style.layers) {
+ auto bucket = getBucket(*layer_desc);
+ if (bucket) {
+ bucket->placeFeatures();
+ }
+ }
+}
+
+void VectorTileData::endRedoPlacement() {
+ for (const auto& layer_desc : style.layers) {
+ auto bucket = getBucket(*layer_desc);
+ if (bucket) {
+ bucket->swapRenderData();
+ }
+ }
+ redoingPlacement = false;
+ if (redoWhenDone) {
+ redoPlacement(lastAngle);
+ redoWhenDone = false;
}
}
diff --git a/src/mbgl/map/vector_tile_data.hpp b/src/mbgl/map/vector_tile_data.hpp
index 09a6330ed0..2cf419079f 100644
--- a/src/mbgl/map/vector_tile_data.hpp
+++ b/src/mbgl/map/vector_tile_data.hpp
@@ -43,6 +43,7 @@ public:
~VectorTileData();
void parse() override;
+ void redoPlacement(float angle) override;
virtual Bucket* getBucket(StyleLayer const &layer_desc) override;
size_t countBuckets() const;
@@ -81,6 +82,13 @@ private:
mutable std::mutex bucketsMutex;
std::unique_ptr<CollisionTile> collision;
+
+ float lastAngle = 0;
+ float currentAngle = 0;
+ bool redoingPlacement = false;
+ bool redoWhenDone = false;
+ void endRedoPlacement();
+ void workerRedoPlacement(float angle);
};
}
diff --git a/src/mbgl/renderer/bucket.hpp b/src/mbgl/renderer/bucket.hpp
index 711fc42384..147895a099 100644
--- a/src/mbgl/renderer/bucket.hpp
+++ b/src/mbgl/renderer/bucket.hpp
@@ -27,6 +27,9 @@ public:
return !uploaded;
}
+ virtual void placeFeatures() {}
+ virtual void swapRenderData() {}
+
protected:
bool uploaded = false;
diff --git a/src/mbgl/renderer/symbol_bucket.cpp b/src/mbgl/renderer/symbol_bucket.cpp
index a14f9a7a41..6995d7a043 100644
--- a/src/mbgl/renderer/symbol_bucket.cpp
+++ b/src/mbgl/renderer/symbol_bucket.cpp
@@ -63,12 +63,12 @@ SymbolBucket::~SymbolBucket() {
void SymbolBucket::upload() {
if (hasTextData()) {
- text.vertices.upload();
- text.triangles.upload();
+ renderData->text.vertices.upload();
+ renderData->text.triangles.upload();
}
if (hasIconData()) {
- icon.vertices.upload();
- icon.triangles.upload();
+ renderData->icon.vertices.upload();
+ renderData->icon.triangles.upload();
}
uploaded = true;
@@ -83,11 +83,11 @@ void SymbolBucket::render(Painter& painter,
bool SymbolBucket::hasData() const { return hasTextData() || hasIconData(); }
-bool SymbolBucket::hasTextData() const { return !text.groups.empty(); }
+bool SymbolBucket::hasTextData() const { return renderData && !renderData->text.groups.empty(); }
-bool SymbolBucket::hasIconData() const { return !icon.groups.empty(); }
+bool SymbolBucket::hasIconData() const { return renderData && !renderData->icon.groups.empty(); }
-bool SymbolBucket::hasCollisionBoxData() const { return !collisionBox.groups.empty(); }
+bool SymbolBucket::hasCollisionBoxData() const { return renderData && !renderData->collisionBox.groups.empty(); }
bool SymbolBucket::needsDependencies(const GeometryTileLayer& layer,
const FilterExpression& filter,
@@ -263,7 +263,7 @@ void SymbolBucket::addFeatures(uintptr_t tileUID,
features.clear();
- placeFeatures();
+ placeFeatures(true);
}
@@ -317,6 +317,12 @@ void SymbolBucket::addFeature(const std::vector<std::vector<Coordinate>> &lines,
}
void SymbolBucket::placeFeatures() {
+ placeFeatures(false);
+}
+
+void SymbolBucket::placeFeatures(bool swapImmediately) {
+
+ renderDataInProgress = util::make_unique<SymbolRenderData>();
// Calculate which labels can be shown and when they can be shown and
// create the bufers used for rendering.
@@ -363,7 +369,8 @@ void SymbolBucket::placeFeatures() {
collision.insertFeature(symbolInstance.textCollisionFeature, glyphScale);
}
if (glyphScale < collision.maxScale) {
- addSymbols<TextBuffer, TextElementGroup>(text, symbolInstance.glyphQuads, glyphScale, layout.text.keep_upright, textAlongLine);
+ addSymbols<SymbolRenderData::TextBuffer, TextElementGroup>(renderDataInProgress->text,
+ symbolInstance.glyphQuads, glyphScale, layout.text.keep_upright, textAlongLine);
}
}
@@ -372,12 +379,15 @@ void SymbolBucket::placeFeatures() {
collision.insertFeature(symbolInstance.iconCollisionFeature, iconScale);
}
if (iconScale < collision.maxScale) {
- addSymbols<IconBuffer, IconElementGroup>(icon, symbolInstance.iconQuads, iconScale, layout.icon.keep_upright, iconAlongLine);
+ addSymbols<SymbolRenderData::IconBuffer, IconElementGroup>(renderDataInProgress->icon,
+ symbolInstance.iconQuads, iconScale, layout.icon.keep_upright, iconAlongLine);
}
}
}
addToDebugBuffers();
+
+ if (swapImmediately) swapRenderData();
}
template <typename Buffer, typename GroupType>
@@ -448,7 +458,7 @@ void SymbolBucket::addSymbols(Buffer &buffer, const SymbolQuads &symbols, float
void SymbolBucket::addToDebugBuffers() {
const float yStretch = 1.0f;
- const float angle = 0.0f;
+ const float angle = collision.angle;
const float zoom = collision.zoom;
float angle_sin = std::sin(-angle);
float angle_cos = std::cos(-angle);
@@ -475,6 +485,7 @@ void SymbolBucket::addToDebugBuffers() {
const float maxZoom = util::max(0.0f, util::min(25.0f, static_cast<float>(zoom + log(box.maxScale) / log(2))));
const float placementZoom= util::max(0.0f, util::min(25.0f, static_cast<float>(zoom + log(box.placementScale) / log(2))));
+ auto& collisionBox = renderDataInProgress->collisionBox;
if (!collisionBox.groups.size()) {
// Move to a new group because the old one can't hold the geometry.
collisionBox.groups.emplace_back(util::make_unique<CollisionBoxElementGroup>());
@@ -496,9 +507,14 @@ void SymbolBucket::addToDebugBuffers() {
}
}
+void SymbolBucket::swapRenderData() {
+ renderData = std::move(renderDataInProgress);
+}
+
void SymbolBucket::drawGlyphs(SDFShader &shader) {
char *vertex_index = BUFFER_OFFSET(0);
char *elements_index = BUFFER_OFFSET(0);
+ auto& text = renderData->text;
for (auto &group : text.groups) {
assert(group);
group->array[0].bind(shader, text.vertices, text.triangles, vertex_index);
@@ -511,6 +527,7 @@ void SymbolBucket::drawGlyphs(SDFShader &shader) {
void SymbolBucket::drawIcons(SDFShader &shader) {
char *vertex_index = BUFFER_OFFSET(0);
char *elements_index = BUFFER_OFFSET(0);
+ auto& icon = renderData->icon;
for (auto &group : icon.groups) {
assert(group);
group->array[0].bind(shader, icon.vertices, icon.triangles, vertex_index);
@@ -523,6 +540,7 @@ void SymbolBucket::drawIcons(SDFShader &shader) {
void SymbolBucket::drawIcons(IconShader &shader) {
char *vertex_index = BUFFER_OFFSET(0);
char *elements_index = BUFFER_OFFSET(0);
+ auto& icon = renderData->icon;
for (auto &group : icon.groups) {
assert(group);
group->array[1].bind(shader, icon.vertices, icon.triangles, vertex_index);
@@ -534,6 +552,7 @@ void SymbolBucket::drawIcons(IconShader &shader) {
void SymbolBucket::drawCollisionBoxes(CollisionBoxShader &shader) {
char *vertex_index = BUFFER_OFFSET(0);
+ auto& collisionBox = renderData->collisionBox;
for (auto &group : collisionBox.groups) {
group->array[0].bind(shader, collisionBox.vertices, vertex_index);
MBGL_CHECK_ERROR(glDrawArrays(GL_LINES, 0, group->vertex_length));
diff --git a/src/mbgl/renderer/symbol_bucket.hpp b/src/mbgl/renderer/symbol_bucket.hpp
index fb696b03bd..43d91bf419 100644
--- a/src/mbgl/renderer/symbol_bucket.hpp
+++ b/src/mbgl/renderer/symbol_bucket.hpp
@@ -87,15 +87,18 @@ public:
const FilterExpression&,
GlyphStore&,
Sprite&);
+ void placeFeatures();
private:
void addFeature(const std::vector<std::vector<Coordinate>> &lines,
const Shaping &shapedText, const PositionedIcon &shapedIcon,
const GlyphPositions &face);
- void placeFeatures();
void addToDebugBuffers();
+ void placeFeatures(bool swapImmediately);
+ void swapRenderData();
+
// Adds placed items to the buffer.
template <typename Buffer, typename GroupType>
void addSymbols(Buffer &buffer, const SymbolQuads &symbols, float scale, const bool keepUpright, const bool alongLine);
@@ -109,23 +112,27 @@ private:
std::vector<SymbolInstance> symbolInstances;
std::vector<SymbolFeature> features;
- struct TextBuffer {
- TextVertexBuffer vertices;
- TriangleElementsBuffer triangles;
- std::vector<std::unique_ptr<TextElementGroup>> groups;
- } text;
-
- struct IconBuffer {
- IconVertexBuffer vertices;
- TriangleElementsBuffer triangles;
- std::vector<std::unique_ptr<IconElementGroup>> groups;
- } icon;
-
- struct CollisionBoxBuffer {
- CollisionBoxVertexBuffer vertices;
- std::vector<std::unique_ptr<CollisionBoxElementGroup>> groups;
- } collisionBox;
-
+ struct SymbolRenderData {
+ struct TextBuffer {
+ TextVertexBuffer vertices;
+ TriangleElementsBuffer triangles;
+ std::vector<std::unique_ptr<TextElementGroup>> groups;
+ } text;
+
+ struct IconBuffer {
+ IconVertexBuffer vertices;
+ TriangleElementsBuffer triangles;
+ std::vector<std::unique_ptr<IconElementGroup>> groups;
+ } icon;
+
+ struct CollisionBoxBuffer {
+ CollisionBoxVertexBuffer vertices;
+ std::vector<std::unique_ptr<CollisionBoxElementGroup>> groups;
+ } collisionBox;
+ };
+
+ std::unique_ptr<SymbolRenderData> renderData;
+ std::unique_ptr<SymbolRenderData> renderDataInProgress;
};
}