[core] Refresh Texture Pool logic
Take advantage of mbgl::gl::ObjectPool being iterable, and also let TexturePool update the texture ID value when releasing.
This commit is contained in:
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <array>
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
@@ -89,6 +90,7 @@ public:
|
||||
UniqueTexturePool createTexturePool() {
|
||||
ObjectPool ids;
|
||||
MBGL_CHECK_ERROR(glGenTextures(TextureMax, ids.data()));
|
||||
assert(ids.size() == size_t(TextureMax));
|
||||
return UniqueTexturePool(std::move(ids), { this });
|
||||
}
|
||||
|
||||
|
||||
@@ -1,38 +1,39 @@
|
||||
#include <mbgl/gl/texture_pool.hpp>
|
||||
#include <mbgl/gl/object_store.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
GLuint TexturePool::getTextureID(gl::ObjectStore& store) {
|
||||
for (auto& impl : pools) {
|
||||
if (impl.ids.empty()) continue;
|
||||
auto it = impl.ids.begin();
|
||||
auto nextAvailableID = [](auto& pool_) {
|
||||
auto it = pool_.availableIDs.begin();
|
||||
GLuint id = *it;
|
||||
impl.ids.erase(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(Impl(store));
|
||||
auto it = pools.back().ids.begin();
|
||||
GLuint id = *it;
|
||||
pools.back().ids.erase(it);
|
||||
return id;
|
||||
pools.emplace_back(Impl { store });
|
||||
return nextAvailableID(pools.back());
|
||||
}
|
||||
|
||||
void TexturePool::releaseTextureID(GLuint id) {
|
||||
void TexturePool::releaseTextureID(GLuint& id) {
|
||||
for (auto it = pools.begin(); it != pools.end(); ++it) {
|
||||
for (GLsizei i = 0; i < gl::TextureMax; ++i) {
|
||||
if (it->pool.get()[i] == id) {
|
||||
it->ids.push_back(id);
|
||||
if (GLsizei(it->ids.size()) == gl::TextureMax) {
|
||||
pools.erase(it);
|
||||
}
|
||||
return;
|
||||
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);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,20 +14,20 @@ namespace gl {
|
||||
class TexturePool : private util::noncopyable {
|
||||
public:
|
||||
GLuint getTextureID(gl::ObjectStore&);
|
||||
void releaseTextureID(GLuint);
|
||||
void releaseTextureID(GLuint&);
|
||||
|
||||
private:
|
||||
class Impl : private util::noncopyable {
|
||||
public:
|
||||
Impl(gl::ObjectStore& store) : pool(store.createTexturePool()), ids(gl::TextureMax) {
|
||||
std::copy(pool.get().begin(), pool.get().end(), ids.begin());
|
||||
Impl(gl::ObjectStore& store) : pool(store.createTexturePool()), availableIDs(gl::TextureMax) {
|
||||
std::copy(pool.get().begin(), pool.get().end(), availableIDs.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; }
|
||||
Impl(Impl&& o) : pool(std::move(o.pool)), availableIDs(std::move(o.availableIDs)) {}
|
||||
Impl& operator=(Impl&& o) { pool = std::move(o.pool); availableIDs = std::move(o.availableIDs); return *this; }
|
||||
|
||||
gl::UniqueTexturePool pool;
|
||||
std::vector<GLuint> ids;
|
||||
std::vector<GLuint> availableIDs;
|
||||
};
|
||||
|
||||
std::vector<Impl> pools;
|
||||
|
||||
@@ -16,7 +16,6 @@ Raster::Raster(gl::TexturePool& texturePool_)
|
||||
Raster::~Raster() {
|
||||
if (textured) {
|
||||
texturePool.releaseTextureID(textureID);
|
||||
textureID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user