[core] Added save/restore capabilities to GL config
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user