[core] store viewport and FBO binding

This commit is contained in:
Konstantin Käfer
2016-07-05 11:09:59 +02:00
parent 0f5b194617
commit ffa8a7668b
7 changed files with 89 additions and 4 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -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()) {

View File

@@ -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;