diff --git a/src/mbgl/gl/gl_config.hpp b/src/mbgl/gl/gl_config.hpp index 7b42c7829..66f440653 100644 --- a/src/mbgl/gl/gl_config.hpp +++ b/src/mbgl/gl/gl_config.hpp @@ -12,7 +12,7 @@ namespace gl { template class Value { public: - inline void operator=(const typename T::Type& value) { + void operator=(const typename T::Type& value) { if (dirty || current != value) { dirty = false; current = value; @@ -20,16 +20,24 @@ public: } } - inline void reset() { + void reset() { dirty = true; current = T::Default; T::Set(current); } - inline void setDirty() { + void setDirty() { dirty = true; } + typename T::Type getCurrent() { + return current; + } + + bool getDirty() { + return dirty; + } + private: typename T::Type current = T::Default; bool dirty = false; diff --git a/src/mbgl/gl/object_store.hpp b/src/mbgl/gl/object_store.hpp index 8c798f168..a7b1993b5 100644 --- a/src/mbgl/gl/object_store.hpp +++ b/src/mbgl/gl/object_store.hpp @@ -96,6 +96,14 @@ public: // Only call this while the OpenGL context is exclusive to this thread. void performCleanup(); + bool empty() const { + return abandonedPrograms.empty() + && abandonedShaders.empty() + && abandonedBuffers.empty() + && abandonedTextures.empty() + && abandonedVAOs.empty(); + } + private: friend ProgramDeleter; friend ShaderDeleter; diff --git a/test/gl/object.cpp b/test/gl/object.cpp new file mode 100644 index 000000000..c80404095 --- /dev/null +++ b/test/gl/object.cpp @@ -0,0 +1,120 @@ +#include + +#include +#include + +#include +#include +#include + +#include + +namespace { + +static bool getFlag = false; +static bool setFlag = false; + +}; // namespace + +struct MockGLObject { + using Type = bool; + static const Type Default = false; + static Type Get() { getFlag = true; return true; } + static void Set(const Type&) { setFlag = true; } +}; + +TEST(GLObject, Preserve) { + getFlag = false; + setFlag = false; + + auto object = std::make_unique>(); + EXPECT_TRUE(getFlag); + EXPECT_FALSE(setFlag); + + getFlag = false; + object.reset(); + EXPECT_FALSE(getFlag); + EXPECT_TRUE(setFlag); +} + +TEST(GLObject, Value) { + setFlag = false; + + auto object = std::make_unique>(); + EXPECT_EQ(object->getCurrent(), false); + EXPECT_FALSE(object->getDirty()); + EXPECT_FALSE(setFlag); + + object->setDirty(); + EXPECT_TRUE(object->getDirty()); + + *object = false; + EXPECT_EQ(object->getCurrent(), false); + EXPECT_FALSE(object->getDirty()); + EXPECT_TRUE(setFlag); + + setFlag = false; + *object = true; + EXPECT_EQ(object->getCurrent(), true); + EXPECT_FALSE(object->getDirty()); + EXPECT_TRUE(setFlag); + + object->reset(); + EXPECT_EQ(object->getCurrent(), false); + EXPECT_TRUE(object->getDirty()); + EXPECT_TRUE(setFlag); +} + +TEST(GLObject, Store) { + mbgl::HeadlessView view(std::make_shared(), 1); + view.activate(); + + mbgl::gl::ObjectStore store; + EXPECT_TRUE(store.empty()); + + mbgl::gl::UniqueProgram program = store.createProgram(); + EXPECT_TRUE(program.get() != 0); + program.reset(); + EXPECT_FALSE(store.empty()); + store.performCleanup(); + EXPECT_TRUE(store.empty()); + + mbgl::gl::UniqueShader shader = store.createShader(GL_VERTEX_SHADER); + EXPECT_TRUE(shader.get() != 0); + shader.reset(); + EXPECT_FALSE(store.empty()); + store.performCleanup(); + EXPECT_TRUE(store.empty()); + + mbgl::gl::UniqueBuffer buffer = store.createBuffer(); + EXPECT_TRUE(buffer.get() != 0); + buffer.reset(); + EXPECT_FALSE(store.empty()); + store.performCleanup(); + EXPECT_TRUE(store.empty()); + + mbgl::gl::UniqueTexture texture = store.createTexture(); + EXPECT_TRUE(texture.get() != 0); + texture.reset(); + EXPECT_FALSE(store.empty()); + store.performCleanup(); + EXPECT_TRUE(store.empty()); + + mbgl::gl::UniqueVAO vao = store.createVAO(); + EXPECT_TRUE(vao.get() != 0); + vao.reset(); + EXPECT_FALSE(store.empty()); + store.performCleanup(); + EXPECT_TRUE(store.empty()); + + mbgl::gl::UniqueTexturePool texturePool = store.createTexturePool(); + for (auto& id : texturePool.get()) { + EXPECT_TRUE(id != 0); + } + texturePool.reset(); + EXPECT_FALSE(store.empty()); + store.performCleanup(); + EXPECT_TRUE(store.empty()); + + view.deactivate(); +} diff --git a/test/test.gypi b/test/test.gypi index 03052ab1c..f9a25e4e8 100644 --- a/test/test.gypi +++ b/test/test.gypi @@ -48,6 +48,8 @@ 'geometry/binpack.cpp', + 'gl/object.cpp', + 'map/map.cpp', 'map/transform.cpp',