diff --git a/src/mbgl/gl/texture_pool.cpp b/src/mbgl/gl/texture_pool.cpp index 334111dd5..edde48537 100644 --- a/src/mbgl/gl/texture_pool.cpp +++ b/src/mbgl/gl/texture_pool.cpp @@ -1,38 +1,44 @@ #include - #include #include #include -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::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 f68ca2eea..0992b8398 100644 --- a/src/mbgl/gl/texture_pool.hpp +++ b/src/mbgl/gl/texture_pool.hpp @@ -3,20 +3,36 @@ #include #include +#include -#include +#include +#include +#include namespace mbgl { namespace gl { class TexturePool : private util::noncopyable { - public: GLuint getTextureID(); - void removeTextureID(GLuint texture_id); + void releaseTextureID(GLuint); private: - std::set 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 ids; + }; + + std::vector pools; }; } // namespace gl diff --git a/src/mbgl/util/raster.cpp b/src/mbgl/util/raster.cpp index 2bb8c9007..49c013ba0 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; } }