From 54858dae8cb92ba3e111422cdc8188f6d38ab4a9 Mon Sep 17 00:00:00 2001 From: Bruno de Oliveira Abinader Date: Tue, 20 Oct 2015 12:52:40 -0700 Subject: [PATCH] [core] Added save/restore capabilities to GL config --- include/mbgl/map/mode.hpp | 4 ++ src/mbgl/renderer/gl_config.hpp | 119 +++++++++++++++++++++++++++++++- src/mbgl/renderer/painter.cpp | 8 +++ 3 files changed, 130 insertions(+), 1 deletion(-) diff --git a/include/mbgl/map/mode.hpp b/include/mbgl/map/mode.hpp index 3e838dca9..6ad9af5c7 100644 --- a/include/mbgl/map/mode.hpp +++ b/include/mbgl/map/mode.hpp @@ -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, diff --git a/src/mbgl/renderer/gl_config.hpp b/src/mbgl/renderer/gl_config.hpp index 078dcabe7..4797d744f 100644 --- a/src/mbgl/renderer/gl_config.hpp +++ b/src/mbgl/renderer/gl_config.hpp @@ -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(func), ref, static_cast(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(sfail), static_cast(dpfail), static_cast(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(sfactor), static_cast(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; Value stencilMask; Value stencilTest; diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index c4b6e559a..1db2bde7b 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -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