1 #pragma once 2 3 #include <mbgl/gl/program.hpp> 4 #include <mbgl/gl/features.hpp> 5 #include <mbgl/programs/segment.hpp> 6 #include <mbgl/programs/binary_program.hpp> 7 #include <mbgl/programs/attributes.hpp> 8 #include <mbgl/programs/program_parameters.hpp> 9 #include <mbgl/style/paint_property.hpp> 10 #include <mbgl/shaders/shaders.hpp> 11 #include <mbgl/util/io.hpp> 12 13 #include <unordered_map> 14 15 namespace mbgl { 16 17 template <class Shaders, 18 class Primitive, 19 class LayoutAttrs, 20 class Uniforms, 21 class PaintProps> 22 class Program { 23 public: 24 using LayoutAttributes = LayoutAttrs; 25 using LayoutVertex = typename LayoutAttributes::Vertex; 26 27 using PaintProperties = PaintProps; 28 using PaintPropertyBinders = typename PaintProperties::Binders; 29 using PaintAttributes = typename PaintPropertyBinders::Attributes; 30 using Attributes = gl::ConcatenateAttributes<LayoutAttributes, PaintAttributes>; 31 32 using UniformValues = typename Uniforms::Values; 33 using PaintUniforms = typename PaintPropertyBinders::Uniforms; 34 using AllUniforms = gl::ConcatenateUniforms<Uniforms, PaintUniforms>; 35 36 using ProgramType = gl::Program<Primitive, Attributes, AllUniforms>; 37 38 ProgramType program; 39 Program(gl::Context & context,const ProgramParameters & programParameters)40 Program(gl::Context& context, const ProgramParameters& programParameters) 41 : program(ProgramType::createProgram( 42 context, 43 programParameters, 44 Shaders::name, 45 Shaders::vertexSource, 46 Shaders::fragmentSource)) { 47 } 48 computeAllUniformValues(const UniformValues & uniformValues,const PaintPropertyBinders & paintPropertyBinders,const typename PaintProperties::PossiblyEvaluated & currentProperties,float currentZoom)49 static typename AllUniforms::Values computeAllUniformValues( 50 const UniformValues& uniformValues, 51 const PaintPropertyBinders& paintPropertyBinders, 52 const typename PaintProperties::PossiblyEvaluated& currentProperties, 53 float currentZoom) { 54 return uniformValues 55 .concat(paintPropertyBinders.uniformValues(currentZoom, currentProperties)); 56 } 57 computeAllAttributeBindings(const gl::VertexBuffer<LayoutVertex> & layoutVertexBuffer,const PaintPropertyBinders & paintPropertyBinders,const typename PaintProperties::PossiblyEvaluated & currentProperties)58 static typename Attributes::Bindings computeAllAttributeBindings( 59 const gl::VertexBuffer<LayoutVertex>& layoutVertexBuffer, 60 const PaintPropertyBinders& paintPropertyBinders, 61 const typename PaintProperties::PossiblyEvaluated& currentProperties) { 62 return LayoutAttributes::bindings(layoutVertexBuffer) 63 .concat(paintPropertyBinders.attributeBindings(currentProperties)); 64 } 65 activeBindingCount(const typename Attributes::Bindings & allAttributeBindings)66 static uint32_t activeBindingCount(const typename Attributes::Bindings& allAttributeBindings) { 67 return Attributes::activeBindingCount(allAttributeBindings); 68 } 69 70 template <class DrawMode> draw(gl::Context & context,DrawMode drawMode,gl::DepthMode depthMode,gl::StencilMode stencilMode,gl::ColorMode colorMode,const gl::IndexBuffer<DrawMode> & indexBuffer,const SegmentVector<Attributes> & segments,const typename AllUniforms::Values & allUniformValues,const typename Attributes::Bindings & allAttributeBindings,const std::string & layerID)71 void draw(gl::Context& context, 72 DrawMode drawMode, 73 gl::DepthMode depthMode, 74 gl::StencilMode stencilMode, 75 gl::ColorMode colorMode, 76 const gl::IndexBuffer<DrawMode>& indexBuffer, 77 const SegmentVector<Attributes>& segments, 78 const typename AllUniforms::Values& allUniformValues, 79 const typename Attributes::Bindings& allAttributeBindings, 80 const std::string& layerID) { 81 for (auto& segment : segments) { 82 auto vertexArrayIt = segment.vertexArrays.find(layerID); 83 84 if (vertexArrayIt == segment.vertexArrays.end()) { 85 vertexArrayIt = segment.vertexArrays.emplace(layerID, context.createVertexArray()).first; 86 } 87 88 program.draw( 89 context, 90 std::move(drawMode), 91 std::move(depthMode), 92 std::move(stencilMode), 93 std::move(colorMode), 94 allUniformValues, 95 vertexArrayIt->second, 96 Attributes::offsetBindings(allAttributeBindings, segment.vertexOffset), 97 indexBuffer, 98 segment.indexOffset, 99 segment.indexLength); 100 } 101 } 102 }; 103 104 template <class Program> 105 class ProgramMap { 106 public: 107 using PaintProperties = typename Program::PaintProperties; 108 using PaintPropertyBinders = typename Program::PaintPropertyBinders; 109 using Bitset = typename PaintPropertyBinders::Bitset; 110 ProgramMap(gl::Context & context_,ProgramParameters parameters_)111 ProgramMap(gl::Context& context_, ProgramParameters parameters_) 112 : context(context_), 113 parameters(std::move(parameters_)) { 114 } 115 get(const typename PaintProperties::PossiblyEvaluated & currentProperties)116 Program& get(const typename PaintProperties::PossiblyEvaluated& currentProperties) { 117 Bitset bits = PaintPropertyBinders::constants(currentProperties); 118 auto it = programs.find(bits); 119 if (it != programs.end()) { 120 return it->second; 121 } 122 return programs.emplace(std::piecewise_construct, 123 std::forward_as_tuple(bits), 124 std::forward_as_tuple(context, 125 parameters.withAdditionalDefines(PaintPropertyBinders::defines(currentProperties)))).first->second; 126 } 127 128 private: 129 gl::Context& context; 130 ProgramParameters parameters; 131 std::unordered_map<Bitset, Program> programs; 132 }; 133 134 } // namespace mbgl 135