diff options
author | Ansis Brammanis <brammanis@gmail.com> | 2015-05-20 17:52:00 -0400 |
---|---|---|
committer | Ansis Brammanis <brammanis@gmail.com> | 2015-05-20 17:52:00 -0400 |
commit | d41bfa26796c955da65cccba48f2d9b697b18abf (patch) | |
tree | e1ff1d5d5eca8701d303ebfe0b64cc3f8aaa548d /src/mbgl | |
parent | 7abd7950c96a493bf054631332ab2bbcc4aac016 (diff) | |
download | qtlocation-mapboxgl-d41bfa26796c955da65cccba48f2d9b697b18abf.tar.gz |
redo placement when map rotates
Diffstat (limited to 'src/mbgl')
-rw-r--r-- | src/mbgl/map/source.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/map/source.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/map/tile_data.cpp | 1 | ||||
-rw-r--r-- | src/mbgl/map/tile_data.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/map/vector_tile_data.cpp | 47 | ||||
-rw-r--r-- | src/mbgl/map/vector_tile_data.hpp | 8 | ||||
-rw-r--r-- | src/mbgl/renderer/bucket.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.cpp | 41 | ||||
-rw-r--r-- | src/mbgl/renderer/symbol_bucket.hpp | 43 |
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; }; } |