Introduce GLObjectStore
Make a class for keeping GL objects ids and attach it to the ThreadContext instead of hanging it on the Environment.
This commit is contained in:
@@ -3,8 +3,9 @@
|
||||
|
||||
#include <mbgl/platform/gl.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/util/gl_object_store.hpp>
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
#include <mbgl/map/environment.hpp>
|
||||
#include <mbgl/util/thread_context.hpp>
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
@@ -23,7 +24,7 @@ public:
|
||||
~Buffer() {
|
||||
cleanup();
|
||||
if (buffer != 0) {
|
||||
Environment::Get().abandonBuffer(buffer);
|
||||
util::ThreadContext::getGLObjectStore()->abandonBuffer(buffer);
|
||||
buffer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include <mbgl/map/environment.hpp>
|
||||
#include <mbgl/geometry/line_atlas.hpp>
|
||||
#include <mbgl/platform/gl.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
#include <mbgl/util/gl_object_store.hpp>
|
||||
#include <mbgl/util/thread_context.hpp>
|
||||
|
||||
#include <boost/functional/hash.hpp>
|
||||
|
||||
@@ -22,7 +23,7 @@ LineAtlas::~LineAtlas() {
|
||||
std::lock_guard<std::recursive_mutex> lock(mtx);
|
||||
|
||||
if (texture) {
|
||||
Environment::Get().abandonTexture(texture);
|
||||
mbgl::util::ThreadContext::getGLObjectStore()->abandonTexture(texture);
|
||||
texture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <atomic>
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
#include <mbgl/map/environment.hpp>
|
||||
#include <mbgl/geometry/sprite_atlas.hpp>
|
||||
#include <mbgl/platform/gl.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/platform/platform.hpp>
|
||||
#include <mbgl/util/gl_object_store.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
#include <mbgl/util/constants.hpp>
|
||||
#include <mbgl/util/scaling.hpp>
|
||||
#include <mbgl/util/thread_context.hpp>
|
||||
|
||||
#include <mbgl/map/sprite.hpp>
|
||||
|
||||
@@ -300,7 +301,7 @@ void SpriteAtlas::bind(bool linear) {
|
||||
SpriteAtlas::~SpriteAtlas() {
|
||||
std::lock_guard<std::recursive_mutex> lock(mtx);
|
||||
if (texture) {
|
||||
Environment::Get().abandonTexture(texture);
|
||||
mbgl::util::ThreadContext::getGLObjectStore()->abandonTexture(texture);
|
||||
texture = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#include <mbgl/geometry/vao.hpp>
|
||||
#include <mbgl/platform/log.hpp>
|
||||
#include <mbgl/util/gl_object_store.hpp>
|
||||
#include <mbgl/util/string.hpp>
|
||||
#include <mbgl/map/environment.hpp>
|
||||
#include <mbgl/util/thread_context.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
@@ -47,7 +48,7 @@ VertexArrayObject::~VertexArrayObject() {
|
||||
if (!DeleteVertexArrays) return;
|
||||
|
||||
if (vao) {
|
||||
Environment::Get().abandonVAO(vao);
|
||||
util::ThreadContext::getGLObjectStore()->abandonVAO(vao);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <mbgl/style/style_bucket.hpp>
|
||||
#include <mbgl/style/style_layer.hpp>
|
||||
|
||||
#include <mbgl/util/gl_object_store.hpp>
|
||||
#include <mbgl/util/uv_detail.hpp>
|
||||
#include <mbgl/util/worker.hpp>
|
||||
#include <mbgl/util/texture_pool.hpp>
|
||||
@@ -37,6 +38,7 @@ MapContext::MapContext(uv_loop_t* loop, View& view_, FileSource& fileSource, Map
|
||||
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
|
||||
|
||||
util::ThreadContext::setFileSource(&fileSource);
|
||||
util::ThreadContext::setGLObjectStore(&glObjectStore);
|
||||
|
||||
asyncUpdate->unref();
|
||||
|
||||
@@ -52,12 +54,12 @@ void MapContext::cleanup() {
|
||||
view.notify();
|
||||
|
||||
// Explicit resets currently necessary because these abandon resources that need to be
|
||||
// cleaned up by env.performCleanup();
|
||||
// cleaned up by glObjectStore.performCleanup();
|
||||
style.reset();
|
||||
painter.reset();
|
||||
texturePool.reset();
|
||||
|
||||
env.performCleanup();
|
||||
glObjectStore.performCleanup();
|
||||
|
||||
view.deactivate();
|
||||
}
|
||||
@@ -310,7 +312,7 @@ void MapContext::render() {
|
||||
assert(util::ThreadContext::currentlyOn(util::ThreadType::Map));
|
||||
|
||||
// Cleanup OpenGL objects that we abandoned since the last render call.
|
||||
env.performCleanup();
|
||||
glObjectStore.performCleanup();
|
||||
|
||||
if (data.mode == MapMode::Still && (!callback || !data.getFullyLoaded())) {
|
||||
// We are either not waiting for a map to be rendered, or we don't have all resources yet.
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <mbgl/map/environment.hpp>
|
||||
#include <mbgl/map/transform_state.hpp>
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/util/gl_object_store.hpp>
|
||||
#include <mbgl/util/ptr.hpp>
|
||||
|
||||
#include <vector>
|
||||
@@ -76,6 +77,8 @@ private:
|
||||
View& view;
|
||||
MapData& data;
|
||||
|
||||
util::GLObjectStore glObjectStore;
|
||||
|
||||
Environment env;
|
||||
EnvironmentScope envScope;
|
||||
|
||||
|
||||
48
src/mbgl/util/gl_object_store.cpp
Normal file
48
src/mbgl/util/gl_object_store.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include <mbgl/util/gl_object_store.hpp>
|
||||
|
||||
#include <mbgl/util/thread.hpp>
|
||||
#include <mbgl/geometry/vao.hpp>
|
||||
#include <mbgl/platform/gl.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
void GLObjectStore::abandonVAO(uint32_t vao) {
|
||||
assert(ThreadContext::currentlyOn(ThreadType::Map));
|
||||
abandonedVAOs.emplace_back(vao);
|
||||
}
|
||||
|
||||
void GLObjectStore::abandonBuffer(uint32_t buffer) {
|
||||
assert(ThreadContext::currentlyOn(ThreadType::Map));
|
||||
abandonedBuffers.emplace_back(buffer);
|
||||
}
|
||||
|
||||
void GLObjectStore::abandonTexture(uint32_t texture) {
|
||||
assert(ThreadContext::currentlyOn(ThreadType::Map));
|
||||
abandonedTextures.emplace_back(texture);
|
||||
}
|
||||
|
||||
void GLObjectStore::performCleanup() {
|
||||
assert(ThreadContext::currentlyOn(ThreadType::Map));
|
||||
|
||||
if (!abandonedVAOs.empty()) {
|
||||
MBGL_CHECK_ERROR(VertexArrayObject::Delete(static_cast<GLsizei>(abandonedVAOs.size()),
|
||||
abandonedVAOs.data()));
|
||||
abandonedVAOs.clear();
|
||||
}
|
||||
|
||||
if (!abandonedTextures.empty()) {
|
||||
MBGL_CHECK_ERROR(glDeleteTextures(static_cast<GLsizei>(abandonedTextures.size()),
|
||||
abandonedTextures.data()));
|
||||
abandonedTextures.clear();
|
||||
}
|
||||
|
||||
if (!abandonedBuffers.empty()) {
|
||||
MBGL_CHECK_ERROR(glDeleteBuffers(static_cast<GLsizei>(abandonedBuffers.size()),
|
||||
abandonedBuffers.data()));
|
||||
abandonedBuffers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
34
src/mbgl/util/gl_object_store.hpp
Normal file
34
src/mbgl/util/gl_object_store.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef MBGL_MAP_UTIL_GL_OBJECT_STORE
|
||||
#define MBGL_MAP_UTIL_GL_OBJECT_STORE
|
||||
|
||||
#include <mbgl/util/noncopyable.hpp>
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace mbgl {
|
||||
namespace util {
|
||||
|
||||
class GLObjectStore : private util::noncopyable {
|
||||
public:
|
||||
GLObjectStore() = default;
|
||||
|
||||
// Mark OpenGL objects for deletion
|
||||
void abandonVAO(uint32_t vao);
|
||||
void abandonBuffer(uint32_t buffer);
|
||||
void abandonTexture(uint32_t texture);
|
||||
|
||||
// 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();
|
||||
|
||||
private:
|
||||
std::vector<uint32_t> abandonedVAOs;
|
||||
std::vector<uint32_t> abandonedBuffers;
|
||||
std::vector<uint32_t> abandonedTextures;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,5 +1,7 @@
|
||||
#include <mbgl/util/texture_pool.hpp>
|
||||
#include <mbgl/map/environment.hpp>
|
||||
|
||||
#include <mbgl/util/gl_object_store.hpp>
|
||||
#include <mbgl/util/thread_context.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
@@ -43,9 +45,9 @@ void TexturePool::removeTextureID(GLuint texture_id) {
|
||||
}
|
||||
|
||||
void TexturePool::clearTextureIDs() {
|
||||
auto& env = Environment::Get();
|
||||
auto getGLObjectStore = util::ThreadContext::getGLObjectStore();
|
||||
for (auto texture : texture_ids) {
|
||||
env.abandonTexture(texture);
|
||||
getGLObjectStore->abandonTexture(texture);
|
||||
}
|
||||
texture_ids.clear();
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ class FileSource;
|
||||
|
||||
namespace util {
|
||||
|
||||
class GLObjectStore;
|
||||
|
||||
enum class ThreadPriority : bool {
|
||||
Regular,
|
||||
Low,
|
||||
@@ -49,12 +51,21 @@ public:
|
||||
current.get()->fileSource = fileSource;
|
||||
}
|
||||
|
||||
static GLObjectStore* getGLObjectStore() {
|
||||
return current.get()->glObjectStore;
|
||||
}
|
||||
|
||||
static void setGLObjectStore(GLObjectStore* glObjectStore) {
|
||||
current.get()->glObjectStore = glObjectStore;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
ThreadType type;
|
||||
ThreadPriority priority;
|
||||
|
||||
FileSource* fileSource = nullptr;
|
||||
GLObjectStore* glObjectStore = nullptr;
|
||||
|
||||
static uv::tls<ThreadContext> current;
|
||||
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
|
||||
#include <uv.h>
|
||||
|
||||
// XXX: uv.h will include <bits/termios.h> that will
|
||||
// polute the namespace by defining "B0" which
|
||||
// will conflict with boost macros.
|
||||
#ifdef B0
|
||||
#undef B0
|
||||
#endif
|
||||
|
||||
#include <functional>
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
|
||||
Reference in New Issue
Block a user