diff options
author | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-02-14 22:26:30 +0200 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-02-18 13:27:35 +0200 |
commit | 124173080f35d4a53e24790c0ad2cf2687d35836 (patch) | |
tree | 415f17836fd92d53fa212b55c29536d71407df1c /src | |
parent | 3397398c1f5f05e22219557e0e81cfe61d693b33 (diff) | |
download | qtlocation-mapboxgl-124173080f35d4a53e24790c0ad2cf2687d35836.tar.gz |
[gl] Added mbgl::gl::Texture{,Pool}Holder
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/geometry/glyph_atlas.cpp | 13 | ||||
-rw-r--r-- | src/mbgl/geometry/glyph_atlas.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/geometry/line_atlas.cpp | 13 | ||||
-rw-r--r-- | src/mbgl/geometry/line_atlas.hpp | 4 | ||||
-rw-r--r-- | src/mbgl/gl/gl_object_store.cpp | 43 | ||||
-rw-r--r-- | src/mbgl/gl/gl_object_store.hpp | 41 | ||||
-rw-r--r-- | src/mbgl/gl/texture_pool.cpp | 18 | ||||
-rw-r--r-- | src/mbgl/gl/texture_pool.hpp | 1 | ||||
-rw-r--r-- | src/mbgl/sprite/sprite_atlas.cpp | 10 | ||||
-rw-r--r-- | src/mbgl/sprite/sprite_atlas.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/util/raster.cpp | 9 | ||||
-rw-r--r-- | src/mbgl/util/raster.hpp | 2 |
12 files changed, 98 insertions, 62 deletions
diff --git a/src/mbgl/geometry/glyph_atlas.cpp b/src/mbgl/geometry/glyph_atlas.cpp index c220ec53b1..a5e07f2523 100644 --- a/src/mbgl/geometry/glyph_atlas.cpp +++ b/src/mbgl/geometry/glyph_atlas.cpp @@ -3,9 +3,9 @@ #include <mbgl/text/font_stack.hpp> #include <mbgl/gl/gl.hpp> +#include <mbgl/gl/gl_object_store.hpp> #include <mbgl/platform/log.hpp> #include <mbgl/platform/platform.hpp> -#include <mbgl/gl/gl_object_store.hpp> #include <mbgl/util/thread_context.hpp> #include <cassert> @@ -24,11 +24,6 @@ GlyphAtlas::GlyphAtlas(uint16_t width_, uint16_t height_) GlyphAtlas::~GlyphAtlas() { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - - if (texture) { - mbgl::util::ThreadContext::getGLObjectStore()->abandonTexture(texture); - texture = 0; - } } void GlyphAtlas::addGlyphs(uintptr_t tileUID, @@ -194,8 +189,8 @@ void GlyphAtlas::upload() { void GlyphAtlas::bind() { if (!texture) { - MBGL_CHECK_ERROR(glGenTextures(1, &texture)); - MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture)); + texture.create(); + MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID())); #ifndef GL_ES_VERSION_2_0 MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); #endif @@ -204,6 +199,6 @@ void GlyphAtlas::bind() { MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)); MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); } else { - MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture)); + MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID())); } }; diff --git a/src/mbgl/geometry/glyph_atlas.hpp b/src/mbgl/geometry/glyph_atlas.hpp index 06a2d2a76a..c123d01133 100644 --- a/src/mbgl/geometry/glyph_atlas.hpp +++ b/src/mbgl/geometry/glyph_atlas.hpp @@ -5,6 +5,7 @@ #include <mbgl/text/glyph_store.hpp> #include <mbgl/util/noncopyable.hpp> #include <mbgl/gl/gl.hpp> +#include <mbgl/gl/gl_object_store.hpp> #include <string> #include <set> @@ -53,7 +54,7 @@ private: std::map<std::string, std::map<uint32_t, GlyphValue>> index; const std::unique_ptr<uint8_t[]> data; std::atomic<bool> dirty; - GLuint texture = 0; + gl::TextureHolder texture; }; } // namespace mbgl diff --git a/src/mbgl/geometry/line_atlas.cpp b/src/mbgl/geometry/line_atlas.cpp index 63a5a34ea0..6163306dc9 100644 --- a/src/mbgl/geometry/line_atlas.cpp +++ b/src/mbgl/geometry/line_atlas.cpp @@ -1,8 +1,8 @@ #include <mbgl/geometry/line_atlas.hpp> #include <mbgl/gl/gl.hpp> +#include <mbgl/gl/gl_object_store.hpp> #include <mbgl/platform/log.hpp> #include <mbgl/platform/platform.hpp> -#include <mbgl/gl/gl_object_store.hpp> #include <mbgl/util/thread_context.hpp> #include <boost/functional/hash.hpp> @@ -21,11 +21,6 @@ LineAtlas::LineAtlas(GLsizei w, GLsizei h) LineAtlas::~LineAtlas() { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - - if (texture) { - mbgl::util::ThreadContext::getGLObjectStore()->abandonTexture(texture); - texture = 0; - } } LinePatternPos LineAtlas::getDashPosition(const std::vector<float> &dasharray, bool round) { @@ -141,15 +136,15 @@ void LineAtlas::bind() { bool first = false; if (!texture) { - MBGL_CHECK_ERROR(glGenTextures(1, &texture)); - MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture)); + texture.create(); + MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID())); MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)); MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)); MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)); MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); first = true; } else { - MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture)); + MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID())); } if (dirty) { diff --git a/src/mbgl/geometry/line_atlas.hpp b/src/mbgl/geometry/line_atlas.hpp index b2d7222369..0e6e14ff54 100644 --- a/src/mbgl/geometry/line_atlas.hpp +++ b/src/mbgl/geometry/line_atlas.hpp @@ -2,10 +2,10 @@ #define MBGL_GEOMETRY_LINE_ATLAS #include <mbgl/gl/gl.hpp> +#include <mbgl/gl/gl_object_store.hpp> #include <vector> #include <map> -#include <memory> namespace mbgl { @@ -36,7 +36,7 @@ public: private: const std::unique_ptr<GLbyte[]> data; bool dirty; - GLuint texture = 0; + gl::TextureHolder texture; int nextRow = 0; std::map<size_t, LinePatternPos> positions; }; diff --git a/src/mbgl/gl/gl_object_store.cpp b/src/mbgl/gl/gl_object_store.cpp index 68d743cd95..addf1cc972 100644 --- a/src/mbgl/gl/gl_object_store.cpp +++ b/src/mbgl/gl/gl_object_store.cpp @@ -48,6 +48,32 @@ void BufferHolder::reset() { id = 0; } +void TextureHolder::create() { + if (id) return; + assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + MBGL_CHECK_ERROR(glGenTextures(1, &id)); +} + +void TextureHolder::reset() { + if (!id) return; + assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + MBGL_CHECK_ERROR(glDeleteTextures(1, &id)); + id = 0; +} + +void TexturePoolHolder::create() { + if (bool()) return; + assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + MBGL_CHECK_ERROR(glGenTextures(TextureMax, ids.data())); +} + +void TexturePoolHolder::reset() { + if (!bool()) return; + assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + MBGL_CHECK_ERROR(glDeleteTextures(TextureMax, ids.data())); + ids.fill(0); +} + void GLObjectStore::abandonVAO(GLuint vao) { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); @@ -59,9 +85,14 @@ void GLObjectStore::abandon(BufferHolder&& buffer) { abandonedBuffers.push_back(std::move(buffer)); } -void GLObjectStore::abandonTexture(GLuint texture) { +void GLObjectStore::abandon(TextureHolder&& texture) { assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); - abandonedTextures.emplace_back(texture); + abandonedTextures.push_back(std::move(texture)); +} + +void GLObjectStore::abandon(TexturePoolHolder&& texture) { + assert(util::ThreadContext::currentlyOn(util::ThreadType::Map)); + abandonedTexturePools.push_back(std::move(texture)); } void GLObjectStore::performCleanup() { @@ -74,12 +105,8 @@ void GLObjectStore::performCleanup() { } abandonedBuffers.clear(); - - if (!abandonedTextures.empty()) { - MBGL_CHECK_ERROR(glDeleteTextures(static_cast<GLsizei>(abandonedTextures.size()), - abandonedTextures.data())); - abandonedTextures.clear(); - } + abandonedTextures.clear(); + abandonedTexturePools.clear(); } } // namespace gl diff --git a/src/mbgl/gl/gl_object_store.hpp b/src/mbgl/gl/gl_object_store.hpp index 7b9409f329..6a115df0cb 100644 --- a/src/mbgl/gl/gl_object_store.hpp +++ b/src/mbgl/gl/gl_object_store.hpp @@ -4,6 +4,8 @@ #include <mbgl/gl/gl.hpp> #include <mbgl/util/noncopyable.hpp> +#include <array> +#include <algorithm> #include <memory> #include <vector> @@ -63,12 +65,46 @@ public: void reset(); }; +class TextureHolder : public GLHolder { +public: + TextureHolder() = default; + ~TextureHolder() { reset(); } + + TextureHolder(TextureHolder&& o) noexcept : GLHolder(std::move(o)) {} + TextureHolder& operator=(TextureHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; } + + void create(); + void reset(); +}; + +class TexturePoolHolder : private util::noncopyable { +public: + static const GLsizei TextureMax = 64; + + TexturePoolHolder() { ids.fill(0); } + ~TexturePoolHolder() { reset(); } + + TexturePoolHolder(TexturePoolHolder&& o) noexcept : ids(std::move(o.ids)) {} + TexturePoolHolder& operator=(TexturePoolHolder&& o) noexcept { ids = std::move(o.ids); return *this; } + + explicit operator bool() { return std::none_of(ids.begin(), ids.end(), [](int id) { return id == 0; }); } + const std::array<GLuint, TextureMax>& getIDs() const { return ids; } + const GLuint& operator[](size_t pos) { return ids[pos]; } + + void create(); + void reset(); + +private: + std::array<GLuint, TextureMax> ids; +}; + class GLObjectStore : private util::noncopyable { public: // Mark OpenGL objects for deletion void abandonVAO(GLuint vao); void abandon(BufferHolder&&); - void abandonTexture(GLuint texture); + void abandon(TextureHolder&&); + void abandon(TexturePoolHolder&&); // Actually remove the objects we marked as abandoned with the above methods. // Only call this while the OpenGL context is exclusive to this thread. @@ -79,7 +115,8 @@ private: // GLHolder-derived object can vary in size. std::vector<GLuint> abandonedVAOs; std::vector<BufferHolder> abandonedBuffers; - std::vector<GLuint> abandonedTextures; + std::vector<TextureHolder> abandonedTextures; + std::vector<TexturePoolHolder> abandonedTexturePools; }; } // namespace gl diff --git a/src/mbgl/gl/texture_pool.cpp b/src/mbgl/gl/texture_pool.cpp index 9d0ff79b11..334111dd52 100644 --- a/src/mbgl/gl/texture_pool.cpp +++ b/src/mbgl/gl/texture_pool.cpp @@ -31,26 +31,8 @@ GLuint TexturePool::getTextureID() { } void TexturePool::removeTextureID(GLuint texture_id) { - bool needs_clear = false; - texture_ids.insert(texture_id); - - if (texture_ids.size() > TextureMax) { - needs_clear = true; - } - - if (needs_clear) { // TODO: We need to find a better way to deal with texture pool cleanup -// clearTextureIDs(); - } -} - -void TexturePool::clearTextureIDs() { - auto getGLObjectStore = util::ThreadContext::getGLObjectStore(); - for (auto texture : texture_ids) { - getGLObjectStore->abandonTexture(texture); - } - texture_ids.clear(); } } // namespace gl diff --git a/src/mbgl/gl/texture_pool.hpp b/src/mbgl/gl/texture_pool.hpp index 3981d98f08..f68ca2eeaa 100644 --- a/src/mbgl/gl/texture_pool.hpp +++ b/src/mbgl/gl/texture_pool.hpp @@ -14,7 +14,6 @@ class TexturePool : private util::noncopyable { public: GLuint getTextureID(); void removeTextureID(GLuint texture_id); - void clearTextureIDs(); private: std::set<GLuint> texture_ids; diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp index 269ceb2c7c..7137e6d1fc 100644 --- a/src/mbgl/sprite/sprite_atlas.cpp +++ b/src/mbgl/sprite/sprite_atlas.cpp @@ -3,7 +3,6 @@ #include <mbgl/gl/gl.hpp> #include <mbgl/platform/log.hpp> #include <mbgl/platform/platform.hpp> -#include <mbgl/gl/gl_object_store.hpp> #include <mbgl/util/math.hpp> #include <mbgl/util/std.hpp> #include <mbgl/util/constants.hpp> @@ -187,8 +186,8 @@ void SpriteAtlas::bind(bool linear) { } if (!texture) { - MBGL_CHECK_ERROR(glGenTextures(1, &texture)); - MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture)); + texture.create(); + MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID())); #ifndef GL_ES_VERSION_2_0 MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); #endif @@ -198,7 +197,7 @@ void SpriteAtlas::bind(bool linear) { MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)); fullUploadRequired = true; } else { - MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture)); + MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID())); } GLuint filter_val = linear ? GL_LINEAR : GL_NEAREST; @@ -250,8 +249,7 @@ void SpriteAtlas::bind(bool linear) { SpriteAtlas::~SpriteAtlas() { std::lock_guard<std::recursive_mutex> lock(mtx); if (texture) { - mbgl::util::ThreadContext::getGLObjectStore()->abandonTexture(texture); - texture = 0; + mbgl::util::ThreadContext::getGLObjectStore()->abandon(std::move(texture)); } } diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp index ff3ed2b052..ff9cb44e4d 100644 --- a/src/mbgl/sprite/sprite_atlas.hpp +++ b/src/mbgl/sprite/sprite_atlas.hpp @@ -3,6 +3,7 @@ #include <mbgl/geometry/binpack.hpp> #include <mbgl/gl/gl.hpp> +#include <mbgl/gl/gl_object_store.hpp> #include <mbgl/util/noncopyable.hpp> #include <mbgl/util/ptr.hpp> #include <mbgl/util/optional.hpp> @@ -94,7 +95,7 @@ private: std::unique_ptr<uint32_t[]> data; std::atomic<bool> dirty; bool fullUploadRequired = true; - GLuint texture = 0; + gl::TextureHolder texture; uint32_t filter = 0; static const int buffer = 1; }; diff --git a/src/mbgl/util/raster.cpp b/src/mbgl/util/raster.cpp index bf0de1330d..2bb8c90078 100644 --- a/src/mbgl/util/raster.cpp +++ b/src/mbgl/util/raster.cpp @@ -15,7 +15,8 @@ Raster::Raster(gl::TexturePool& texturePool_) Raster::~Raster() { if (textured) { - texturePool.removeTextureID(texture); + texturePool.removeTextureID(textureID); + textureID = 0; } } @@ -45,7 +46,7 @@ void Raster::bind(bool linear) { if (img.data && !textured) { upload(); } else if (textured) { - MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture)); + MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, textureID)); } GLint new_filter = linear ? GL_LINEAR : GL_NEAREST; @@ -58,8 +59,8 @@ void Raster::bind(bool linear) { void Raster::upload() { if (img.data && !textured) { - texture = texturePool.getTextureID(); - MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture)); + textureID = texturePool.getTextureID(); + MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, textureID)); #ifndef GL_ES_VERSION_2_0 MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); #endif diff --git a/src/mbgl/util/raster.hpp b/src/mbgl/util/raster.hpp index f19f679bd5..e47fe665f6 100644 --- a/src/mbgl/util/raster.hpp +++ b/src/mbgl/util/raster.hpp @@ -38,7 +38,7 @@ public: bool textured = false; // the uploaded texture - GLuint texture = 0; + GLuint textureID = 0; // texture opacity double opacity = 0; |