diff options
author | Konstantin Käfer <mail@kkaefer.com> | 2016-09-27 12:27:35 +0200 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2016-09-27 11:03:29 -0700 |
commit | 21386b31465302d63cae5d93680442555c8560f1 (patch) | |
tree | 1220ea780dcbc6d79b83f476900a6f12cb3f71fc /src | |
parent | e881795ed10484ecfe8de73aaaa349c44eb259db (diff) | |
download | qtlocation-mapboxgl-21386b31465302d63cae5d93680442555c8560f1.tar.gz |
[core] move GL value accessors to gl::value namespace
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/gl/gl_config.hpp | 124 | ||||
-rw-r--r-- | src/mbgl/gl/state.hpp | 90 | ||||
-rw-r--r-- | src/mbgl/gl/value.cpp (renamed from src/mbgl/gl/gl_values.cpp) | 4 | ||||
-rw-r--r-- | src/mbgl/gl/value.hpp | 382 | ||||
-rw-r--r-- | src/mbgl/renderer/painter.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/renderer/painter_debug.cpp | 2 |
6 files changed, 515 insertions, 95 deletions
diff --git a/src/mbgl/gl/gl_config.hpp b/src/mbgl/gl/gl_config.hpp index 225f4f8de6..fed79594e4 100644 --- a/src/mbgl/gl/gl_config.hpp +++ b/src/mbgl/gl/gl_config.hpp @@ -1,72 +1,14 @@ #pragma once -#include <cstdint> -#include <tuple> -#include <array> - -#include <mbgl/gl/gl_values.hpp> +#include <mbgl/gl/state.hpp> +#include <mbgl/gl/value.hpp> 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: - void operator=(const typename T::Type& value) { - if (*this != value) { - dirty = false; - current = value; - T::Set(current); - } - } - - bool operator!=(const typename T::Type& value) const { - return dirty || current != value; - } - - void reset() { - *this = defaultValue; - } - - void setDirty() { - dirty = true; - } - - typename T::Type getCurrent() const { - return current; - } - - bool getDirty() const { - return dirty; - } - - void setDefaultValue(const typename T::Type& value) { - defaultValue = value; - } - -private: - typename T::Type defaultValue = DefaultValue<T>::Get(); - typename T::Type current = defaultValue; - bool dirty = false; -}; - class Config { public: - void reset() { + void resetState() { stencilFunc.reset(); stencilMask.reset(); stencilTest.reset(); @@ -91,12 +33,15 @@ public: pixelZoom.reset(); rasterPos.reset(); #endif // GL_ES_VERSION_2_0 + for (auto& tex : texture) { + tex.reset(); + } vertexBuffer.reset(); elementBuffer.reset(); vertexArrayObject.reset(); } - void setDirty() { + void setDirtyState() { stencilFunc.setDirty(); stencilMask.setDirty(); stencilTest.setDirty(); @@ -121,39 +66,42 @@ public: pixelZoom.setDirty(); rasterPos.setDirty(); #endif // GL_ES_VERSION_2_0 + for (auto& tex : texture) { + tex.setDirty(); + } vertexBuffer.setDirty(); elementBuffer.setDirty(); vertexArrayObject.setDirty(); } - Value<StencilFunc> stencilFunc; - Value<StencilMask> stencilMask; - Value<StencilTest> stencilTest; - Value<StencilOp> stencilOp; - Value<DepthRange> depthRange; - Value<DepthMask> depthMask; - Value<DepthTest> depthTest; - Value<DepthFunc> depthFunc; - Value<Blend> blend; - Value<BlendFunc> blendFunc; - Value<BlendColor> blendColor; - Value<ColorMask> colorMask; - Value<ClearDepth> clearDepth; - Value<ClearColor> clearColor; - Value<ClearStencil> clearStencil; - Value<Program> program; - Value<LineWidth> lineWidth; - Value<ActiveTexture> activeTexture; - Value<BindFramebuffer> bindFramebuffer; - Value<Viewport> viewport; + State<value::StencilFunc> stencilFunc; + State<value::StencilMask> stencilMask; + State<value::StencilTest> stencilTest; + State<value::StencilOp> stencilOp; + State<value::DepthRange> depthRange; + State<value::DepthMask> depthMask; + State<value::DepthTest> depthTest; + State<value::DepthFunc> depthFunc; + State<value::Blend> blend; + State<value::BlendFunc> blendFunc; + State<value::BlendColor> blendColor; + State<value::ColorMask> colorMask; + State<value::ClearDepth> clearDepth; + State<value::ClearColor> clearColor; + State<value::ClearStencil> clearStencil; + State<value::Program> program; + State<value::LineWidth> lineWidth; + State<value::ActiveTexture> activeTexture; + State<value::BindFramebuffer> bindFramebuffer; + State<value::Viewport> viewport; #ifndef GL_ES_VERSION_2_0 - Value<PixelZoom> pixelZoom; - Value<RasterPos> rasterPos; + State<value::PixelZoom> pixelZoom; + State<value::RasterPos> rasterPos; #endif // GL_ES_VERSION_2_0 - std::array<Value<BindTexture>, 2> texture; - Value<BindBuffer<GL_ARRAY_BUFFER>> vertexBuffer; - Value<BindBuffer<GL_ELEMENT_ARRAY_BUFFER>> elementBuffer; - Value<BindVAO> vertexArrayObject; + std::array<State<value::BindTexture>, 2> texture; + State<value::BindBuffer<GL_ARRAY_BUFFER>> vertexBuffer; + State<value::BindBuffer<GL_ELEMENT_ARRAY_BUFFER>> elementBuffer; + State<value::BindVAO> vertexArrayObject; }; } // namespace gl diff --git a/src/mbgl/gl/state.hpp b/src/mbgl/gl/state.hpp new file mode 100644 index 0000000000..274ae5e2fe --- /dev/null +++ b/src/mbgl/gl/state.hpp @@ -0,0 +1,90 @@ +#pragma once + +namespace mbgl { +namespace gl { + +// Helper struct that allows obtaining the default value of a Value class +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; + } +}; + +// Wraps a piece of OpenGL state and remember its value to avoid redundant state calls. +// Wrapped types need to implement to the Value class interface: +// +// class Value { +// using Type = ...; +// static const constexpr Type Default = ...; +// static void Set(const Type& value); +// static Type Get(); +// }; +// +// The Get() function is optional, but if it is omitted, you must provide a Default. +// Default is also optional, but if it is omitted, you must provide a Get() function. +// If both are present, DefaultValue<T>::Get() will use the Default member. +template <typename T> +class State { +public: + void operator=(const typename T::Type& value) { + if (*this != value) { + dirty = false; + currentValue = value; + T::Set(currentValue); + } + } + + bool operator!=(const typename T::Type& value) const { + return dirty || currentValue != value; + } + + void reset() { + *this = defaultValue; + } + + void setDirty() { + dirty = true; + } + + typename T::Type getCurrentValue() const { + return currentValue; + } + + bool isDirty() const { + return dirty; + } + + void setDefaultValue(const typename T::Type& value) { + defaultValue = value; + } + +private: + typename T::Type defaultValue = DefaultValue<T>::Get(); + typename T::Type currentValue = defaultValue; + bool dirty = false; +}; + +// Helper struct that stores the current state and restores it upon destruction. You should not use +// this code normally, except for debugging purposes. +template <typename T> +class PreserveState { +public: + PreserveState() : value(T::Get()) { + } + ~PreserveState() { + T::Set(value); + } + +private: + const typename T::Type value; +}; + +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/gl/gl_values.cpp b/src/mbgl/gl/value.cpp index c987c65aa0..7df3f4e3bd 100644 --- a/src/mbgl/gl/gl_values.cpp +++ b/src/mbgl/gl/value.cpp @@ -1,7 +1,8 @@ -#include <mbgl/gl/gl_values.hpp> +#include <mbgl/gl/value.hpp> namespace mbgl { namespace gl { +namespace value { const constexpr StencilFunc::Type StencilFunc::Default; const constexpr StencilMask::Type StencilMask::Default; @@ -29,5 +30,6 @@ const constexpr PixelZoom::Type PixelZoom::Default; const constexpr RasterPos::Type RasterPos::Default; #endif // GL_ES_VERSION_2_0 +} // namespace value } // namespace gl } // namespace mbgl diff --git a/src/mbgl/gl/value.hpp b/src/mbgl/gl/value.hpp new file mode 100644 index 0000000000..6436228ed1 --- /dev/null +++ b/src/mbgl/gl/value.hpp @@ -0,0 +1,382 @@ +#pragma once + +#include <cstdint> +#include <tuple> +#include <array> +#include <cassert> + +#include <mbgl/gl/gl.hpp> +#include <mbgl/util/color.hpp> + +namespace mbgl { +namespace gl { +namespace value { + +struct ClearDepth { + using Type = GLfloat; + static const constexpr Type Default = 1; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glClearDepth(value)); + } + static Type Get() { + Type clearDepth; + MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_CLEAR_VALUE, &clearDepth)); + return clearDepth; + } +}; + +struct ClearColor { + using Type = Color; + static const constexpr Type Default = { 0, 0, 0, 0 }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glClearColor(value.r, value.g, value.b, value.a)); + } + static Type Get() { + GLfloat floats[4]; + MBGL_CHECK_ERROR(glGetFloatv(GL_COLOR_CLEAR_VALUE, floats)); + return { floats[0], floats[1], floats[2], floats[3] }; + } +}; + +struct ClearStencil { + using Type = GLint; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glClearStencil(value)); + } + static Type Get() { + Type clearStencil; + MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &clearStencil)); + return clearStencil; + } +}; + +struct StencilMask { + using Type = GLuint; + static const constexpr Type Default = ~0u; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glStencilMask(value)); + } + static Type Get() { + GLint stencilMask; + MBGL_CHECK_ERROR(glGetIntegerv(GL_STENCIL_WRITEMASK, &stencilMask)); + return stencilMask; + } +}; + +struct DepthMask { + using Type = GLboolean; + static const constexpr Type Default = GL_TRUE; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glDepthMask(value)); + } + static Type Get() { + Type depthMask; + MBGL_CHECK_ERROR(glGetBooleanv(GL_DEPTH_WRITEMASK, &depthMask)); + return depthMask; + } +}; + +struct ColorMask { + struct Type { bool r, g, b, a; }; + static const constexpr Type Default = { GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glColorMask(value.r, value.g, value.b, value.a)); + } + static Type Get() { + GLboolean bools[4]; + MBGL_CHECK_ERROR(glGetBooleanv(GL_COLOR_WRITEMASK, bools)); + return { static_cast<bool>(bools[0]), static_cast<bool>(bools[1]), + static_cast<bool>(bools[2]), static_cast<bool>(bools[3]) }; + } +}; + +constexpr bool operator!=(const ColorMask::Type& a, const ColorMask::Type& b) { + return a.r != b.r || a.g != b.g || a.b != b.b || a.a != b.a; +} + +struct StencilFunc { + struct Type { GLenum func; GLint ref; GLuint mask; }; + static const constexpr Type Default = { GL_ALWAYS, 0, ~0u }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glStencilFunc(value.func, value.ref, value.mask)); + } + 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) }; + } +}; + +constexpr bool operator!=(const StencilFunc::Type& a, const StencilFunc::Type& b) { + return a.func != b.func || a.ref != b.ref || a.mask != b.mask; +} + +struct StencilTest { + using Type = bool; + static const constexpr Type Default = GL_FALSE; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(value ? glEnable(GL_STENCIL_TEST) : glDisable(GL_STENCIL_TEST)); + } + static Type Get() { + Type stencilTest; + MBGL_CHECK_ERROR(stencilTest = glIsEnabled(GL_STENCIL_TEST)); + return stencilTest; + } +}; + +struct StencilOp { + struct Type { GLenum sfail, dpfail, dppass; }; + static const constexpr Type Default = { GL_KEEP, GL_KEEP, GL_REPLACE }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glStencilOp(value.sfail, value.dpfail, value.dppass)); + } + 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) }; + } +}; + +constexpr bool operator!=(const StencilOp::Type& a, const StencilOp::Type& b) { + return a.sfail != b.sfail || a.dpfail != b.dpfail || a.dppass != b.dppass; +} + +struct DepthRange { + struct Type { GLfloat near, far; }; + static const constexpr Type Default = { 0, 1 }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glDepthRange(value.near, value.far)); + } + static Type Get() { + GLfloat floats[2]; + MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_RANGE, floats)); + return { floats[0], floats[1] }; + } +}; + +constexpr bool operator!=(const DepthRange::Type& a, const DepthRange::Type& b) { + return a.near != b.near || a.far != b.far; +} + +struct DepthTest { + using Type = bool; + static const constexpr Type Default = GL_FALSE; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(value ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST)); + } + static Type Get() { + Type depthTest; + MBGL_CHECK_ERROR(depthTest = glIsEnabled(GL_DEPTH_TEST)); + return depthTest; + } +}; + +struct DepthFunc { + using Type = GLenum; + static const constexpr Type Default = GL_LEQUAL; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glDepthFunc(value)); + } + static Type Get() { + GLint depthFunc; + MBGL_CHECK_ERROR(glGetIntegerv(GL_DEPTH_FUNC, &depthFunc)); + return depthFunc; + } +}; + +struct Blend { + using Type = bool; + static const constexpr Type Default = GL_TRUE; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(value ? glEnable(GL_BLEND) : glDisable(GL_BLEND)); + } + static Type Get() { + Type blend; + MBGL_CHECK_ERROR(blend = glIsEnabled(GL_BLEND)); + return blend; + } +}; + +struct BlendFunc { + struct Type { GLenum sfactor, dfactor; }; + static const constexpr Type Default = { GL_ONE, GL_ONE_MINUS_SRC_ALPHA }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glBlendFunc(value.sfactor, value.dfactor)); + } + 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) }; + } +}; + +constexpr bool operator!=(const BlendFunc::Type& a, const BlendFunc::Type& b) { + return a.sfactor != b.sfactor || a.dfactor != b.dfactor; +} + +struct BlendColor { + using Type = Color; + static const constexpr Type Default = { 0, 0, 0, 0 }; + inline static void Set(const Type& value) { + MBGL_CHECK_ERROR(glBlendColor(value.r, value.g, value.b, value.a)); + } + inline static Type Get() { + GLfloat floats[4]; + MBGL_CHECK_ERROR(glGetFloatv(GL_BLEND_COLOR, floats)); + return { floats[0], floats[1], floats[2], floats[3] }; + } +}; + +struct Program { + using Type = GLuint; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glUseProgram(value)); + } + static Type Get() { + GLint program; + MBGL_CHECK_ERROR(glGetIntegerv(GL_CURRENT_PROGRAM, &program)); + return program; + } +}; + +struct LineWidth { + using Type = GLfloat; + static const constexpr Type Default = 1; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glLineWidth(value)); + } + static Type Get() { + Type lineWidth; + MBGL_CHECK_ERROR(glGetFloatv(GL_LINE_WIDTH, &lineWidth)); + return lineWidth; + } +}; + +struct ActiveTexture { + using Type = uint8_t; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glActiveTexture(GL_TEXTURE0 + value)); + } + static Type Get() { + GLint activeTexture; + MBGL_CHECK_ERROR(glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture)); + return activeTexture - GL_TEXTURE0; + } +}; + +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 { + struct Type { GLfloat xfactor; GLfloat yfactor; }; + static const constexpr Type Default = { 1, 1 }; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glPixelZoom(value.xfactor, value.yfactor)); + } + static Type Get() { + Type value; + MBGL_CHECK_ERROR(glGetFloatv(GL_ZOOM_X, &value.xfactor)); + MBGL_CHECK_ERROR(glGetFloatv(GL_ZOOM_Y, &value.yfactor)); + return value; + } +}; + +constexpr bool operator!=(const PixelZoom::Type& a, const PixelZoom::Type& b) { + return a.xfactor != b.xfactor || a.yfactor != b.yfactor; +} + +struct RasterPos { + using Type = std::array<GLdouble, 4>; + static const constexpr Type Default = {{ 0, 0, 0, 0 }}; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glRasterPos4d(value[0], value[1], value[2], value[3])); + } + static Type Get() { + Type pos; + MBGL_CHECK_ERROR(glGetDoublev(GL_CURRENT_RASTER_POSITION, pos.data())); + return pos; + } +}; + +#endif // GL_ES_VERSION_2_0 + +struct BindTexture { + using Type = GLuint; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glBindTexture(GL_TEXTURE_2D, value)); + } + static Type Get() { + GLint texture; + MBGL_CHECK_ERROR(glGetIntegerv(GL_TEXTURE_BINDING_2D, &texture)); + return texture; + } +}; + +template <GLenum target> +struct BindBuffer { + static_assert(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER, + "target must be one of GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER"); + using Type = GLuint; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + MBGL_CHECK_ERROR(glBindBuffer(target, value)); + } + static Type Get() { + GLint binding; + MBGL_CHECK_ERROR(glGetIntegerv(target == GL_ARRAY_BUFFER ? GL_ARRAY_BUFFER_BINDING + : GL_ELEMENT_ARRAY_BUFFER_BINDING, + &binding)); + return binding; + } +}; + +template <GLenum target> +const typename BindBuffer<target>::Type BindBuffer<target>::Default; + +struct BindVAO { + using Type = GLuint; + static const constexpr Type Default = 0; + static void Set(const Type& value) { + if (gl::BindVertexArray) { + MBGL_CHECK_ERROR(gl::BindVertexArray(value)); + } + } +}; + + +} // namespace value +} // namespace gl +} // namespace mbgl diff --git a/src/mbgl/renderer/painter.cpp b/src/mbgl/renderer/painter.cpp index 438e4b5e47..2b3189cc55 100644 --- a/src/mbgl/renderer/painter.cpp +++ b/src/mbgl/renderer/painter.cpp @@ -48,8 +48,8 @@ Painter::Painter(const TransformState& state_, #endif // Reset GL values - config.setDirty(); - config.reset(); + config.setDirtyState(); + config.resetState(); } Painter::~Painter() = default; @@ -225,7 +225,7 @@ void Painter::render(const Style& style, const FrameData& frame_, SpriteAtlas& a } if (frame.contextMode == GLContextMode::Shared) { - config.setDirty(); + config.setDirtyState(); } } @@ -276,7 +276,7 @@ void Painter::renderPass(PaintParameters& parameters, config.stencilTest = GL_FALSE; setDepthSublayer(0); layer.as<CustomLayer>()->impl->render(state); - config.setDirty(); + config.setDirtyState(); config.bindFramebuffer.reset(); config.viewport.reset(); } else { diff --git a/src/mbgl/renderer/painter_debug.cpp b/src/mbgl/renderer/painter_debug.cpp index 8c15070cd5..adecc20518 100644 --- a/src/mbgl/renderer/painter_debug.cpp +++ b/src/mbgl/renderer/painter_debug.cpp @@ -6,8 +6,6 @@ #include <mbgl/util/string.hpp> #include <mbgl/gl/debugging.hpp> #include <mbgl/gl/gl.hpp> -#include <mbgl/gl/gl_values.hpp> -#include <mbgl/gl/gl_helper.hpp> #include <mbgl/util/color.hpp> namespace mbgl { |