[core] store viewport and FBO binding
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user