diff options
author | Chris Loer <chris.loer@gmail.com> | 2017-03-31 14:53:18 -0700 |
---|---|---|
committer | Chris Loer <chris.loer@mapbox.com> | 2017-04-04 11:33:12 -0700 |
commit | 5cdf838a387cae446dba500ac49a1c5524bf7949 (patch) | |
tree | 3b438034a7842c36a7804096785fca1a6ad6fa80 /src/mbgl/text/glyph_atlas.hpp | |
parent | 64beba3accb0f2088b2e01fad710f915c81d99c7 (diff) | |
download | qtlocation-mapboxgl-5cdf838a387cae446dba500ac49a1c5524bf7949.tar.gz |
[core] De-mutex GlyphAtlas and SpriteAtlas
- Expose glyph and icon information to workers via message interface.
- Glyph/SpriteAtlas track which tiles have outstanding requests
and send messages to them when glyphs/icons become available.
- Remove obsolete "updateSymbolDependentTiles" pathway
- Symbol preparation for a tile now depends on all glyphs becoming
available before it can start.
- Start tracking individual icons needed for a tile, although we don't
do anything with the information yet.
- Introduce typedef for GlyphID
Diffstat (limited to 'src/mbgl/text/glyph_atlas.hpp')
-rw-r--r-- | src/mbgl/text/glyph_atlas.hpp | 68 |
1 files changed, 40 insertions, 28 deletions
diff --git a/src/mbgl/text/glyph_atlas.hpp b/src/mbgl/text/glyph_atlas.hpp index 8267630096..120f19accc 100644 --- a/src/mbgl/text/glyph_atlas.hpp +++ b/src/mbgl/text/glyph_atlas.hpp @@ -1,46 +1,55 @@ #pragma once #include <mbgl/text/glyph.hpp> +#include <mbgl/text/glyph_atlas_observer.hpp> +#include <mbgl/text/glyph_range.hpp> #include <mbgl/text/glyph_set.hpp> #include <mbgl/geometry/binpack.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/util/image.hpp> #include <mbgl/gl/texture.hpp> #include <mbgl/gl/object.hpp> -#include <atomic> #include <string> #include <unordered_set> #include <unordered_map> -#include <mutex> + +class GlyphAtlasTest; namespace mbgl { class FileSource; class GlyphPBF; -class GlyphAtlasObserver; namespace gl { class Context; } // namespace gl -class GlyphAtlas : public util::noncopyable { +class GlyphRequestor { +public: + virtual void onGlyphsAvailable(GlyphPositionMap, GlyphRangeSet) = 0; +}; + +class GlyphAtlas : public util::noncopyable, public GlyphAtlasObserver { public: GlyphAtlas(Size, 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 GlyphRangeSet&); + GlyphSet& getGlyphSet(const FontStack&); + + // Workers send a `getGlyphs` message to the main thread once they have determined + // which glyphs they will need. Invoking this method will increment reference + // counts for all the glyphs in `GlyphDependencies`. If all glyphs are already + // locally available, the observer will be notified that the glyphs are available + // immediately. Otherwise, a request on the FileSource is made, and when all glyphs + // are parsed and added to the atlas, the observer will be notified. + // Workers are given a copied 'GlyphPositions' map to use for placing their glyphs. + // The positions specified in this object are guaranteed to be + // valid for the lifetime of the tile. + void getGlyphs(GlyphRequestor& requestor, GlyphDependencies glyphs); void setURL(const std::string &url) { glyphURL = url; @@ -52,12 +61,7 @@ public: void setObserver(GlyphAtlasObserver* observer); - void addGlyphs(uintptr_t tileUID, - const std::u16string& text, - const FontStack&, - const util::exclusive<GlyphSet>&, - GlyphPositions&); - void removeGlyphs(uintptr_t tileUID); + void removeGlyphs(GlyphRequestor&); // Binds the atlas texture to the GPU, and uploads data if it is out of date. void bind(gl::Context&, gl::TextureUnit unit); @@ -67,22 +71,29 @@ public: void upload(gl::Context&, gl::TextureUnit unit); Size getSize() const; + + virtual void onGlyphsLoaded(const FontStack&, const GlyphRange&); + virtual void onGlyphsError(const FontStack&, const GlyphRange&, std::exception_ptr); + + friend class ::GlyphAtlasTest; private: - void requestGlyphRange(const FontStack&, const GlyphRange&); + void addGlyphs(GlyphRequestor& requestor, const GlyphDependencies& glyphDependencies); - Rect<uint16_t> addGlyph(uintptr_t tileID, - const FontStack&, - const SDFGlyph&); + // Only used by GlyphAtlasTest + bool hasGlyphRanges(const FontStack&, const GlyphRangeSet& ranges) const; + bool hasGlyphRange(const FontStack&, const GlyphRange& range) const; + void addGlyph(GlyphRequestor& requestor, const FontStack&, const SDFGlyph&); + FileSource& fileSource; std::string glyphURL; struct GlyphValue { - GlyphValue(Rect<uint16_t> rect_, uintptr_t id) + GlyphValue(Rect<uint16_t> rect_, GlyphRequestor* id) : rect(std::move(rect_)), ids({ id }) {} Rect<uint16_t> rect; - std::unordered_set<uintptr_t> ids; + std::unordered_set<GlyphRequestor*> ids; }; struct Entry { @@ -92,14 +103,15 @@ private: }; std::unordered_map<FontStack, Entry, FontStackHash> entries; - std::mutex mutex; + + void removeGlyphValues(GlyphRequestor& requestor, std::map<uint32_t, GlyphValue>& face); + void removePendingRanges(GlyphRequestor& requestor, std::map<GlyphRange, GlyphPBF>& ranges); - util::WorkQueue workQueue; GlyphAtlasObserver* observer = nullptr; BinPack<uint16_t> bin; AlphaImage image; - std::atomic<bool> dirty; + bool dirty; mbgl::optional<gl::Texture> texture; }; |