summaryrefslogtreecommitdiff
path: root/src/mbgl/renderer/paint_property_binder.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mbgl/renderer/paint_property_binder.hpp')
-rw-r--r--src/mbgl/renderer/paint_property_binder.hpp60
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 a4bea24bbf..062b77888e 100644
--- a/src/mbgl/renderer/paint_property_binder.hpp
+++ b/src/mbgl/renderer/paint_property_binder.hpp
@@ -6,6 +6,8 @@
#include <mbgl/util/type_list.hpp>
#include <mbgl/renderer/paint_property_statistics.hpp>
+#include <bitset>
+
namespace mbgl {
/*
@@ -54,8 +56,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
@@ -66,15 +67,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 {
@@ -170,9 +164,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:
@@ -230,9 +228,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:
@@ -342,6 +344,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;
};