[core] Added save/restore capabilities to GL config

This commit is contained in:
Bruno de Oliveira Abinader
2015-10-20 12:52:40 -07:00
parent a1c53d92e5
commit 54858dae8c
3 changed files with 130 additions and 1 deletions

View File

@@ -10,6 +10,10 @@ enum class MapMode : uint8_t {
Still, // a once-off still image
};
// We can avoid redundant GL calls when it is known that the GL context is not
// being shared. In a shared GL context case, we need to make sure that the
// correct GL configurations are in use - they might have changed between render
// calls.
enum class GLContextMode : uint8_t {
Unique,
Shared,

View File

@@ -25,6 +25,14 @@ public:
T::Set(current);
}
inline void save() {
current = T::Get();
}
inline void restore() {
T::Set(current);
}
private:
typename T::Type current = T::Default;
};
@@ -35,14 +43,24 @@ struct ClearDepth {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(glClearDepth(value));
}
inline static Type Get() {
Type clearDepth;
MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth));
return clearDepth;
}
};
struct ClearColor {
struct Type { float r, g, b, a; };
struct Type { GLfloat r, g, b, a; };
static const Type Default;
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(glClearColor(value.r, value.g, value.b, value.a));
}
inline static Type Get() {
GLfloat floats[4];
MBGL_CHECK_ERROR(glGetFloatv(GL_COLOR_CLEAR_VALUE, floats));
return { floats[0], floats[1], floats[2], floats[3] };
}
};
inline bool operator!=(const ClearColor::Type& a, const ClearColor::Type& b) {
@@ -55,6 +73,11 @@ struct ClearStencil {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(glClearStencil(value));
}
inline static Type Get() {
Type clearStencil;
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil));
return clearStencil;
}
};
struct StencilMask {
@@ -63,6 +86,11 @@ struct StencilMask {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(glStencilMask(value));
}
inline static Type Get() {
GLint stencilMask;
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_WRITEMASK, &stencilMask));
return stencilMask;
}
};
struct DepthMask {
@@ -71,6 +99,11 @@ struct DepthMask {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(glDepthMask(value));
}
inline static Type Get() {
Type depthMask;
MBGL_CHECK_ERROR(glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask));
return depthMask;
}
};
struct ColorMask {
@@ -79,6 +112,11 @@ struct ColorMask {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(glColorMask(value.r, value.g, value.b, value.a));
}
inline static Type Get() {
GLfloat floats[4];
MBGL_CHECK_ERROR(glGetFloatv(GL_COLOR_WRITEMASK, floats));
return { floats[0], floats[1], floats[2], floats[3] };
}
};
inline bool operator!=(const ColorMask::Type& a, const ColorMask::Type& b) {
@@ -91,6 +129,13 @@ struct StencilFunc {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(glStencilFunc(value.func, value.ref, value.mask));
}
inline static Type Get() {
GLint func, ref, mask;
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_FUNC, &func));
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_REF, &ref));
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_VALUE_MASK, &mask));
return { static_cast<GLenum>(func), ref, static_cast<GLuint>(mask) };
}
};
inline bool operator!=(const StencilFunc::Type& a, const StencilFunc::Type& b) {
@@ -103,6 +148,11 @@ struct StencilTest {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(value ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST));
}
inline static Type Get() {
Type stencilTest;
MBGL_CHECK_ERROR(stencilTest = glIsEnabled(GL_STENCIL_TEST));
return stencilTest;
}
};
struct StencilOp {
@@ -111,6 +161,13 @@ struct StencilOp {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(glStencilOp(value.sfail, value.dpfail, value.dppass));
}
inline static Type Get() {
GLint sfail, dpfail, dppass;
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_FAIL, &sfail));
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &dpfail));
MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &dppass));
return { static_cast<GLenum>(sfail), static_cast<GLenum>(dpfail), static_cast<GLuint>(dppass) };
}
};
struct DepthRange {
@@ -119,6 +176,11 @@ struct DepthRange {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(glDepthRange(value.near, value.far));
}
inline static Type Get() {
GLfloat floats[2];
MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_RANGE, floats));
return { floats[0], floats[1] };
}
};
inline bool operator!=(const DepthRange::Type& a, const DepthRange::Type& b) {
@@ -131,6 +193,11 @@ struct DepthTest {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(value ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST));
}
inline static Type Get() {
Type depthTest;
MBGL_CHECK_ERROR(depthTest = glIsEnabled(GL_DEPTH_TEST));
return depthTest;
}
};
struct DepthFunc {
@@ -139,6 +206,11 @@ struct DepthFunc {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(glDepthFunc(value));
}
inline static Type Get() {
GLint depthFunc;
MBGL_CHECK_ERROR(glGetIntegerv(GL_DEPTH_FUNC, &depthFunc));
return depthFunc;
}
};
struct Blend {
@@ -147,6 +219,11 @@ struct Blend {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(value ? glEnable(GL_BLEND) : glDisable(GL_BLEND));
}
inline static Type Get() {
Type blend;
MBGL_CHECK_ERROR(blend = glIsEnabled(GL_BLEND));
return blend;
}
};
struct BlendFunc {
@@ -155,6 +232,12 @@ struct BlendFunc {
inline static void Set(const Type& value) {
MBGL_CHECK_ERROR(glBlendFunc(value.sfactor, value.dfactor));
}
inline static Type Get() {
GLint sfactor, dfactor;
MBGL_CHECK_ERROR(glGetIntegerv(GL_BLEND_SRC_ALPHA, &sfactor));
MBGL_CHECK_ERROR(glGetIntegerv(GL_BLEND_DST_ALPHA, &dfactor));
return { static_cast<GLenum>(sfactor), static_cast<GLenum>(dfactor) };
}
};
class Config {
@@ -176,6 +259,40 @@ public:
clearStencil.reset();
}
void restore() {
stencilFunc.restore();
stencilMask.restore();
stencilTest.restore();
stencilOp.restore();
depthRange.restore();
depthMask.restore();
depthTest.restore();
depthFunc.restore();
blend.restore();
blendFunc.restore();
colorMask.restore();
clearDepth.restore();
clearColor.restore();
clearStencil.restore();
}
void save() {
stencilFunc.save();
stencilMask.save();
stencilTest.save();
stencilOp.save();
depthRange.save();
depthMask.save();
depthTest.save();
depthFunc.save();
blend.save();
blendFunc.save();
colorMask.save();
clearDepth.save();
clearColor.save();
clearStencil.save();
}
Value<StencilFunc> stencilFunc;
Value<StencilMask> stencilMask;
Value<StencilTest> stencilTest;

View File

@@ -147,6 +147,10 @@ void Painter::render(const Style& style, TransformState state_, const FrameData&
state = state_;
frame = frame_;
if (data.contextMode == GLContextMode::Shared) {
config.restore();
}
glyphAtlas = style.glyphAtlas.get();
spriteAtlas = style.spriteAtlas.get();
lineAtlas = style.lineAtlas.get();
@@ -244,6 +248,10 @@ void Painter::render(const Style& style, TransformState state_, const FrameData&
MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, 0));
MBGL_CHECK_ERROR(VertexArrayObject::Unbind());
}
if (data.contextMode == GLContextMode::Shared) {
config.save();
}
}
template <class Iterator>