diff options
author | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-02-15 01:51:54 +0200 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-02-18 13:27:35 +0200 |
commit | 3762dcfb8260beb587f753dde32751c13fa3c1d1 (patch) | |
tree | fbc5c2949682a4ec6bebe1c3acab0f2eccdb52c8 | |
parent | 69112a2a09404cc0ee7089a9f1f81ff1feac586f (diff) | |
download | qtlocation-mapboxgl-3762dcfb8260beb587f753dde32751c13fa3c1d1.tar.gz |
[gl] Refactor texture pool cleanup
Texture pool now allocates a block of 64 textures per time. Each block
contains a TextureObject which handles GL object lifetime. Blocks can be
added or removed according to the following rules:
1. If pool is empty, created a new block upon first call (lazy load);
2. Iterate blocks to find an available texture ID:
- If found, remove that from the list of available IDs for that block
and return its ID.
- Othewise, allocate a new block and grab an available ID from that.
3. When releasing a texture ID, check if the associated block is free.
If no IDs are currently in use, then abandon its TextureObject and
remove the block from the pool.
-rw-r--r-- | src/mbgl/gl/texture_pool.cpp | 46 | ||||
-rw-r--r-- | src/mbgl/gl/texture_pool.hpp | 24 | ||||
-rw-r--r-- | src/mbgl/util/raster.cpp | 2 |
3 files changed, 47 insertions, 25 deletions
diff --git a/src/mbgl/gl/texture_pool.cpp b/src/mbgl/gl/texture_pool.cpp index 334111dd52..edde485374 100644 --- a/src/mbgl/gl/texture_pool.cpp +++ b/src/mbgl/gl/texture_pool.cpp @@ -1,38 +1,44 @@ #include <mbgl/gl/texture_pool.hpp> - #include <mbgl/gl/gl_object_store.hpp> #include <mbgl/util/thread_context.hpp> #include <vector> -const GLsizei TextureMax = 64; - namespace mbgl { namespace gl { GLuint TexturePool::getTextureID() { - if (texture_ids.empty()) { - GLuint new_texture_ids[TextureMax]; - MBGL_CHECK_ERROR(glGenTextures(TextureMax, new_texture_ids)); - for (GLuint id = 0; id < TextureMax; id++) { - texture_ids.insert(new_texture_ids[id]); - } - } - - GLuint id = 0; - - if (!texture_ids.empty()) { - std::set<GLuint>::iterator id_iterator = texture_ids.begin(); - id = *id_iterator; - texture_ids.erase(id_iterator); + if (pools.empty()) pools.emplace_back(); + + for (auto& impl : pools) { + if (impl.ids.empty()) continue; + auto it = impl.ids.begin(); + GLuint id = *it; + impl.ids.erase(it); + return id; } + // All texture IDs are in use. + pools.emplace_back(); + auto it = pools.back().ids.begin(); + GLuint id = *it; + pools.back().ids.erase(it); return id; } -void TexturePool::removeTextureID(GLuint texture_id) { - texture_ids.insert(texture_id); - // TODO: We need to find a better way to deal with texture pool cleanup +void TexturePool::releaseTextureID(GLuint id) { + for (auto it = pools.begin(); it != pools.end(); ++it) { + for (GLsizei i = 0; i < gl::TexturePoolHolder::TextureMax; ++i) { + if (it->pool[i] == id) { + it->ids.push_back(id); + if (GLsizei(it->ids.size()) == gl::TexturePoolHolder::TextureMax) { + util::ThreadContext::getGLObjectStore()->abandon(std::move(it->pool)); + pools.erase(it); + } + return; + } + } + } } } // namespace gl diff --git a/src/mbgl/gl/texture_pool.hpp b/src/mbgl/gl/texture_pool.hpp index f68ca2eeaa..0992b8398d 100644 --- a/src/mbgl/gl/texture_pool.hpp +++ b/src/mbgl/gl/texture_pool.hpp @@ -3,20 +3,36 @@ #include <mbgl/util/noncopyable.hpp> #include <mbgl/gl/gl.hpp> +#include <mbgl/gl/gl_object_store.hpp> -#include <set> +#include <algorithm> +#include <memory> +#include <vector> namespace mbgl { namespace gl { class TexturePool : private util::noncopyable { - public: GLuint getTextureID(); - void removeTextureID(GLuint texture_id); + void releaseTextureID(GLuint); private: - std::set<GLuint> texture_ids; + class Impl : private util::noncopyable { + public: + Impl() : ids(gl::TexturePoolHolder::TextureMax) { + pool.create(); + std::copy(pool.getIDs().begin(), pool.getIDs().end(), ids.begin()); + } + + Impl(Impl&& o) : pool(std::move(o.pool)), ids(std::move(o.ids)) {} + Impl& operator=(Impl&& o) { pool = std::move(o.pool); ids = std::move(o.ids); return *this; } + + gl::TexturePoolHolder pool; + std::vector<GLuint> ids; + }; + + std::vector<Impl> pools; }; } // namespace gl diff --git a/src/mbgl/util/raster.cpp b/src/mbgl/util/raster.cpp index 2bb8c90078..49c013ba08 100644 --- a/src/mbgl/util/raster.cpp +++ b/src/mbgl/util/raster.cpp @@ -15,7 +15,7 @@ Raster::Raster(gl::TexturePool& texturePool_) Raster::~Raster() { if (textured) { - texturePool.removeTextureID(textureID); + texturePool.releaseTextureID(textureID); textureID = 0; } } |