diff options
21 files changed, 177 insertions, 231 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake index 4e1773eaac..fa681a03c4 100644 --- a/cmake/core-files.cmake +++ b/cmake/core-files.cmake @@ -62,8 +62,6 @@ set(MBGL_CORE_FILES src/mbgl/geometry/feature_index.hpp src/mbgl/geometry/fill_buffer.cpp src/mbgl/geometry/fill_buffer.hpp - src/mbgl/geometry/glyph_atlas.cpp - src/mbgl/geometry/glyph_atlas.hpp src/mbgl/geometry/icon_buffer.cpp src/mbgl/geometry/icon_buffer.hpp src/mbgl/geometry/line_atlas.cpp @@ -352,14 +350,14 @@ set(MBGL_CORE_FILES src/mbgl/text/get_anchors.hpp src/mbgl/text/glyph.cpp src/mbgl/text/glyph.hpp + src/mbgl/text/glyph_atlas.cpp + src/mbgl/text/glyph_atlas.hpp + src/mbgl/text/glyph_atlas_observer.hpp src/mbgl/text/glyph_pbf.cpp src/mbgl/text/glyph_pbf.hpp src/mbgl/text/glyph_range.hpp src/mbgl/text/glyph_set.cpp src/mbgl/text/glyph_set.hpp - src/mbgl/text/glyph_store.cpp - src/mbgl/text/glyph_store.hpp - src/mbgl/text/glyph_store_observer.hpp src/mbgl/text/placement_config.hpp src/mbgl/text/quads.cpp src/mbgl/text/quads.hpp diff --git a/cmake/test-files.cmake b/cmake/test-files.cmake index 23dc0b82ce..706d1bca59 100644 --- a/cmake/test-files.cmake +++ b/cmake/test-files.cmake @@ -74,7 +74,6 @@ set(MBGL_TEST_FILES # style test/style/filter.cpp test/style/functions.cpp - test/style/glyph_store.cpp test/style/source.cpp test/style/style.cpp test/style/style_layer.cpp @@ -82,6 +81,7 @@ set(MBGL_TEST_FILES test/style/tile_source.cpp # text + test/text/glyph_atlas.cpp test/text/quads.cpp # tile diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 277376a4e3..b25bb18ac4 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -4,9 +4,9 @@ #include <mbgl/renderer/symbol_bucket.hpp> #include <mbgl/style/filter_evaluator.hpp> #include <mbgl/sprite/sprite_atlas.hpp> -#include <mbgl/geometry/glyph_atlas.hpp> +#include <mbgl/text/glyph_atlas.hpp> #include <mbgl/text/get_anchors.hpp> -#include <mbgl/text/glyph_store.hpp> +#include <mbgl/text/glyph_atlas.hpp> #include <mbgl/text/collision_tile.hpp> #include <mbgl/util/utf.hpp> #include <mbgl/util/token.hpp> @@ -124,8 +124,8 @@ bool SymbolLayout::hasSymbolInstances() const { return !symbolInstances.empty(); } -bool SymbolLayout::canPrepare(GlyphStore& glyphStore) { - if (!layout.textField.value.empty() && !layout.textFont.value.empty() && !glyphStore.hasGlyphRanges(layout.textFont, ranges)) { +bool SymbolLayout::canPrepare(GlyphAtlas& glyphAtlas) { + if (!layout.textField.value.empty() && !layout.textFont.value.empty() && !glyphAtlas.hasGlyphRanges(layout.textFont, ranges)) { return false; } @@ -137,8 +137,7 @@ bool SymbolLayout::canPrepare(GlyphStore& glyphStore) { } void SymbolLayout::prepare(uintptr_t tileUID, - GlyphAtlas& glyphAtlas, - GlyphStore& glyphStore) { + GlyphAtlas& glyphAtlas) { float horizontalAlign = 0.5; float verticalAlign = 0.5; @@ -180,7 +179,7 @@ void SymbolLayout::prepare(uintptr_t tileUID, layout.textJustify == TextJustifyType::Left ? 0 : 0.5; - auto glyphSet = glyphStore.getGlyphSet(layout.textFont); + auto glyphSet = glyphAtlas.getGlyphSet(layout.textFont); for (const auto& feature : features) { if (feature.geometry.empty()) continue; diff --git a/src/mbgl/layout/symbol_layout.hpp b/src/mbgl/layout/symbol_layout.hpp index 000dacaf3a..db27f1b817 100644 --- a/src/mbgl/layout/symbol_layout.hpp +++ b/src/mbgl/layout/symbol_layout.hpp @@ -16,7 +16,6 @@ class GeometryTileLayer; class CollisionTile; class SpriteAtlas; class GlyphAtlas; -class GlyphStore; class SymbolBucket; namespace style { @@ -38,11 +37,10 @@ public: float textMaxSize, SpriteAtlas&); - bool canPrepare(GlyphStore&); + bool canPrepare(GlyphAtlas&); void prepare(uintptr_t tileUID, - GlyphAtlas&, - GlyphStore&); + GlyphAtlas&); std::unique_ptr<SymbolBucket> place(CollisionTile&); diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index c0357eda3e..915f83f01b 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -17,7 +17,7 @@ #include <mbgl/sprite/sprite_atlas.hpp> #include <mbgl/geometry/line_atlas.hpp> -#include <mbgl/geometry/glyph_atlas.hpp> +#include <mbgl/text/glyph_atlas.hpp> #include <mbgl/shader/shaders.hpp> diff --git a/src/mbgl/renderer/painter_symbol.cpp b/src/mbgl/renderer/painter_symbol.cpp index aa5d4f0d9b..dbc27038a0 100644 --- a/src/mbgl/renderer/painter_symbol.cpp +++ b/src/mbgl/renderer/painter_symbol.cpp @@ -4,7 +4,7 @@ #include <mbgl/renderer/render_tile.hpp> #include <mbgl/style/layers/symbol_layer.hpp> #include <mbgl/style/layers/symbol_layer_impl.hpp> -#include <mbgl/geometry/glyph_atlas.hpp> +#include <mbgl/text/glyph_atlas.hpp> #include <mbgl/sprite/sprite_atlas.hpp> #include <mbgl/shader/shaders.hpp> #include <mbgl/util/math.hpp> diff --git a/src/mbgl/style/bucket_parameters.hpp b/src/mbgl/style/bucket_parameters.hpp index 14fda41b8d..9aad35dcad 100644 --- a/src/mbgl/style/bucket_parameters.hpp +++ b/src/mbgl/style/bucket_parameters.hpp @@ -13,7 +13,6 @@ class TileID; class GeometryTileLayer; class GeometryTileFeature; class GlyphAtlas; -class GlyphStore; class CollisionTile; class FeatureIndex; @@ -26,7 +25,6 @@ public: const std::atomic<bool>& obsolete_, uintptr_t tileUID_, GlyphAtlas& glyphAtlas_, - GlyphStore& glyphStore_, FeatureIndex& featureIndex_, const MapMode mode_) : tileID(tileID_), @@ -34,7 +32,6 @@ public: obsolete(obsolete_), tileUID(tileUID_), glyphAtlas(glyphAtlas_), - glyphStore(glyphStore_), featureIndex(featureIndex_), mode(mode_) {} @@ -49,7 +46,6 @@ public: const std::atomic<bool>& obsolete; uintptr_t tileUID; GlyphAtlas& glyphAtlas; - GlyphStore& glyphStore; FeatureIndex& featureIndex; const MapMode mode; }; diff --git a/src/mbgl/style/observer.hpp b/src/mbgl/style/observer.hpp index 799d15dff0..6694819bca 100644 --- a/src/mbgl/style/observer.hpp +++ b/src/mbgl/style/observer.hpp @@ -1,6 +1,6 @@ #pragma once -#include <mbgl/text/glyph_store_observer.hpp> +#include <mbgl/text/glyph_atlas_observer.hpp> #include <mbgl/sprite/sprite_atlas_observer.hpp> #include <mbgl/style/source_observer.hpp> #include <mbgl/map/update.hpp> @@ -8,7 +8,7 @@ namespace mbgl { namespace style { -class Observer : public GlyphStoreObserver, +class Observer : public GlyphAtlasObserver, public SpriteAtlasObserver, public SourceObserver { public: diff --git a/src/mbgl/style/style.cpp b/src/mbgl/style/style.cpp index 3d045bf1b7..e519238637 100644 --- a/src/mbgl/style/style.cpp +++ b/src/mbgl/style/style.cpp @@ -19,7 +19,7 @@ #include <mbgl/style/cascade_parameters.hpp> #include <mbgl/style/calculation_parameters.hpp> #include <mbgl/sprite/sprite_atlas.hpp> -#include <mbgl/geometry/glyph_atlas.hpp> +#include <mbgl/text/glyph_atlas.hpp> #include <mbgl/geometry/line_atlas.hpp> #include <mbgl/renderer/render_item.hpp> #include <mbgl/renderer/render_tile.hpp> @@ -37,12 +37,11 @@ static Observer nullObserver; Style::Style(FileSource& fileSource_, float pixelRatio) : fileSource(fileSource_), - glyphStore(std::make_unique<GlyphStore>(fileSource)), - glyphAtlas(std::make_unique<GlyphAtlas>(2048, 2048)), + glyphAtlas(std::make_unique<GlyphAtlas>(2048, 2048, fileSource)), spriteAtlas(std::make_unique<SpriteAtlas>(1024, 1024, pixelRatio)), lineAtlas(std::make_unique<LineAtlas>(256, 512)), observer(&nullObserver) { - glyphStore->setObserver(this); + glyphAtlas->setObserver(this); spriteAtlas->setObserver(this); } @@ -51,7 +50,7 @@ Style::~Style() { source->baseImpl->setObserver(nullptr); } - glyphStore->setObserver(nullptr); + glyphAtlas->setObserver(nullptr); spriteAtlas->setObserver(nullptr); } @@ -122,7 +121,7 @@ void Style::setJSON(const std::string& json) { defaultBearing = parser.bearing; defaultPitch = parser.pitch; - glyphStore->setURL(parser.glyphURL); + glyphAtlas->setURL(parser.glyphURL); spriteAtlas->load(parser.spriteURL, fileSource); loaded = true; diff --git a/src/mbgl/style/style.hpp b/src/mbgl/style/style.hpp index 2621e53c45..a3c51a45e7 100644 --- a/src/mbgl/style/style.hpp +++ b/src/mbgl/style/style.hpp @@ -5,7 +5,7 @@ #include <mbgl/style/source_observer.hpp> #include <mbgl/style/layer_observer.hpp> #include <mbgl/style/update_batch.hpp> -#include <mbgl/text/glyph_store_observer.hpp> +#include <mbgl/text/glyph_atlas_observer.hpp> #include <mbgl/sprite/sprite_atlas_observer.hpp> #include <mbgl/map/mode.hpp> #include <mbgl/map/zoom_history.hpp> @@ -24,7 +24,6 @@ namespace mbgl { class FileSource; -class GlyphStore; class GlyphAtlas; class SpriteAtlas; class LineAtlas; @@ -36,7 +35,7 @@ class Layer; class UpdateParameters; class QueryParameters; -class Style : public GlyphStoreObserver, +class Style : public GlyphAtlasObserver, public SpriteAtlasObserver, public SourceObserver, public LayerObserver, @@ -103,7 +102,6 @@ public: void dumpDebugLogs() const; FileSource& fileSource; - std::unique_ptr<GlyphStore> glyphStore; std::unique_ptr<GlyphAtlas> glyphAtlas; std::unique_ptr<SpriteAtlas> spriteAtlas; std::unique_ptr<LineAtlas> lineAtlas; diff --git a/src/mbgl/geometry/glyph_atlas.cpp b/src/mbgl/text/glyph_atlas.cpp index ff62c5b897..9e92e3e81e 100644 --- a/src/mbgl/geometry/glyph_atlas.cpp +++ b/src/mbgl/text/glyph_atlas.cpp @@ -1,5 +1,6 @@ -#include <mbgl/geometry/glyph_atlas.hpp> - +#include <mbgl/text/glyph_atlas.hpp> +#include <mbgl/text/glyph_atlas_observer.hpp> +#include <mbgl/text/glyph_pbf.hpp> #include <mbgl/gl/gl.hpp> #include <mbgl/gl/object_store.hpp> #include <mbgl/gl/gl_config.hpp> @@ -9,12 +10,15 @@ #include <cassert> #include <algorithm> - namespace mbgl { -GlyphAtlas::GlyphAtlas(uint16_t width_, uint16_t height_) +static GlyphAtlasObserver nullObserver; + +GlyphAtlas::GlyphAtlas(uint16_t width_, uint16_t height_, FileSource& fileSource_) : width(width_), height(height_), + fileSource(fileSource_), + observer(&nullObserver), bin(width_, height_), data(std::make_unique<uint8_t[]>(width_ * height_)), dirty(true) { @@ -22,6 +26,64 @@ GlyphAtlas::GlyphAtlas(uint16_t width_, uint16_t height_) GlyphAtlas::~GlyphAtlas() = default; +void GlyphAtlas::requestGlyphRange(const FontStack& fontStack, const GlyphRange& range) { + std::lock_guard<std::mutex> lock(rangesMutex); + auto& rangeSets = ranges[fontStack]; + + const auto& rangeSetsIt = rangeSets.find(range); + if (rangeSetsIt != rangeSets.end()) { + return; + } + + rangeSets.emplace(range, + std::make_unique<GlyphPBF>(this, fontStack, range, observer, fileSource)); +} + +bool GlyphAtlas::hasGlyphRanges(const FontStack& fontStack, const std::set<GlyphRange>& glyphRanges) { + if (glyphRanges.empty()) { + return true; + } + + std::lock_guard<std::mutex> lock(rangesMutex); + const auto& rangeSets = ranges[fontStack]; + + bool hasRanges = true; + for (const auto& range : glyphRanges) { + const auto& rangeSetsIt = rangeSets.find(range); + if (rangeSetsIt == rangeSets.end()) { + // Push the request to the MapThread, so we can easly cancel + // if it is still pending when we destroy this object. + workQueue.push(std::bind(&GlyphAtlas::requestGlyphRange, this, fontStack, range)); + + hasRanges = false; + continue; + } + + if (!rangeSetsIt->second->isParsed()) { + hasRanges = false; + } + } + + return hasRanges; +} + +util::exclusive<GlyphSet> GlyphAtlas::getGlyphSet(const FontStack& fontStack) { + auto lock = std::make_unique<std::lock_guard<std::mutex>>(glyphSetsMutex); + + auto it = glyphSets.find(fontStack); + if (it == glyphSets.end()) { + it = glyphSets.emplace(fontStack, std::make_unique<GlyphSet>()).first; + } + + // FIXME: We lock all GlyphSets, but what we should + // really do is lock only the one we are returning. + return { it->second.get(), std::move(lock) }; +} + +void GlyphAtlas::setObserver(GlyphAtlasObserver* observer_) { + observer = observer_; +} + void GlyphAtlas::addGlyphs(uintptr_t tileUID, const std::u32string& text, const FontStack& fontStack, diff --git a/src/mbgl/geometry/glyph_atlas.hpp b/src/mbgl/text/glyph_atlas.hpp index b9170c1caf..ca88d16f8b 100644 --- a/src/mbgl/geometry/glyph_atlas.hpp +++ b/src/mbgl/text/glyph_atlas.hpp @@ -1,9 +1,13 @@ #pragma once +#include <mbgl/text/glyph.hpp> +#include <mbgl/text/glyph_set.hpp> #include <mbgl/geometry/binpack.hpp> -#include <mbgl/text/glyph_store.hpp> #include <mbgl/util/noncopyable.hpp> #include <mbgl/util/optional.hpp> +#include <mbgl/util/font_stack.hpp> +#include <mbgl/util/exclusive.hpp> +#include <mbgl/util/work_queue.hpp> #include <mbgl/gl/gl.hpp> #include <mbgl/gl/object_store.hpp> @@ -12,18 +16,43 @@ #include <set> #include <unordered_map> #include <mutex> +#include <exception> +#include <vector> namespace mbgl { +class FileSource; +class GlyphPBF; +class GlyphAtlasObserver; + namespace gl { class Config; } // namespace gl class GlyphAtlas : public util::noncopyable { public: - GlyphAtlas(uint16_t width, uint16_t height); + GlyphAtlas(uint16_t width, uint16_t height, FileSource&); ~GlyphAtlas(); + util::exclusive<GlyphSet> getGlyphSet(const FontStack&); + + // Returns true if the set of GlyphRanges are available and parsed or false + // if they are not. For the missing ranges, a request on the FileSource is + // made and when the glyph if finally parsed, it gets added to the respective + // GlyphSet and a signal is emitted to notify the observers. This method + // can be called from any thread. + bool hasGlyphRanges(const FontStack&, const std::set<GlyphRange>&); + + void setURL(const std::string &url) { + glyphURL = url; + } + + std::string getURL() const { + return glyphURL; + } + + void setObserver(GlyphAtlasObserver* observer); + void addGlyphs(uintptr_t tileUID, const std::u32string& text, const FontStack&, @@ -42,6 +71,26 @@ public: const GLsizei height; private: + void requestGlyphRange(const FontStack&, const GlyphRange&); + + Rect<uint16_t> addGlyph(uintptr_t tileID, + const FontStack&, + const SDFGlyph&); + + + FileSource& fileSource; + std::string glyphURL; + + std::unordered_map<FontStack, std::map<GlyphRange, std::unique_ptr<GlyphPBF>>, FontStackHash> ranges; + std::mutex rangesMutex; + + std::unordered_map<FontStack, std::unique_ptr<GlyphSet>, FontStackHash> glyphSets; + std::mutex glyphSetsMutex; + + util::WorkQueue workQueue; + + GlyphAtlasObserver* observer = nullptr; + struct GlyphValue { GlyphValue(Rect<uint16_t> rect_, uintptr_t id) : rect(std::move(rect_)), ids({ id }) {} @@ -49,10 +98,6 @@ private: std::set<uintptr_t> ids; }; - Rect<uint16_t> addGlyph(uintptr_t tileID, - const FontStack&, - const SDFGlyph&); - std::mutex mtx; BinPack<uint16_t> bin; std::unordered_map<FontStack, std::map<uint32_t, GlyphValue>, FontStackHash> index; diff --git a/src/mbgl/text/glyph_store_observer.hpp b/src/mbgl/text/glyph_atlas_observer.hpp index 39f10cd812..9841017117 100644 --- a/src/mbgl/text/glyph_store_observer.hpp +++ b/src/mbgl/text/glyph_atlas_observer.hpp @@ -8,9 +8,9 @@ namespace mbgl { -class GlyphStoreObserver { +class GlyphAtlasObserver { public: - virtual ~GlyphStoreObserver() = default; + virtual ~GlyphAtlasObserver() = default; virtual void onGlyphsLoaded(const FontStack&, const GlyphRange&) {} virtual void onGlyphsError(const FontStack&, const GlyphRange&, std::exception_ptr) {} diff --git a/src/mbgl/text/glyph_pbf.cpp b/src/mbgl/text/glyph_pbf.cpp index b4dac4ce01..21edfe436c 100644 --- a/src/mbgl/text/glyph_pbf.cpp +++ b/src/mbgl/text/glyph_pbf.cpp @@ -1,10 +1,10 @@ #include <mbgl/text/glyph_pbf.hpp> - +#include <mbgl/text/glyph_atlas.hpp> +#include <mbgl/text/glyph_atlas_observer.hpp> +#include <mbgl/text/glyph_set.hpp> #include <mbgl/storage/file_source.hpp> #include <mbgl/storage/resource.hpp> #include <mbgl/storage/response.hpp> -#include <mbgl/text/glyph_store_observer.hpp> -#include <mbgl/text/glyph_set.hpp> #include <mbgl/util/exception.hpp> #include <mbgl/util/string.hpp> #include <mbgl/util/token.hpp> @@ -62,14 +62,14 @@ void parseGlyphPBF(mbgl::GlyphSet& glyphSet, const std::string& data) { namespace mbgl { -GlyphPBF::GlyphPBF(GlyphStore* store, +GlyphPBF::GlyphPBF(GlyphAtlas* atlas, const FontStack& fontStack, const GlyphRange& glyphRange, - GlyphStoreObserver* observer_, + GlyphAtlasObserver* observer_, FileSource& fileSource) : parsed(false), observer(observer_) { - req = fileSource.request(Resource::glyphs(store->getURL(), fontStack, glyphRange), [this, store, fontStack, glyphRange](Response res) { + req = fileSource.request(Resource::glyphs(atlas->getURL(), fontStack, glyphRange), [this, atlas, fontStack, glyphRange](Response res) { if (res.error) { observer->onGlyphsError(fontStack, glyphRange, std::make_exception_ptr(std::runtime_error(res.error->message))); } else if (res.notModified) { @@ -79,7 +79,7 @@ GlyphPBF::GlyphPBF(GlyphStore* store, observer->onGlyphsLoaded(fontStack, glyphRange); } else { try { - parseGlyphPBF(**store->getGlyphSet(fontStack), *res.data); + parseGlyphPBF(**atlas->getGlyphSet(fontStack), *res.data); } catch (...) { observer->onGlyphsError(fontStack, glyphRange, std::current_exception()); return; diff --git a/src/mbgl/text/glyph_pbf.hpp b/src/mbgl/text/glyph_pbf.hpp index 85f4b62e6f..7412ebe411 100644 --- a/src/mbgl/text/glyph_pbf.hpp +++ b/src/mbgl/text/glyph_pbf.hpp @@ -1,7 +1,6 @@ #pragma once #include <mbgl/text/glyph.hpp> -#include <mbgl/text/glyph_store.hpp> #include <mbgl/util/font_stack.hpp> #include <mbgl/util/noncopyable.hpp> @@ -12,15 +11,17 @@ namespace mbgl { +class GlyphAtlas; +class GlyphAtlasObserver; class AsyncRequest; class FileSource; class GlyphPBF : private util::noncopyable { public: - GlyphPBF(GlyphStore*, + GlyphPBF(GlyphAtlas*, const FontStack&, const GlyphRange&, - GlyphStoreObserver*, + GlyphAtlasObserver*, FileSource&); ~GlyphPBF(); @@ -31,7 +32,7 @@ public: private: std::atomic<bool> parsed; std::unique_ptr<AsyncRequest> req; - GlyphStoreObserver* observer = nullptr; + GlyphAtlasObserver* observer = nullptr; }; } // namespace mbgl diff --git a/src/mbgl/text/glyph_store.cpp b/src/mbgl/text/glyph_store.cpp deleted file mode 100644 index 8ed2eeace5..0000000000 --- a/src/mbgl/text/glyph_store.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include <mbgl/text/glyph_store.hpp> -#include <mbgl/text/glyph_store_observer.hpp> -#include <mbgl/text/glyph_pbf.hpp> - -#include <cassert> - -namespace mbgl { - -static GlyphStoreObserver nullObserver; - -GlyphStore::GlyphStore(FileSource& fileSource_) - : fileSource(fileSource_), observer(&nullObserver) { -} - -GlyphStore::~GlyphStore() = default; - -void GlyphStore::requestGlyphRange(const FontStack& fontStack, const GlyphRange& range) { - std::lock_guard<std::mutex> lock(rangesMutex); - auto& rangeSets = ranges[fontStack]; - - const auto& rangeSetsIt = rangeSets.find(range); - if (rangeSetsIt != rangeSets.end()) { - return; - } - - rangeSets.emplace(range, - std::make_unique<GlyphPBF>(this, fontStack, range, observer, fileSource)); -} - - -bool GlyphStore::hasGlyphRanges(const FontStack& fontStack, const std::set<GlyphRange>& glyphRanges) { - if (glyphRanges.empty()) { - return true; - } - - std::lock_guard<std::mutex> lock(rangesMutex); - const auto& rangeSets = ranges[fontStack]; - - bool hasRanges = true; - for (const auto& range : glyphRanges) { - const auto& rangeSetsIt = rangeSets.find(range); - if (rangeSetsIt == rangeSets.end()) { - // Push the request to the MapThread, so we can easly cancel - // if it is still pending when we destroy this object. - workQueue.push(std::bind(&GlyphStore::requestGlyphRange, this, fontStack, range)); - - hasRanges = false; - continue; - } - - if (!rangeSetsIt->second->isParsed()) { - hasRanges = false; - } - } - - return hasRanges; -} - -util::exclusive<GlyphSet> GlyphStore::getGlyphSet(const FontStack& fontStack) { - auto lock = std::make_unique<std::lock_guard<std::mutex>>(glyphSetsMutex); - - auto it = glyphSets.find(fontStack); - if (it == glyphSets.end()) { - it = glyphSets.emplace(fontStack, std::make_unique<GlyphSet>()).first; - } - - // FIXME: We lock all GlyphSets, but what we should - // really do is lock only the one we are returning. - return { it->second.get(), std::move(lock) }; -} - -void GlyphStore::setObserver(GlyphStoreObserver* observer_) { - observer = observer_; -} - -} // namespace mbgl diff --git a/src/mbgl/text/glyph_store.hpp b/src/mbgl/text/glyph_store.hpp deleted file mode 100644 index edc89b4894..0000000000 --- a/src/mbgl/text/glyph_store.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#pragma once - -#include <mbgl/text/glyph.hpp> -#include <mbgl/text/glyph_set.hpp> -#include <mbgl/util/font_stack.hpp> -#include <mbgl/util/exclusive.hpp> -#include <mbgl/util/noncopyable.hpp> -#include <mbgl/util/work_queue.hpp> - -#include <exception> -#include <vector> -#include <set> -#include <string> -#include <unordered_map> - -namespace mbgl { - -class FileSource; -class GlyphPBF; -class GlyphStoreObserver; - -// The GlyphStore manages the loading and storage of Glyphs -// and creation of GlyphSet objects. The GlyphStore lives -// on the MapThread but can be queried from any thread. -class GlyphStore : private util::noncopyable { -public: - GlyphStore(FileSource&); - ~GlyphStore(); - - util::exclusive<GlyphSet> getGlyphSet(const FontStack&); - - // Returns true if the set of GlyphRanges are available and parsed or false - // if they are not. For the missing ranges, a request on the FileSource is - // made and when the glyph if finally parsed, it gets added to the respective - // GlyphSet and a signal is emitted to notify the observers. This method - // can be called from any thread. - bool hasGlyphRanges(const FontStack&, const std::set<GlyphRange>&); - - void setURL(const std::string &url) { - glyphURL = url; - } - - std::string getURL() const { - return glyphURL; - } - - void setObserver(GlyphStoreObserver* observer); - -private: - void requestGlyphRange(const FontStack&, const GlyphRange&); - - FileSource& fileSource; - std::string glyphURL; - - std::unordered_map<FontStack, std::map<GlyphRange, std::unique_ptr<GlyphPBF>>, FontStackHash> ranges; - std::mutex rangesMutex; - - std::unordered_map<FontStack, std::unique_ptr<GlyphSet>, FontStackHash> glyphSets; - std::mutex glyphSetsMutex; - - util::WorkQueue workQueue; - - GlyphStoreObserver* observer = nullptr; -}; - -} // namespace mbgl diff --git a/src/mbgl/tile/geometry_tile.cpp b/src/mbgl/tile/geometry_tile.cpp index 36919517a2..ef40ea8e70 100644 --- a/src/mbgl/tile/geometry_tile.cpp +++ b/src/mbgl/tile/geometry_tile.cpp @@ -28,7 +28,6 @@ GeometryTile::GeometryTile(const OverscaledTileID& id_, ActorRef<GeometryTile>(*this, mailbox), id_, *parameters.style.glyphAtlas, - *parameters.style.glyphStore, obsolete, parameters.mode) { } diff --git a/src/mbgl/tile/geometry_tile_worker.cpp b/src/mbgl/tile/geometry_tile_worker.cpp index 927cd0c2a1..6d26d85093 100644 --- a/src/mbgl/tile/geometry_tile_worker.cpp +++ b/src/mbgl/tile/geometry_tile_worker.cpp @@ -2,11 +2,11 @@ #include <mbgl/tile/geometry_tile_data.hpp> #include <mbgl/tile/geometry_tile.hpp> #include <mbgl/text/collision_tile.hpp> +#include <mbgl/text/glyph_atlas.hpp> #include <mbgl/layout/symbol_layout.hpp> #include <mbgl/style/bucket_parameters.hpp> #include <mbgl/style/layers/symbol_layer.hpp> #include <mbgl/style/layers/symbol_layer_impl.hpp> -#include <mbgl/geometry/glyph_atlas.hpp> #include <mbgl/renderer/symbol_bucket.hpp> #include <mbgl/platform/log.hpp> #include <mbgl/util/constants.hpp> @@ -23,14 +23,12 @@ GeometryTileWorker::GeometryTileWorker(ActorRef<GeometryTileWorker> self_, ActorRef<GeometryTile> parent_, OverscaledTileID id_, GlyphAtlas& glyphAtlas_, - GlyphStore& glyphStore_, const std::atomic<bool>& obsolete_, const MapMode mode_) : self(std::move(self_)), parent(std::move(parent_)), id(std::move(id_)), glyphAtlas(glyphAtlas_), - glyphStore(glyphStore_), obsolete(obsolete_), mode(mode_) { } @@ -217,7 +215,6 @@ void GeometryTileWorker::redoLayout() { obsolete, reinterpret_cast<uintptr_t>(this), glyphAtlas, - glyphStore, *featureIndex, mode); @@ -255,11 +252,10 @@ void GeometryTileWorker::attemptPlacement() { } if (symbolLayout->state == SymbolLayout::Pending) { - if (symbolLayout->canPrepare(glyphStore)) { + if (symbolLayout->canPrepare(glyphAtlas)) { symbolLayout->state = SymbolLayout::Prepared; symbolLayout->prepare(reinterpret_cast<uintptr_t>(this), - glyphAtlas, - glyphStore); + glyphAtlas); } else { canPlace = false; } diff --git a/src/mbgl/tile/geometry_tile_worker.hpp b/src/mbgl/tile/geometry_tile_worker.hpp index 362021fa4f..d55b29702c 100644 --- a/src/mbgl/tile/geometry_tile_worker.hpp +++ b/src/mbgl/tile/geometry_tile_worker.hpp @@ -15,7 +15,6 @@ namespace mbgl { class GeometryTile; class GeometryTileData; class GlyphAtlas; -class GlyphStore; class SymbolLayout; namespace style { @@ -28,7 +27,6 @@ public: ActorRef<GeometryTile> parent, OverscaledTileID, GlyphAtlas&, - GlyphStore&, const std::atomic<bool>&, const MapMode); ~GeometryTileWorker(); @@ -48,7 +46,6 @@ private: const OverscaledTileID id; GlyphAtlas& glyphAtlas; - GlyphStore& glyphStore; const std::atomic<bool>& obsolete; const MapMode mode; diff --git a/test/style/glyph_store.cpp b/test/text/glyph_atlas.cpp index 08ec6902b9..27d43a1721 100644 --- a/test/style/glyph_store.cpp +++ b/test/text/glyph_atlas.cpp @@ -3,7 +3,7 @@ #include <mbgl/test/stub_style_observer.hpp> #include <mbgl/text/glyph_set.hpp> -#include <mbgl/text/glyph_store.hpp> +#include <mbgl/text/glyph_atlas.hpp> #include <mbgl/util/run_loop.hpp> #include <mbgl/util/string.hpp> #include <mbgl/util/io.hpp> @@ -11,20 +11,20 @@ using namespace mbgl; -class GlyphStoreTest { +class GlyphAtlasTest { public: util::RunLoop loop; StubFileSource fileSource; StubStyleObserver observer; - GlyphStore glyphStore { fileSource }; + GlyphAtlas glyphAtlas { 32, 32, fileSource }; void run(const std::string& url, const FontStack& fontStack, const std::set<GlyphRange>& glyphRanges) { // Squelch logging. Log::setObserver(std::make_unique<Log::NullObserver>()); - glyphStore.setObserver(&observer); - glyphStore.setURL(url); - glyphStore.hasGlyphRanges(fontStack, glyphRanges); + glyphAtlas.setObserver(&observer); + glyphAtlas.setURL(url); + glyphAtlas.hasGlyphRanges(fontStack, glyphRanges); loop.run(); } @@ -34,8 +34,8 @@ public: } }; -TEST(GlyphStore, LoadingSuccess) { - GlyphStoreTest test; +TEST(GlyphAtlas, LoadingSuccess) { + GlyphAtlasTest test; test.fileSource.glyphsResponse = [&] (const Resource& resource) { EXPECT_EQ(Resource::Kind::Glyphs, resource.kind); @@ -50,10 +50,10 @@ TEST(GlyphStore, LoadingSuccess) { }; test.observer.glyphsLoaded = [&] (const FontStack&, const GlyphRange&) { - if (!test.glyphStore.hasGlyphRanges({{"Test Stack"}}, {{0, 255}, {256, 511}})) + if (!test.glyphAtlas.hasGlyphRanges({{"Test Stack"}}, {{0, 255}, {256, 511}})) return; - auto glyphSet = test.glyphStore.getGlyphSet({{"Test Stack"}}); + auto glyphSet = test.glyphAtlas.getGlyphSet({{"Test Stack"}}); ASSERT_FALSE(glyphSet->getSDFs().empty()); test.end(); @@ -65,8 +65,8 @@ TEST(GlyphStore, LoadingSuccess) { {{0, 255}, {256, 511}}); } -TEST(GlyphStore, LoadingFail) { - GlyphStoreTest test; +TEST(GlyphAtlas, LoadingFail) { + GlyphAtlasTest test; test.fileSource.glyphsResponse = [&] (const Resource&) { Response response; @@ -83,9 +83,9 @@ TEST(GlyphStore, LoadingFail) { EXPECT_TRUE(error != nullptr); EXPECT_EQ(util::toString(error), "Failed by the test case"); - auto glyphSet = test.glyphStore.getGlyphSet({{"Test Stack"}}); + auto glyphSet = test.glyphAtlas.getGlyphSet({{"Test Stack"}}); ASSERT_TRUE(glyphSet->getSDFs().empty()); - ASSERT_FALSE(test.glyphStore.hasGlyphRanges({{"Test Stack"}}, {{0, 255}})); + ASSERT_FALSE(test.glyphAtlas.hasGlyphRanges({{"Test Stack"}}, {{0, 255}})); test.end(); }; @@ -96,8 +96,8 @@ TEST(GlyphStore, LoadingFail) { {{0, 255}}); } -TEST(GlyphStore, LoadingCorrupted) { - GlyphStoreTest test; +TEST(GlyphAtlas, LoadingCorrupted) { + GlyphAtlasTest test; test.fileSource.glyphsResponse = [&] (const Resource&) { Response response; @@ -112,9 +112,9 @@ TEST(GlyphStore, LoadingCorrupted) { EXPECT_TRUE(error != nullptr); EXPECT_EQ(util::toString(error), "unknown pbf field type exception"); - auto glyphSet = test.glyphStore.getGlyphSet({{"Test Stack"}}); + auto glyphSet = test.glyphAtlas.getGlyphSet({{"Test Stack"}}); ASSERT_TRUE(glyphSet->getSDFs().empty()); - ASSERT_FALSE(test.glyphStore.hasGlyphRanges({{"Test Stack"}}, {{0, 255}})); + ASSERT_FALSE(test.glyphAtlas.hasGlyphRanges({{"Test Stack"}}, {{0, 255}})); test.end(); }; @@ -125,8 +125,8 @@ TEST(GlyphStore, LoadingCorrupted) { {{0, 255}}); } -TEST(GlyphStore, LoadingCancel) { - GlyphStoreTest test; +TEST(GlyphAtlas, LoadingCancel) { + GlyphAtlasTest test; test.fileSource.glyphsResponse = [&] (const Resource&) { test.end(); |