diff --git a/src/mbgl/gl/object_store.cpp b/src/mbgl/gl/object_store.cpp index 4198c090a..4139854f6 100644 --- a/src/mbgl/gl/object_store.cpp +++ b/src/mbgl/gl/object_store.cpp @@ -22,7 +22,11 @@ void BufferDeleter::operator()(GLuint id) const { void TextureDeleter::operator()(GLuint id) const { assert(store); - store->abandonedTextures.push_back(id); + if (store->pooledTextures.size() >= TextureMax) { + store->abandonedTextures.push_back(id); + } else { + store->pooledTextures.push_back(id); + } } void VAODeleter::operator()(GLuint id) const { @@ -30,14 +34,8 @@ void VAODeleter::operator()(GLuint id) const { store->abandonedVAOs.push_back(id); } -void TexturePoolDeleter::operator()(ObjectPool ids) const { - assert(store); - for (const auto& id : ids) { - store->abandonedTextures.push_back(id); - } -} - ObjectStore::~ObjectStore() { + assert(pooledTextures.empty()); assert(abandonedPrograms.empty()); assert(abandonedShaders.empty()); assert(abandonedBuffers.empty()); @@ -45,6 +43,12 @@ ObjectStore::~ObjectStore() { assert(abandonedVAOs.empty()); } +void ObjectStore::reset() { + std::copy(pooledTextures.begin(), pooledTextures.end(), std::back_inserter(abandonedTextures)); + pooledTextures.resize(0); + performCleanup(); +} + void ObjectStore::performCleanup() { for (GLuint id : abandonedPrograms) { MBGL_CHECK_ERROR(glDeleteProgram(id)); diff --git a/src/mbgl/gl/object_store.hpp b/src/mbgl/gl/object_store.hpp index 956d65bda..96bb8008f 100644 --- a/src/mbgl/gl/object_store.hpp +++ b/src/mbgl/gl/object_store.hpp @@ -5,7 +5,6 @@ #include -#include #include #include #include @@ -42,19 +41,11 @@ struct VAODeleter { void operator()(GLuint) const; }; -using ObjectPool = std::array; - -struct TexturePoolDeleter { - ObjectStore* store; - void operator()(ObjectPool) const; -}; - using UniqueProgram = std_experimental::unique_resource; using UniqueShader = std_experimental::unique_resource; using UniqueBuffer = std_experimental::unique_resource; using UniqueTexture = std_experimental::unique_resource; using UniqueVAO = std_experimental::unique_resource; -using UniqueTexturePool = std_experimental::unique_resource; class ObjectStore : private util::noncopyable { public: @@ -75,8 +66,13 @@ public: } UniqueTexture createTexture() { - GLuint id = 0; - MBGL_CHECK_ERROR(glGenTextures(1, &id)); + if (pooledTextures.empty()) { + pooledTextures.resize(TextureMax); + MBGL_CHECK_ERROR(glGenTextures(TextureMax, pooledTextures.data())); + } + + GLuint id = pooledTextures.back(); + pooledTextures.pop_back(); return UniqueTexture { std::move(id), { this } }; } @@ -86,19 +82,17 @@ public: return UniqueVAO { std::move(id), { this } }; } - UniqueTexturePool createTexturePool() { - ObjectPool ids; - MBGL_CHECK_ERROR(glGenTextures(TextureMax, ids.data())); - static_assert(ids.size() == size_t(TextureMax), "Texture ids size mismatch"); - return UniqueTexturePool { std::move(ids), { this } }; - } - // Actually remove the objects we marked as abandoned with the above methods. // Only call this while the OpenGL context is exclusive to this thread. void performCleanup(); + // Drain pools and remove abandoned objects, in preparation for destroying the store. + // Only call this while the OpenGL context is exclusive to this thread. + void reset(); + bool empty() const { - return abandonedPrograms.empty() + return pooledTextures.empty() + && abandonedPrograms.empty() && abandonedShaders.empty() && abandonedBuffers.empty() && abandonedTextures.empty() @@ -111,7 +105,8 @@ private: friend BufferDeleter; friend TextureDeleter; friend VAODeleter; - friend TexturePoolDeleter; + + std::vector pooledTextures; std::vector abandonedPrograms; std::vector abandonedShaders; diff --git a/src/mbgl/gl/texture_pool.cpp b/src/mbgl/gl/texture_pool.cpp deleted file mode 100644 index b5462e837..000000000 --- a/src/mbgl/gl/texture_pool.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include - -#include -#include -#include - -namespace mbgl { -namespace gl { - -class TexturePool::Impl : private util::noncopyable { -public: - class Pool : private util::noncopyable { - public: - Pool(gl::ObjectStore& store) : pool(store.createTexturePool()), availableIDs(gl::TextureMax) { - std::copy(pool.get().begin(), pool.get().end(), availableIDs.begin()); - } - - Pool(Pool&& o) : pool(std::move(o.pool)), availableIDs(std::move(o.availableIDs)) {} - Pool& operator=(Pool&& o) { pool = std::move(o.pool); availableIDs = std::move(o.availableIDs); return *this; } - - gl::UniqueTexturePool pool; - std::vector availableIDs; - }; - - GLuint acquireTexture(gl::ObjectStore& store) { - auto nextAvailableID = [](auto& pool_) { - auto it = pool_.availableIDs.begin(); - GLuint id = *it; - pool_.availableIDs.erase(it); - return id; - }; - - for (auto& pool : pools) { - if (pool.availableIDs.empty()) continue; - return nextAvailableID(pool); - } - - // All texture IDs are in use. - pools.emplace_back(Pool { store }); - return nextAvailableID(pools.back()); - } - - void releaseTexture(GLuint id) { - for (auto it = pools.begin(); it != pools.end(); ++it) { - if (std::find(it->pool.get().begin(), it->pool.get().end(), id) != it->pool.get().end()) { - it->availableIDs.push_back(id); - if (GLsizei(it->availableIDs.size()) == gl::TextureMax) { - pools.erase(it); - } - return; - } - } - } - -private: - std::vector pools; -}; - -void TextureReleaser::operator()(GLuint id) const { - assert(pool); - pool->impl->releaseTexture(id); -} - -TexturePool::TexturePool() : impl(std::make_unique()) { -} - -TexturePool::~TexturePool() = default; - -PooledTexture TexturePool::acquireTexture(gl::ObjectStore& store) { - return PooledTexture { impl->acquireTexture(store) , { this } }; -} - -} // namespace gl -} // namespace mbgl diff --git a/src/mbgl/gl/texture_pool.hpp b/src/mbgl/gl/texture_pool.hpp deleted file mode 100644 index 1cdcdf220..000000000 --- a/src/mbgl/gl/texture_pool.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include -#include - -#include - -#include - -namespace mbgl { -namespace gl { - -class TexturePool; - -struct TextureReleaser { - TexturePool* pool; - void operator()(GLuint) const; -}; - -using PooledTexture = std_experimental::unique_resource; - -class TexturePool : private util::noncopyable { -public: - TexturePool(); - ~TexturePool(); - - PooledTexture acquireTexture(gl::ObjectStore&); - -private: - friend TextureReleaser; - - class Impl; - const std::unique_ptr impl; -}; - -} // namespace gl -} // namespace mbgl diff --git a/src/mbgl/map/map.cpp b/src/mbgl/map/map.cpp index 7bf24fc42..5697036a6 100644 --- a/src/mbgl/map/map.cpp +++ b/src/mbgl/map/map.cpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -63,7 +62,6 @@ public: util::AsyncTask asyncUpdate; std::unique_ptr annotationManager; - std::unique_ptr texturePool; std::unique_ptr painter; std::unique_ptr