summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruno de Oliveira Abinader <bruno@mapbox.com>2016-02-14 22:26:30 +0200
committerBruno de Oliveira Abinader <bruno@mapbox.com>2016-02-18 13:27:35 +0200
commit124173080f35d4a53e24790c0ad2cf2687d35836 (patch)
tree415f17836fd92d53fa212b55c29536d71407df1c /src
parent3397398c1f5f05e22219557e0e81cfe61d693b33 (diff)
downloadqtlocation-mapboxgl-124173080f35d4a53e24790c0ad2cf2687d35836.tar.gz
[gl] Added mbgl::gl::Texture{,Pool}Holder
Diffstat (limited to 'src')
-rw-r--r--src/mbgl/geometry/glyph_atlas.cpp13
-rw-r--r--src/mbgl/geometry/glyph_atlas.hpp3
-rw-r--r--src/mbgl/geometry/line_atlas.cpp13
-rw-r--r--src/mbgl/geometry/line_atlas.hpp4
-rw-r--r--src/mbgl/gl/gl_object_store.cpp43
-rw-r--r--src/mbgl/gl/gl_object_store.hpp41
-rw-r--r--src/mbgl/gl/texture_pool.cpp18
-rw-r--r--src/mbgl/gl/texture_pool.hpp1
-rw-r--r--src/mbgl/sprite/sprite_atlas.cpp10
-rw-r--r--src/mbgl/sprite/sprite_atlas.hpp3
-rw-r--r--src/mbgl/util/raster.cpp9
-rw-r--r--src/mbgl/util/raster.hpp2
12 files changed, 98 insertions, 62 deletions
diff --git a/src/mbgl/geometry/glyph_atlas.cpp b/src/mbgl/geometry/glyph_atlas.cpp
index c220ec53b1..a5e07f2523 100644
--- a/src/mbgl/geometry/glyph_atlas.cpp
+++ b/src/mbgl/geometry/glyph_atlas.cpp
@@ -3,9 +3,9 @@
#include <mbgl/text/font_stack.hpp>
#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/platform/platform.hpp>
-#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/util/thread_context.hpp>
#include <cassert>
@@ -24,11 +24,6 @@ GlyphAtlas::GlyphAtlas(uint16_t width_, uint16_t height_)
GlyphAtlas::~GlyphAtlas() {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
-
- if (texture) {
- mbgl::util::ThreadContext::getGLObjectStore()->abandonTexture(texture);
- texture = 0;
- }
}
void GlyphAtlas::addGlyphs(uintptr_t tileUID,
@@ -194,8 +189,8 @@ void GlyphAtlas::upload() {
void GlyphAtlas::bind() {
if (!texture) {
- MBGL_CHECK_ERROR(glGenTextures(1, &texture));
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ texture.create();
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
#ifndef GL_ES_VERSION_2_0
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
@@ -204,6 +199,6 @@ void GlyphAtlas::bind() {
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));
} else {
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
}
};
diff --git a/src/mbgl/geometry/glyph_atlas.hpp b/src/mbgl/geometry/glyph_atlas.hpp
index 06a2d2a76a..c123d01133 100644
--- a/src/mbgl/geometry/glyph_atlas.hpp
+++ b/src/mbgl/geometry/glyph_atlas.hpp
@@ -5,6 +5,7 @@
#include <mbgl/text/glyph_store.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <string>
#include <set>
@@ -53,7 +54,7 @@ private:
std::map<std::string, std::map<uint32_t, GlyphValue>> index;
const std::unique_ptr<uint8_t[]> data;
std::atomic<bool> dirty;
- GLuint texture = 0;
+ gl::TextureHolder texture;
};
} // namespace mbgl
diff --git a/src/mbgl/geometry/line_atlas.cpp b/src/mbgl/geometry/line_atlas.cpp
index 63a5a34ea0..6163306dc9 100644
--- a/src/mbgl/geometry/line_atlas.cpp
+++ b/src/mbgl/geometry/line_atlas.cpp
@@ -1,8 +1,8 @@
#include <mbgl/geometry/line_atlas.hpp>
#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/platform/platform.hpp>
-#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/util/thread_context.hpp>
#include <boost/functional/hash.hpp>
@@ -21,11 +21,6 @@ LineAtlas::LineAtlas(GLsizei w, GLsizei h)
LineAtlas::~LineAtlas() {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
-
- if (texture) {
- mbgl::util::ThreadContext::getGLObjectStore()->abandonTexture(texture);
- texture = 0;
- }
}
LinePatternPos LineAtlas::getDashPosition(const std::vector<float> &dasharray, bool round) {
@@ -141,15 +136,15 @@ void LineAtlas::bind() {
bool first = false;
if (!texture) {
- MBGL_CHECK_ERROR(glGenTextures(1, &texture));
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ texture.create();
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT));
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
first = true;
} else {
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
}
if (dirty) {
diff --git a/src/mbgl/geometry/line_atlas.hpp b/src/mbgl/geometry/line_atlas.hpp
index b2d7222369..0e6e14ff54 100644
--- a/src/mbgl/geometry/line_atlas.hpp
+++ b/src/mbgl/geometry/line_atlas.hpp
@@ -2,10 +2,10 @@
#define MBGL_GEOMETRY_LINE_ATLAS
#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <vector>
#include <map>
-#include <memory>
namespace mbgl {
@@ -36,7 +36,7 @@ public:
private:
const std::unique_ptr<GLbyte[]> data;
bool dirty;
- GLuint texture = 0;
+ gl::TextureHolder texture;
int nextRow = 0;
std::map<size_t, LinePatternPos> positions;
};
diff --git a/src/mbgl/gl/gl_object_store.cpp b/src/mbgl/gl/gl_object_store.cpp
index 68d743cd95..addf1cc972 100644
--- a/src/mbgl/gl/gl_object_store.cpp
+++ b/src/mbgl/gl/gl_object_store.cpp
@@ -48,6 +48,32 @@ void BufferHolder::reset() {
id = 0;
}
+void TextureHolder::create() {
+ if (id) return;
+ assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
+ MBGL_CHECK_ERROR(glGenTextures(1, &id));
+}
+
+void TextureHolder::reset() {
+ if (!id) return;
+ assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
+ MBGL_CHECK_ERROR(glDeleteTextures(1, &id));
+ id = 0;
+}
+
+void TexturePoolHolder::create() {
+ if (bool()) return;
+ assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
+ MBGL_CHECK_ERROR(glGenTextures(TextureMax, ids.data()));
+}
+
+void TexturePoolHolder::reset() {
+ if (!bool()) return;
+ assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
+ MBGL_CHECK_ERROR(glDeleteTextures(TextureMax, ids.data()));
+ ids.fill(0);
+}
+
void GLObjectStore::abandonVAO(GLuint vao) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
@@ -59,9 +85,14 @@ void GLObjectStore::abandon(BufferHolder&& buffer) {
abandonedBuffers.push_back(std::move(buffer));
}
-void GLObjectStore::abandonTexture(GLuint texture) {
+void GLObjectStore::abandon(TextureHolder&& texture) {
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
- abandonedTextures.emplace_back(texture);
+ abandonedTextures.push_back(std::move(texture));
+}
+
+void GLObjectStore::abandon(TexturePoolHolder&& texture) {
+ assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
+ abandonedTexturePools.push_back(std::move(texture));
}
void GLObjectStore::performCleanup() {
@@ -74,12 +105,8 @@ void GLObjectStore::performCleanup() {
}
abandonedBuffers.clear();
-
- if (!abandonedTextures.empty()) {
- MBGL_CHECK_ERROR(glDeleteTextures(static_cast<GLsizei>(abandonedTextures.size()),
- abandonedTextures.data()));
- abandonedTextures.clear();
- }
+ abandonedTextures.clear();
+ abandonedTexturePools.clear();
}
} // namespace gl
diff --git a/src/mbgl/gl/gl_object_store.hpp b/src/mbgl/gl/gl_object_store.hpp
index 7b9409f329..6a115df0cb 100644
--- a/src/mbgl/gl/gl_object_store.hpp
+++ b/src/mbgl/gl/gl_object_store.hpp
@@ -4,6 +4,8 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/util/noncopyable.hpp>
+#include <array>
+#include <algorithm>
#include <memory>
#include <vector>
@@ -63,12 +65,46 @@ public:
void reset();
};
+class TextureHolder : public GLHolder {
+public:
+ TextureHolder() = default;
+ ~TextureHolder() { reset(); }
+
+ TextureHolder(TextureHolder&& o) noexcept : GLHolder(std::move(o)) {}
+ TextureHolder& operator=(TextureHolder&& o) noexcept { GLHolder::operator=(std::move(o)); return *this; }
+
+ void create();
+ void reset();
+};
+
+class TexturePoolHolder : private util::noncopyable {
+public:
+ static const GLsizei TextureMax = 64;
+
+ TexturePoolHolder() { ids.fill(0); }
+ ~TexturePoolHolder() { reset(); }
+
+ TexturePoolHolder(TexturePoolHolder&& o) noexcept : ids(std::move(o.ids)) {}
+ TexturePoolHolder& operator=(TexturePoolHolder&& o) noexcept { ids = std::move(o.ids); return *this; }
+
+ explicit operator bool() { return std::none_of(ids.begin(), ids.end(), [](int id) { return id == 0; }); }
+ const std::array<GLuint, TextureMax>& getIDs() const { return ids; }
+ const GLuint& operator[](size_t pos) { return ids[pos]; }
+
+ void create();
+ void reset();
+
+private:
+ std::array<GLuint, TextureMax> ids;
+};
+
class GLObjectStore : private util::noncopyable {
public:
// Mark OpenGL objects for deletion
void abandonVAO(GLuint vao);
void abandon(BufferHolder&&);
- void abandonTexture(GLuint texture);
+ void abandon(TextureHolder&&);
+ void abandon(TexturePoolHolder&&);
// Actually remove the objects we marked as abandoned with the above methods.
// Only call this while the OpenGL context is exclusive to this thread.
@@ -79,7 +115,8 @@ private:
// GLHolder-derived object can vary in size.
std::vector<GLuint> abandonedVAOs;
std::vector<BufferHolder> abandonedBuffers;
- std::vector<GLuint> abandonedTextures;
+ std::vector<TextureHolder> abandonedTextures;
+ std::vector<TexturePoolHolder> abandonedTexturePools;
};
} // namespace gl
diff --git a/src/mbgl/gl/texture_pool.cpp b/src/mbgl/gl/texture_pool.cpp
index 9d0ff79b11..334111dd52 100644
--- a/src/mbgl/gl/texture_pool.cpp
+++ b/src/mbgl/gl/texture_pool.cpp
@@ -31,26 +31,8 @@ GLuint TexturePool::getTextureID() {
}
void TexturePool::removeTextureID(GLuint texture_id) {
- bool needs_clear = false;
-
texture_ids.insert(texture_id);
-
- if (texture_ids.size() > TextureMax) {
- needs_clear = true;
- }
-
- if (needs_clear) {
// TODO: We need to find a better way to deal with texture pool cleanup
-// clearTextureIDs();
- }
-}
-
-void TexturePool::clearTextureIDs() {
- auto getGLObjectStore = util::ThreadContext::getGLObjectStore();
- for (auto texture : texture_ids) {
- getGLObjectStore->abandonTexture(texture);
- }
- texture_ids.clear();
}
} // namespace gl
diff --git a/src/mbgl/gl/texture_pool.hpp b/src/mbgl/gl/texture_pool.hpp
index 3981d98f08..f68ca2eeaa 100644
--- a/src/mbgl/gl/texture_pool.hpp
+++ b/src/mbgl/gl/texture_pool.hpp
@@ -14,7 +14,6 @@ class TexturePool : private util::noncopyable {
public:
GLuint getTextureID();
void removeTextureID(GLuint texture_id);
- void clearTextureIDs();
private:
std::set<GLuint> texture_ids;
diff --git a/src/mbgl/sprite/sprite_atlas.cpp b/src/mbgl/sprite/sprite_atlas.cpp
index 269ceb2c7c..7137e6d1fc 100644
--- a/src/mbgl/sprite/sprite_atlas.cpp
+++ b/src/mbgl/sprite/sprite_atlas.cpp
@@ -3,7 +3,6 @@
#include <mbgl/gl/gl.hpp>
#include <mbgl/platform/log.hpp>
#include <mbgl/platform/platform.hpp>
-#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/util/std.hpp>
#include <mbgl/util/constants.hpp>
@@ -187,8 +186,8 @@ void SpriteAtlas::bind(bool linear) {
}
if (!texture) {
- MBGL_CHECK_ERROR(glGenTextures(1, &texture));
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ texture.create();
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
#ifndef GL_ES_VERSION_2_0
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
@@ -198,7 +197,7 @@ void SpriteAtlas::bind(bool linear) {
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
fullUploadRequired = true;
} else {
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture.getID()));
}
GLuint filter_val = linear ? GL_LINEAR : GL_NEAREST;
@@ -250,8 +249,7 @@ void SpriteAtlas::bind(bool linear) {
SpriteAtlas::~SpriteAtlas() {
std::lock_guard<std::recursive_mutex> lock(mtx);
if (texture) {
- mbgl::util::ThreadContext::getGLObjectStore()->abandonTexture(texture);
- texture = 0;
+ mbgl::util::ThreadContext::getGLObjectStore()->abandon(std::move(texture));
}
}
diff --git a/src/mbgl/sprite/sprite_atlas.hpp b/src/mbgl/sprite/sprite_atlas.hpp
index ff3ed2b052..ff9cb44e4d 100644
--- a/src/mbgl/sprite/sprite_atlas.hpp
+++ b/src/mbgl/sprite/sprite_atlas.hpp
@@ -3,6 +3,7 @@
#include <mbgl/geometry/binpack.hpp>
#include <mbgl/gl/gl.hpp>
+#include <mbgl/gl/gl_object_store.hpp>
#include <mbgl/util/noncopyable.hpp>
#include <mbgl/util/ptr.hpp>
#include <mbgl/util/optional.hpp>
@@ -94,7 +95,7 @@ private:
std::unique_ptr<uint32_t[]> data;
std::atomic<bool> dirty;
bool fullUploadRequired = true;
- GLuint texture = 0;
+ gl::TextureHolder texture;
uint32_t filter = 0;
static const int buffer = 1;
};
diff --git a/src/mbgl/util/raster.cpp b/src/mbgl/util/raster.cpp
index bf0de1330d..2bb8c90078 100644
--- a/src/mbgl/util/raster.cpp
+++ b/src/mbgl/util/raster.cpp
@@ -15,7 +15,8 @@ Raster::Raster(gl::TexturePool& texturePool_)
Raster::~Raster() {
if (textured) {
- texturePool.removeTextureID(texture);
+ texturePool.removeTextureID(textureID);
+ textureID = 0;
}
}
@@ -45,7 +46,7 @@ void Raster::bind(bool linear) {
if (img.data && !textured) {
upload();
} else if (textured) {
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, textureID));
}
GLint new_filter = linear ? GL_LINEAR : GL_NEAREST;
@@ -58,8 +59,8 @@ void Raster::bind(bool linear) {
void Raster::upload() {
if (img.data && !textured) {
- texture = texturePool.getTextureID();
- MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, texture));
+ textureID = texturePool.getTextureID();
+ MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, textureID));
#ifndef GL_ES_VERSION_2_0
MBGL_CHECK_ERROR(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0));
#endif
diff --git a/src/mbgl/util/raster.hpp b/src/mbgl/util/raster.hpp
index f19f679bd5..e47fe665f6 100644
--- a/src/mbgl/util/raster.hpp
+++ b/src/mbgl/util/raster.hpp
@@ -38,7 +38,7 @@ public:
bool textured = false;
// the uploaded texture
- GLuint texture = 0;
+ GLuint textureID = 0;
// texture opacity
double opacity = 0;