diff --git a/include/mbgl/geometry/glyph_atlas.hpp b/include/mbgl/geometry/glyph_atlas.hpp index e05cbe3b9..07011d324 100644 --- a/include/mbgl/geometry/glyph_atlas.hpp +++ b/include/mbgl/geometry/glyph_atlas.hpp @@ -32,6 +32,7 @@ public: const SDFGlyph& glyph); void removeGlyphs(uint64_t tile_id); void bind(); + void upload(); public: const uint16_t width = 0; diff --git a/include/mbgl/geometry/sprite_atlas.hpp b/include/mbgl/geometry/sprite_atlas.hpp index bc123abe1..c30499a53 100644 --- a/include/mbgl/geometry/sprite_atlas.hpp +++ b/include/mbgl/geometry/sprite_atlas.hpp @@ -41,10 +41,12 @@ public: // NEVER CALL THIS FUNCTION FROM THE RENDER THREAD! it is blocking. Rect waitForImage(const std::string &name, const Sprite &sprite); - // Binds the image buffer of this sprite atlas to the GPU, and uploads data if it is out - // of date. + // Binds the image buffer of this sprite atlas to the GPU. void bind(bool linear = false); + // Uploads the image buffer to the GPU if it is out of date. + void upload(); + inline float getWidth() const { return width; } inline float getHeight() const { return height; } inline float getTextureWidth() const { return width * pixelRatio; } diff --git a/src/geometry/glyph_atlas.cpp b/src/geometry/glyph_atlas.cpp index 76df941d9..50524f018 100644 --- a/src/geometry/glyph_atlas.cpp +++ b/src/geometry/glyph_atlas.cpp @@ -120,6 +120,20 @@ void GlyphAtlas::removeGlyphs(uint64_t tile_id) { } } +void GlyphAtlas::upload() { + if (dirty) { + bind(); + + std::lock_guard lock(mtx); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, data); + dirty = false; + +#if defined(DEBUG) + // platform::show_debug_image("Glyph Atlas", data, width, height); +#endif + } +} + void GlyphAtlas::bind() { if (!texture) { glGenTextures(1, &texture); @@ -131,14 +145,4 @@ void GlyphAtlas::bind() { } else { glBindTexture(GL_TEXTURE_2D, texture); } - - 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; - -#if defined(DEBUG) - // platform::show_debug_image("Glyph Atlas", data, width, height); -#endif - } }; diff --git a/src/geometry/sprite_atlas.cpp b/src/geometry/sprite_atlas.cpp index 71d3cbee9..3d7c1ecd0 100644 --- a/src/geometry/sprite_atlas.cpp +++ b/src/geometry/sprite_atlas.cpp @@ -196,13 +196,11 @@ void SpriteAtlas::update(const Sprite &sprite) { } void SpriteAtlas::bind(bool linear) { - bool first = false; if (!texture) { glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - first = true; } else { glBindTexture(GL_TEXTURE_2D, texture); } @@ -213,12 +211,17 @@ void SpriteAtlas::bind(bool linear) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter_val); filter = filter_val; } +} +void SpriteAtlas::upload() { if (dirty) { + bool exists = texture; + bind(filter); // Make sure we don't change the filter value. + std::lock_guard lock(mtx); allocate(); - if (first) { + if (!exists) { glTexImage2D( GL_TEXTURE_2D, // GLenum target 0, // GLint level @@ -248,7 +251,7 @@ void SpriteAtlas::bind(bool linear) { #endif dirty = false; } -}; +} SpriteAtlas::~SpriteAtlas() { std::lock_guard lock(mtx); diff --git a/src/map/map.cpp b/src/map/map.cpp index 60ddaa597..b974c1532 100644 --- a/src/map/map.cpp +++ b/src/map/map.cpp @@ -558,6 +558,10 @@ void Map::render() { #if defined(DEBUG) std::vector debug; #endif + + glyphAtlas->upload(); + spriteAtlas->upload(); + painter.clear(); painter.resetFramebuffer();