summaryrefslogtreecommitdiff
path: root/src/mbgl/text/glyph_atlas.hpp
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2016-09-15 17:03:13 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2016-09-19 09:40:43 -0700
commitdc1861f6d5391707126a20dbb0272f5bd3522de8 (patch)
tree961a3612706b9466d9ff0ef278ae1206b821aa88 /src/mbgl/text/glyph_atlas.hpp
parent940124ff713a960d7f70071779dd37d07010fa80 (diff)
downloadqtlocation-mapboxgl-dc1861f6d5391707126a20dbb0272f5bd3522de8.tar.gz
[core] Merge GlyphStore and GlyphAtlas
Diffstat (limited to 'src/mbgl/text/glyph_atlas.hpp')
-rw-r--r--src/mbgl/text/glyph_atlas.hpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/src/mbgl/text/glyph_atlas.hpp b/src/mbgl/text/glyph_atlas.hpp
new file mode 100644
index 0000000000..ca88d16f8b
--- /dev/null
+++ b/src/mbgl/text/glyph_atlas.hpp
@@ -0,0 +1,109 @@
+#pragma once
+
+#include <mbgl/text/glyph.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/gl/gl.hpp>
+#include <mbgl/gl/object_store.hpp>
+
+#include <atomic>
+#include <string>
+#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, 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&,
+ const GlyphSet&,
+ GlyphPositions&);
+ void removeGlyphs(uintptr_t tileUID);
+
+ // Binds the atlas texture to the GPU, and uploads data if it is out of date.
+ void bind(gl::ObjectStore&, gl::Config&, uint32_t unit);
+
+ // 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(gl::ObjectStore&, gl::Config&, uint32_t unit);
+
+ const GLsizei width;
+ 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 }) {}
+ Rect<uint16_t> rect;
+ std::set<uintptr_t> ids;
+ };
+
+ std::mutex mtx;
+ BinPack<uint16_t> bin;
+ std::unordered_map<FontStack, std::map<uint32_t, GlyphValue>, FontStackHash> index;
+ const std::unique_ptr<uint8_t[]> data;
+ std::atomic<bool> dirty;
+ mbgl::optional<gl::UniqueTexture> texture;
+};
+
+} // namespace mbgl