summaryrefslogtreecommitdiff
path: root/src/mbgl/text/glyph_atlas.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/text/glyph_atlas.hpp')
-rw-r--r--src/mbgl/text/glyph_atlas.hpp68
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;
};