From f9601ae68595e5bd2d7951d8ecf8e11117b2162c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20K=C3=A4fer?= Date: Thu, 2 Jul 2015 17:44:32 +0200 Subject: [PATCH] add ability to set custom sprites on the Map object --- include/mbgl/map/map.hpp | 5 +++++ src/mbgl/geometry/sprite_atlas.cpp | 28 ++++++++++++++++++++++++++++ src/mbgl/geometry/sprite_atlas.hpp | 3 +++ src/mbgl/map/map.cpp | 11 +++++++++++ src/mbgl/map/map_context.cpp | 10 ++++++++++ src/mbgl/map/map_context.hpp | 3 +++ 6 files changed, 60 insertions(+) diff --git a/include/mbgl/map/map.hpp b/include/mbgl/map/map.hpp index e9d25bfe8..8178fab49 100644 --- a/include/mbgl/map/map.hpp +++ b/include/mbgl/map/map.hpp @@ -21,6 +21,7 @@ class View; class MapData; class MapContext; class StillImage; +class SpriteImage; class Transform; class PointAnnotation; class ShapeAnnotation; @@ -141,6 +142,10 @@ public: AnnotationIDs getAnnotationsInBounds(const LatLngBounds&, const AnnotationType& = AnnotationType::Any); LatLngBounds getBoundsForAnnotations(const AnnotationIDs&); + // Sprites + void setSprite(const std::string&, std::shared_ptr); + void removeSprite(const std::string&); + // Memory void setSourceTileCacheSize(size_t); void onLowMemory(); diff --git a/src/mbgl/geometry/sprite_atlas.cpp b/src/mbgl/geometry/sprite_atlas.cpp index 779afe288..7b77d7b35 100644 --- a/src/mbgl/geometry/sprite_atlas.cpp +++ b/src/mbgl/geometry/sprite_atlas.cpp @@ -170,6 +170,34 @@ void SpriteAtlas::upload() { } } +void SpriteAtlas::updateDirty() { + auto dirtySprites = store.getDirty(); + if (dirtySprites.empty()) { + return; + } + + std::lock_guard lock(mtx); + + auto imageIterator = images.begin(); + auto spriteIterator = dirtySprites.begin(); + while (imageIterator != images.end() && spriteIterator != dirtySprites.end()) { + if (imageIterator->first.first < spriteIterator->first) { + ++imageIterator; + } else if (spriteIterator->first < imageIterator->first.first) { + ++spriteIterator; + } else { + // The two names match; + Holder& holder = imageIterator->second; + holder.texture = spriteIterator->second; + copy(holder, imageIterator->first.second); + + ++imageIterator; + // Don't advance the spriteIterator because there might be another sprite with the same + // name, but a different wrap value. + } + } +} + void SpriteAtlas::bind(bool linear) { if (!texture) { MBGL_CHECK_ERROR(glGenTextures(1, &texture)); diff --git a/src/mbgl/geometry/sprite_atlas.hpp b/src/mbgl/geometry/sprite_atlas.hpp index c595d2ab7..e9653f6fa 100644 --- a/src/mbgl/geometry/sprite_atlas.hpp +++ b/src/mbgl/geometry/sprite_atlas.hpp @@ -54,6 +54,9 @@ public: // Binds the atlas texture to the GPU, and uploads data if it is out of date. void bind(bool linear = false); + // Updates sprites in the atlas texture that may have changed in the source SpriteStore object. + void updateDirty(); + // Uploads the texture to the GPU to be available when we need it. This is a lazy operation; // the texture is only bound when the data is out of date (=dirty). void upload(); diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index ca8303ec6..37cd3be33 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -346,6 +346,17 @@ LatLngBounds Map::getBoundsForAnnotations(const std::vector& annotatio } +#pragma mark - Sprites + +void Map::setSprite(const std::string& name, std::shared_ptr sprite) { + context->invoke(&MapContext::setSprite, name, sprite); +} + +void Map::removeSprite(const std::string& name) { + setSprite(name, nullptr); +} + + #pragma mark - Toggles void Map::setDebug(bool value) { diff --git a/src/mbgl/map/map_context.cpp b/src/mbgl/map/map_context.cpp index 05a046fdb..a27d7301a 100644 --- a/src/mbgl/map/map_context.cpp +++ b/src/mbgl/map/map_context.cpp @@ -13,6 +13,8 @@ #include #include +#include + #include #include #include @@ -373,6 +375,14 @@ void MapContext::onLowMemory() { view.invalidate(); } +void MapContext::setSprite(const std::string& name, std::shared_ptr sprite) { + if (!style) return; + + style->spriteStore->setSprite(name, sprite); + + style->spriteAtlas->updateDirty(); +} + void MapContext::onTileDataChanged() { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); asyncUpdate->send(); diff --git a/src/mbgl/map/map_context.hpp b/src/mbgl/map/map_context.hpp index 2c085c1aa..2e60d8eae 100644 --- a/src/mbgl/map/map_context.hpp +++ b/src/mbgl/map/map_context.hpp @@ -23,6 +23,7 @@ class Painter; class Sprite; class Worker; class StillImage; +class SpriteImage; struct LatLng; struct LatLngBounds; @@ -64,6 +65,8 @@ public: void cleanup(); + void setSprite(const std::string&, std::shared_ptr); + // Style::Observer implementation. void onTileDataChanged() override; void onResourceLoadingFailed(std::exception_ptr error) override;