diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2017-06-05 12:15:27 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2017-06-13 12:21:50 -0700 |
commit | 9d276f3b0f0e5f1b5089a6cd727927361e6634ac (patch) | |
tree | bbf0c446055126f060e8ee759b7b71281dea8f80 /src/mbgl/renderer/paint_property_binder.hpp | |
parent | 18b50f51b4fa14b9f2fe6f865dc47490b22e74c6 (diff) | |
download | qtlocation-mapboxgl-9d276f3b0f0e5f1b5089a6cd727927361e6634ac.tar.gz |
[core] Dynamic program compilation for data-driven properties
Diffstat (limited to 'src/mbgl/renderer/paint_property_binder.hpp')
-rw-r--r-- | src/mbgl/renderer/paint_property_binder.hpp | 60 |
1 files changed, 43 insertions, 17 deletions
diff --git a/src/mbgl/renderer/paint_property_binder.hpp b/src/mbgl/renderer/paint_property_binder.hpp index 8291301d33..91ddcac2b3 100644 --- a/src/mbgl/renderer/paint_property_binder.hpp +++ b/src/mbgl/renderer/paint_property_binder.hpp @@ -7,6 +7,8 @@ #include <mbgl/renderer/possibly_evaluated_property_value.hpp> #include <mbgl/renderer/paint_property_statistics.hpp> +#include <bitset> + namespace mbgl { /* @@ -55,8 +57,7 @@ std::array<float, N*2> zoomInterpolatedAttributeValue(const std::array<float, N> * For _constant_ properties -- those whose value is a constant, or the constant result of evaluating a camera function at a particular camera position -- we - don't need a vertex buffer, and can instead use a constant attribute binding - via the `glVertexAttrib*` family of functions. + don't need a vertex buffer, and instead use a uniform. * For source functions, we use a vertex buffer with a single attribute value, the evaluated result of the source function for the given feature. * For composite functions, we use a vertex buffer with two attributes: min and @@ -67,15 +68,8 @@ std::array<float, N*2> zoomInterpolatedAttributeValue(const std::array<float, N> between the min and max value at the final displayed zoom level. The use of a uniform allows us to cheaply update the value on every frame. - Note that the shader source is the same regardless of the strategy used to bind - the attribute -- in all cases the attribute is declared as a vec2, in order to - support composite min and max values (color attributes use a vec4 with special - packing). When the constant or source function strategies are used, the - interpolation uniform value is set to zero, and the second attribute element is - unused. This differs from the GL JS implementation, which dynamically generates - shader source based on the strategy used. We found that in WebGL, using - `glVertexAttrib*` was unnacceptably slow. Additionally, in GL Native we have - implemented binary shader caching, which works better if the shaders are constant. + Note that the shader source varies depending on whether we're using a uniform or + attribute. Like GL JS, we dynamically compile shaders at runtime to accomodate this. */ template <class T, class A> class PaintPropertyBinder { @@ -171,9 +165,13 @@ public: return 0.0f; } - T uniformValue(const PossiblyEvaluatedPropertyValue<T>&) const override { - // Uniform values for vertex attribute arrays are unused. - return {}; + T uniformValue(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { + if (currentValue.isConstant()) { + return *currentValue.constant(); + } else { + // Uniform values for vertex attribute arrays are unused. + return {}; + } } private: @@ -231,9 +229,13 @@ public: return util::interpolationFactor(1.0f, std::get<0>(coveringRanges), currentZoom); } - T uniformValue(const PossiblyEvaluatedPropertyValue<T>&) const override { - // Uniform values for vertex attribute arrays are unused. - return {}; + T uniformValue(const PossiblyEvaluatedPropertyValue<T>& currentValue) const override { + if (currentValue.isConstant()) { + return *currentValue.constant(); + } else { + // Uniform values for vertex attribute arrays are unused. + return {}; + } } private: @@ -343,6 +345,30 @@ public: return binders.template get<P>()->statistics; } + + using Bitset = std::bitset<sizeof...(Ps)>; + + template <class EvaluatedProperties> + static Bitset constants(const EvaluatedProperties& currentProperties) { + Bitset result; + util::ignore({ + result.set(TypeIndex<Ps, Ps...>::value, + currentProperties.template get<Ps>().isConstant())... + }); + return result; + } + + template <class EvaluatedProperties> + static std::vector<std::string> defines(const EvaluatedProperties& currentProperties) { + std::vector<std::string> result; + util::ignore({ + (result.push_back(currentProperties.template get<Ps>().isConstant() + ? std::string("#define HAS_UNIFORM_") + Ps::Uniform::name() + : std::string()), 0)... + }); + return result; + } + private: Binders binders; }; |