From 9d276f3b0f0e5f1b5089a6cd727927361e6634ac Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Mon, 5 Jun 2017 12:15:27 -0700 Subject: [core] Dynamic program compilation for data-driven properties --- src/mbgl/renderer/paint_property_binder.hpp | 60 +++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 17 deletions(-) (limited to 'src/mbgl/renderer/paint_property_binder.hpp') 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 #include +#include + namespace mbgl { /* @@ -55,8 +57,7 @@ std::array zoomInterpolatedAttributeValue(const std::array * 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 zoomInterpolatedAttributeValue(const std::array 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 PaintPropertyBinder { @@ -171,9 +165,13 @@ public: return 0.0f; } - T uniformValue(const PossiblyEvaluatedPropertyValue&) const override { - // Uniform values for vertex attribute arrays are unused. - return {}; + T uniformValue(const PossiblyEvaluatedPropertyValue& 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&) const override { - // Uniform values for vertex attribute arrays are unused. - return {}; + T uniformValue(const PossiblyEvaluatedPropertyValue& 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

()->statistics; } + + using Bitset = std::bitset; + + template + static Bitset constants(const EvaluatedProperties& currentProperties) { + Bitset result; + util::ignore({ + result.set(TypeIndex::value, + currentProperties.template get().isConstant())... + }); + return result; + } + + template + static std::vector defines(const EvaluatedProperties& currentProperties) { + std::vector result; + util::ignore({ + (result.push_back(currentProperties.template get().isConstant() + ? std::string("#define HAS_UNIFORM_") + Ps::Uniform::name() + : std::string()), 0)... + }); + return result; + } + private: Binders binders; }; -- cgit v1.2.1