From be44b6b31f88ca951b634ac36d117548587de2da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20Ka=CC=88fer?= Date: Wed, 12 Mar 2014 16:20:52 +0100 Subject: [PATCH] add glyph atlas to map --- include/llmr/geometry/glyph_atlas.hpp | 17 +++++++---------- include/llmr/map/map.hpp | 3 +++ include/llmr/map/tile_data.hpp | 9 ++++++++- src/geometry/glyph_atlas.cpp | 13 +++++++++++-- src/map/map.cpp | 3 ++- src/map/tile_data.cpp | 21 +++++++++++++++++++-- 6 files changed, 50 insertions(+), 16 deletions(-) diff --git a/include/llmr/geometry/glyph_atlas.hpp b/include/llmr/geometry/glyph_atlas.hpp index af159dbe7..b97b79f08 100644 --- a/include/llmr/geometry/glyph_atlas.hpp +++ b/include/llmr/geometry/glyph_atlas.hpp @@ -6,16 +6,12 @@ #include #include #include +#include +#include namespace llmr { -class Glyph { -public: - uint32_t id = 0; - std::string bitmap; - uint16_t width = 0; - uint16_t height = 0; -}; +class VectorTileGlyph; class GlyphAtlas { public: @@ -34,17 +30,18 @@ public: Rect addGlyph(uint64_t tile_id, const std::string& face_name, - const Glyph& glyph, uint8_t buffer); + const VectorTileGlyph& glyph); void removeGlyphs(uint64_t tile_id); void bind(); private: + std::mutex mtx; const uint16_t width = 0; const uint16_t height = 0; BinPack bin; std::map> index; - char *const data = NULL; - bool dirty = true; + char *const data = nullptr; + std::atomic dirty; uint32_t texture = 0; }; diff --git a/include/llmr/map/map.hpp b/include/llmr/map/map.hpp index b6cffb417..3506f4f43 100644 --- a/include/llmr/map/map.hpp +++ b/include/llmr/map/map.hpp @@ -5,6 +5,8 @@ #include #include #include +#include +#include #include #include @@ -76,6 +78,7 @@ private: Transform transform; Style style; Painter painter; + GlyphAtlas glyphAtlas; int32_t min_zoom; int32_t max_zoom; diff --git a/include/llmr/map/tile_data.hpp b/include/llmr/map/tile_data.hpp index 1402cb074..26387eb11 100644 --- a/include/llmr/map/tile_data.hpp +++ b/include/llmr/map/tile_data.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ class LayerDescription; class BucketDescription; class VectorTile; class VectorTileLayer; +class VectorTileFace; class FillVertexBuffer; class LineVertexBuffer; class PointVertexBuffer; @@ -54,7 +56,7 @@ public: }; public: - TileData(Tile::ID id, const Style& style); + TileData(Tile::ID id, const Style& style, GlyphAtlas& glyphAtlas); ~TileData(); // Start loading the tile. @@ -74,6 +76,9 @@ public: const std::string toString() const; +private: + void loadGlyphs(const std::map& faces); + public: const Tile::ID id; std::atomic state; @@ -94,10 +99,12 @@ public: // Holds the buckets of this tile. // They contain the location offsets in the buffers stored above std::map> buckets; + private: // Source data std::string data; const Style& style; + GlyphAtlas& glyphAtlas; platform::Request *req = nullptr; }; diff --git a/src/geometry/glyph_atlas.cpp b/src/geometry/glyph_atlas.cpp index 2afe25c8f..ef55d268e 100644 --- a/src/geometry/glyph_atlas.cpp +++ b/src/geometry/glyph_atlas.cpp @@ -1,4 +1,5 @@ #include +#include #include #include @@ -11,7 +12,8 @@ GlyphAtlas::GlyphAtlas(uint16_t width, uint16_t height) : width(width), height(height), bin(width, height), - data(new char[width *height]) { + data(new char[width *height]), + dirty(true) { } GlyphAtlas::~GlyphAtlas() { @@ -19,7 +21,11 @@ GlyphAtlas::~GlyphAtlas() { } Rect GlyphAtlas::addGlyph(uint64_t tile_id, const std::string& face_name, - const Glyph& glyph, uint8_t buffer) { + const VectorTileGlyph& glyph) { + std::lock_guard lock(mtx); + + // Use constant value for now. + const uint8_t buffer = 3; std::map& face = index[face_name]; std::map::iterator it = face.find(glyph.id); @@ -77,6 +83,8 @@ Rect GlyphAtlas::addGlyph(uint64_t tile_id, const std::string& face_na } void GlyphAtlas::removeGlyphs(uint64_t tile_id) { + std::lock_guard lock(mtx); + for (auto& faces : index) { std::map& face = faces.second; for (auto it = face.begin(); it != face.end(); /* we advance in the body */) { @@ -124,6 +132,7 @@ void GlyphAtlas::bind() { } if (dirty) { + std::lock_guard lock(mtx); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); dirty = false; } diff --git a/src/map/map.cpp b/src/map/map.cpp index 06aea39a3..3d6236827 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -14,6 +14,7 @@ Map::Map(Settings& settings) transform(), style(), painter(transform, settings, style), + glyphAtlas(1024, 1024), min_zoom(0), max_zoom(14) { } @@ -278,7 +279,7 @@ TileData::State Map::addTile(const Tile::ID& id) { if (!new_tile.data) { // If we don't find working tile data, we're just going to load it. - new_tile.data = std::make_shared(normalized_id, style); + new_tile.data = std::make_shared(normalized_id, style, glyphAtlas); new_tile.data->request(); tile_data.push_front(new_tile.data); } diff --git a/src/map/tile_data.cpp b/src/map/tile_data.cpp index 7110297ea..4f835db2d 100644 --- a/src/map/tile_data.cpp +++ b/src/map/tile_data.cpp @@ -19,7 +19,7 @@ using namespace llmr; -TileData::TileData(Tile::ID id, const Style& style) +TileData::TileData(Tile::ID id, const Style& style, GlyphAtlas& glyphAtlas) : id(id), state(State::initial), fillVertexBuffer(std::make_shared()), @@ -29,7 +29,8 @@ TileData::TileData(Tile::ID id, const Style& style) triangleElementsBuffer(std::make_shared()), lineElementsBuffer(std::make_shared()), pointElementsBuffer(std::make_shared()), - style(style) { + style(style), + glyphAtlas(glyphAtlas) { // Initialize tile debug coordinates char coord[32]; @@ -87,6 +88,7 @@ bool TileData::parse() { try { double parse_time_start = platform::time(); VectorTile tile(pbf((const uint8_t *)data.data(), data.size())); + loadGlyphs(tile.faces); parseStyleLayers(tile, style.layers); // double parse_time = (platform::time() - parse_time_start) * 1000.0; if (state == State::obsolete) { @@ -109,6 +111,21 @@ bool TileData::parse() { return true; } + +void TileData::loadGlyphs(const std::map& faces) { + std::map>> rects; + for (const std::pair pair : faces) { + const std::string& name = pair.first; + const VectorTileFace& face = pair.second; + + std::map>& rect = rects[name]; + + for (const VectorTileGlyph& glyph : face.glyphs) { + rect.emplace({ glyph.id, glyphAtlas.addGlyph((uint64_t)id, name, glyph) }); + } + } +} + void TileData::parseStyleLayers(const VectorTile& tile, const std::vector& layers) { for (const LayerDescription& layer_desc : layers) { // Cancel early when parsing.