diff options
-rw-r--r-- | include/mbgl/gl/gl.hpp | 1 | ||||
-rw-r--r-- | include/mbgl/gl/gl_values.hpp | 25 | ||||
-rw-r--r-- | src/mbgl/gl/gl_config.hpp | 29 | ||||
-rw-r--r-- | src/mbgl/gl/object_store.cpp | 11 | ||||
-rw-r--r-- | src/mbgl/gl/object_store.hpp | 17 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.hpp | 2 |
7 files changed, 89 insertions, 4 deletions
diff --git a/include/mbgl/gl/gl.hpp b/include/mbgl/gl/gl.hpp index 092166ef96..be6405c593 100644 --- a/include/mbgl/gl/gl.hpp +++ b/include/mbgl/gl/gl.hpp @@ -21,6 +21,7 @@ #elif TARGET_OS_MAC #include <OpenGL/OpenGL.h> #include <OpenGL/gl.h> + #include <OpenGL/glext.h> #else #error Unsupported Apple platform #endif diff --git a/include/mbgl/gl/gl_values.hpp b/include/mbgl/gl/gl_values.hpp index e5ad2380d1..fa3b87c435 100644 --- a/include/mbgl/gl/gl_values.hpp +++ b/include/mbgl/gl/gl_values.hpp @@ -271,6 +271,31 @@ struct ActiveTexture { } }; +struct BindFramebuffer { + using Type = GLint; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, value)); + } + static Type Get() { + Type activeFBO; + MBGL_CHECK_ERROR(glGetIntegerv(GL_FRAMEBUFFER_BINDING, &activeFBO)); + return activeFBO; + } +}; + +struct Viewport { + using Type = std::array<GLint, 4>; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glViewport(value[0], value[1], value[2], value[3])); + } + static Type Get() { + Type pos; + MBGL_CHECK_ERROR(glGetIntegerv(GL_VIEWPORT, pos.data())); + return pos; + } +}; + + #ifndef GL_ES_VERSION_2_0 struct PixelZoom { diff --git a/src/mbgl/gl/gl_config.hpp b/src/mbgl/gl/gl_config.hpp index 1e0f25a0f3..225f4f8de6 100644 --- a/src/mbgl/gl/gl_config.hpp +++ b/src/mbgl/gl/gl_config.hpp @@ -9,6 +9,20 @@ namespace mbgl { namespace gl { + +template <typename T, typename = void> +struct DefaultValue { + static typename T::Type Get() { + return T::Get(); + } +}; +template <typename T> +struct DefaultValue<T, decltype((void)T::Default, void())> { + static typename T::Type Get() { + return T::Default; + } +}; + template <typename T> class Value { public: @@ -25,7 +39,7 @@ public: } void reset() { - *this = T::Default; + *this = defaultValue; } void setDirty() { @@ -40,8 +54,13 @@ public: return dirty; } + void setDefaultValue(const typename T::Type& value) { + defaultValue = value; + } + private: - typename T::Type current = T::Default; + typename T::Type defaultValue = DefaultValue<T>::Get(); + typename T::Type current = defaultValue; bool dirty = false; }; @@ -66,6 +85,8 @@ public: program.reset(); lineWidth.reset(); activeTexture.reset(); + bindFramebuffer.reset(); + viewport.reset(); #ifndef GL_ES_VERSION_2_0 pixelZoom.reset(); rasterPos.reset(); @@ -94,6 +115,8 @@ public: program.setDirty(); lineWidth.setDirty(); activeTexture.setDirty(); + bindFramebuffer.setDirty(); + viewport.setDirty(); #ifndef GL_ES_VERSION_2_0 pixelZoom.setDirty(); rasterPos.setDirty(); @@ -121,6 +144,8 @@ public: Value<Program> program; Value<LineWidth> lineWidth; Value<ActiveTexture> activeTexture; + Value<BindFramebuffer> bindFramebuffer; + Value<Viewport> viewport; #ifndef GL_ES_VERSION_2_0 Value<PixelZoom> pixelZoom; Value<RasterPos> rasterPos; diff --git a/src/mbgl/gl/object_store.cpp b/src/mbgl/gl/object_store.cpp index 4139854f61..9ddbaa7c8c 100644 --- a/src/mbgl/gl/object_store.cpp +++ b/src/mbgl/gl/object_store.cpp @@ -34,6 +34,11 @@ void VAODeleter::operator()(GLuint id) const { store->abandonedVAOs.push_back(id); } +void FBODeleter::operator()(GLuint id) const { + assert(store); + store->abandonedFBOs.push_back(id); +} + ObjectStore::~ObjectStore() { assert(pooledTextures.empty()); assert(abandonedPrograms.empty()); @@ -41,6 +46,7 @@ ObjectStore::~ObjectStore() { assert(abandonedBuffers.empty()); assert(abandonedTextures.empty()); assert(abandonedVAOs.empty()); + assert(abandonedFBOs.empty()); } void ObjectStore::reset() { @@ -74,6 +80,11 @@ void ObjectStore::performCleanup() { MBGL_CHECK_ERROR(gl::DeleteVertexArrays(int(abandonedVAOs.size()), abandonedVAOs.data())); abandonedVAOs.clear(); } + + if (!abandonedFBOs.empty()) { + MBGL_CHECK_ERROR(glDeleteFramebuffers(int(abandonedFBOs.size()), abandonedFBOs.data())); + abandonedFBOs.clear(); + } } } // namespace gl diff --git a/src/mbgl/gl/object_store.hpp b/src/mbgl/gl/object_store.hpp index 96bb8008f1..ad9725c556 100644 --- a/src/mbgl/gl/object_store.hpp +++ b/src/mbgl/gl/object_store.hpp @@ -41,11 +41,17 @@ struct VAODeleter { void operator()(GLuint) const; }; +struct FBODeleter { + ObjectStore* store; + void operator()(GLuint) const; +}; + using UniqueProgram = std_experimental::unique_resource<GLuint, ProgramDeleter>; using UniqueShader = std_experimental::unique_resource<GLuint, ShaderDeleter>; using UniqueBuffer = std_experimental::unique_resource<GLuint, BufferDeleter>; using UniqueTexture = std_experimental::unique_resource<GLuint, TextureDeleter>; using UniqueVAO = std_experimental::unique_resource<GLuint, VAODeleter>; +using UniqueFBO = std_experimental::unique_resource<GLuint, FBODeleter>; class ObjectStore : private util::noncopyable { public: @@ -82,6 +88,12 @@ public: return UniqueVAO { std::move(id), { this } }; } + UniqueFBO createFBO() { + GLuint id = 0; + MBGL_CHECK_ERROR(glGenFramebuffers(1, &id)); + return UniqueFBO { std::move(id), { this } }; + } + // 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(); @@ -96,7 +108,8 @@ public: && abandonedShaders.empty() && abandonedBuffers.empty() && abandonedTextures.empty() - && abandonedVAOs.empty(); + && abandonedVAOs.empty() + && abandonedFBOs.empty(); } private: @@ -105,6 +118,7 @@ private: friend BufferDeleter; friend TextureDeleter; friend VAODeleter; + friend FBODeleter; std::vector<GLuint> pooledTextures; @@ -113,6 +127,7 @@ private: std::vector<GLuint> abandonedBuffers; std::vector<GLuint> abandonedTextures; std::vector<GLuint> abandonedVAOs; + std::vector<GLuint> abandonedFBOs; }; } // namespace gl diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 5178af004e..438e4b5e47 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -65,6 +65,10 @@ void Painter::setClipping(const ClipID& clip) { } void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& annotationSpriteAtlas) { + if (frame.framebufferSize != frame_.framebufferSize) { + config.viewport.setDefaultValue( + { { 0, 0, frame_.framebufferSize[0], frame_.framebufferSize[1] } }); + } frame = frame_; PaintParameters parameters { @@ -121,6 +125,8 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a // tiles whatsoever. { MBGL_DEBUG_GROUP("clear"); + config.bindFramebuffer.reset(); + config.viewport.reset(); config.stencilFunc.reset(); config.stencilTest = GL_TRUE; config.stencilMask = 0xFF; @@ -271,6 +277,8 @@ void Painter::renderPass(PaintParameters& parameters, setDepthSublayer(0); layer.as<CustomLayer>()->impl->render(state); config.setDirty(); + config.bindFramebuffer.reset(); + config.viewport.reset(); } else { MBGL_DEBUG_GROUP(layer.baseImpl->id + " - " + util::toString(item.tile->id)); if (item.bucket->needsClipping()) { diff --git a/src/mbgl/renderer/painter.hpp b/src/mbgl/renderer/painter.hpp index 66607c81f0..022d3adef8 100644 --- a/src/mbgl/renderer/painter.hpp +++ b/src/mbgl/renderer/painter.hpp @@ -63,7 +63,7 @@ class BackgroundLayer; } // namespace style struct FrameData { - std::array<uint16_t, 2> framebufferSize; + std::array<uint16_t, 2> framebufferSize = {{ 0, 0 }}; TimePoint timePoint; float pixelRatio; MapMode mapMode; |