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 /src | |
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.
Diffstat (limited to 'src')
-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; } } |