diff options
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..e40f1b5147 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) = 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; }; |