diff options
author | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-06-06 20:17:12 +0300 |
---|---|---|
committer | Bruno de Oliveira Abinader <bruno@mapbox.com> | 2016-06-07 13:01:58 +0300 |
commit | 83d349ee16f1918d7e0275d47b9c22abc1a4f50c (patch) | |
tree | 3db5a34ec11598cc2e82df4534200f9a8d7f308c /src | |
parent | 858311d19b9879cf6ac1fea2d8746e136be3c4a3 (diff) | |
download | qtlocation-mapboxgl-83d349ee16f1918d7e0275d47b9c22abc1a4f50c.tar.gz |
[core] Use RAII for TexturePool textures
TexturePool now disposes acquirable ids via SharedTexture, which
guarantees that these are going back to TexturePool once released.
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/gl/texture_pool.cpp | 30 | ||||
-rw-r--r-- | src/mbgl/gl/texture_pool.hpp | 16 | ||||
-rw-r--r-- | src/mbgl/util/raster.cpp | 19 | ||||
-rw-r--r-- | src/mbgl/util/raster.hpp | 9 |
4 files changed, 38 insertions, 36 deletions
diff --git a/src/mbgl/gl/texture_pool.cpp b/src/mbgl/gl/texture_pool.cpp index 87e5aed256..53e29b907b 100644 --- a/src/mbgl/gl/texture_pool.cpp +++ b/src/mbgl/gl/texture_pool.cpp @@ -9,20 +9,20 @@ namespace gl { class TexturePool::Impl : private util::noncopyable { public: - class Group : private util::noncopyable { + class Pool : private util::noncopyable { public: - Group(gl::ObjectStore& store) : pool(store.createTexturePool()), availableIDs(gl::TextureMax) { + Pool(gl::ObjectStore& store) : pool(store.createTexturePool()), availableIDs(gl::TextureMax) { std::copy(pool.get().begin(), pool.get().end(), availableIDs.begin()); } - Group(Group&& o) : pool(std::move(o.pool)), availableIDs(std::move(o.availableIDs)) {} - Group& operator=(Group&& o) { pool = std::move(o.pool); availableIDs = std::move(o.availableIDs); return *this; } + 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<GLuint> availableIDs; }; - GLuint getTextureID(gl::ObjectStore& store) { + GLuint acquireTexture(gl::ObjectStore& store) { auto nextAvailableID = [](auto& pool_) { auto it = pool_.availableIDs.begin(); GLuint id = *it; @@ -36,15 +36,14 @@ public: } // All texture IDs are in use. - pools.emplace_back(Group { store }); + pools.emplace_back(Pool { store }); return nextAvailableID(pools.back()); } - void releaseTextureID(GLuint& id) { + 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); - id = 0; if (GLsizei(it->availableIDs.size()) == gl::TextureMax) { pools.erase(it); } @@ -54,21 +53,22 @@ public: } private: - std::vector<Group> pools; + std::vector<Pool> pools; }; -TexturePool::TexturePool() : impl(std::make_unique<Impl>()) { +void TextureReleaser::operator()(GLuint id) const { + assert(pool); + pool->impl->releaseTexture(id); } -TexturePool::~TexturePool() { +TexturePool::TexturePool() : impl(std::make_unique<Impl>()) { } -GLuint TexturePool::getTextureID(gl::ObjectStore& store) { - return impl->getTextureID(store); +TexturePool::~TexturePool() { } -void TexturePool::releaseTextureID(GLuint& id) { - impl->releaseTextureID(id); +SharedTexture TexturePool::acquireTexture(gl::ObjectStore& store) { + return SharedTexture { impl->acquireTexture(store) , { this } }; } } // namespace gl diff --git a/src/mbgl/gl/texture_pool.hpp b/src/mbgl/gl/texture_pool.hpp index 9ab7d14ef6..3c38343f62 100644 --- a/src/mbgl/gl/texture_pool.hpp +++ b/src/mbgl/gl/texture_pool.hpp @@ -4,20 +4,32 @@ #include <mbgl/gl/gl.hpp> #include <mbgl/gl/object_store.hpp> +#include <unique_resource.hpp> + #include <memory> namespace mbgl { namespace gl { +class TexturePool; + +struct TextureReleaser { + TexturePool* pool; + void operator()(GLuint) const; +}; + +using SharedTexture = std_experimental::unique_resource<GLuint, TextureReleaser>; + class TexturePool : private util::noncopyable { public: TexturePool(); ~TexturePool(); - GLuint getTextureID(gl::ObjectStore&); - void releaseTextureID(GLuint&); + SharedTexture acquireTexture(gl::ObjectStore&); private: + friend TextureReleaser; + class Impl; const std::unique_ptr<Impl> impl; }; diff --git a/src/mbgl/util/raster.cpp b/src/mbgl/util/raster.cpp index 70fdf7b02a..514472010f 100644 --- a/src/mbgl/util/raster.cpp +++ b/src/mbgl/util/raster.cpp @@ -13,12 +13,6 @@ Raster::Raster(gl::TexturePool& texturePool_) : texturePool(texturePool_) {} -Raster::~Raster() { - if (textured) { - texturePool.releaseTextureID(textureID); - } -} - bool Raster::isLoaded() const { std::lock_guard<std::mutex> lock(mtx); return loaded; @@ -42,10 +36,10 @@ void Raster::bind(bool linear, gl::ObjectStore& store) { return; } - if (img.data && !textured) { + if (img.data && !texture) { upload(store); - } else if (textured) { - MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, textureID)); + } else if (texture) { + MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture)); } GLint new_filter = linear ? GL_LINEAR : GL_NEAREST; @@ -57,15 +51,14 @@ void Raster::bind(bool linear, gl::ObjectStore& store) { } void Raster::upload(gl::ObjectStore& store) { - if (img.data && !textured) { - textureID = texturePool.getTextureID(store); - MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, textureID)); + if (img.data && !texture) { + texture = texturePool.acquireTexture(store); + MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, *texture)); #ifndef GL_ES_VERSION_2_0 MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)); #endif 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)); MBGL_CHECK_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img.data.release())); - textured = true; } } diff --git a/src/mbgl/util/raster.hpp b/src/mbgl/util/raster.hpp index ff16112d90..ecf026b5fa 100644 --- a/src/mbgl/util/raster.hpp +++ b/src/mbgl/util/raster.hpp @@ -5,6 +5,7 @@ #include <mbgl/util/image.hpp> #include <mbgl/util/ptr.hpp> #include <mbgl/util/chrono.hpp> +#include <mbgl/util/optional.hpp> #include <mutex> @@ -14,7 +15,6 @@ class Raster : public std::enable_shared_from_this<Raster> { public: Raster(gl::TexturePool&); - ~Raster(); // load image data void load(PremultipliedImage); @@ -33,11 +33,8 @@ public: GLsizei width = 0; GLsizei height = 0; - // has been uploaded to texture - bool textured = false; - - // the uploaded texture - GLuint textureID = 0; + // GL buffer object handle. + mbgl::optional<gl::SharedTexture> texture; // texture opacity double opacity = 0; |