summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mbgl/gl/gl.hpp1
-rw-r--r--include/mbgl/gl/gl_values.hpp25
-rw-r--r--src/mbgl/gl/gl_config.hpp29
-rw-r--r--src/mbgl/gl/object_store.cpp11
-rw-r--r--src/mbgl/gl/object_store.hpp17
-rw-r--r--src/mbgl/renderer/painter.cpp8
-rw-r--r--src/mbgl/renderer/painter.hpp2
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;