diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2016-09-15 17:03:13 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-09-19 09:40:43 -0700 |
commit | dc1861f6d5391707126a20dbb0272f5bd3522de8 (patch) | |
tree | 961a3612706b9466d9ff0ef278ae1206b821aa88 /src/mbgl/text/glyph_atlas.hpp | |
parent | 940124ff713a960d7f70071779dd37d07010fa80 (diff) | |
download | qtlocation-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.hpp | 109 |
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 |