1 #pragma once
2 
3 #include <mbgl/renderer/bucket.hpp>
4 #include <mbgl/map/mode.hpp>
5 #include <mbgl/gl/vertex_buffer.hpp>
6 #include <mbgl/gl/index_buffer.hpp>
7 #include <mbgl/programs/segment.hpp>
8 #include <mbgl/programs/symbol_program.hpp>
9 #include <mbgl/programs/collision_box_program.hpp>
10 #include <mbgl/text/glyph_range.hpp>
11 #include <mbgl/style/layers/symbol_layer_properties.hpp>
12 #include <mbgl/layout/symbol_feature.hpp>
13 #include <mbgl/layout/symbol_instance.hpp>
14 
15 #include <vector>
16 
17 namespace mbgl {
18 
19 class PlacedSymbol {
20 public:
PlacedSymbol(Point<float> anchorPoint_,uint16_t segment_,float lowerSize_,float upperSize_,std::array<float,2> lineOffset_,WritingModeType writingModes_,GeometryCoordinates line_,std::vector<float> tileDistances_)21     PlacedSymbol(Point<float> anchorPoint_, uint16_t segment_, float lowerSize_, float upperSize_,
22             std::array<float, 2> lineOffset_, WritingModeType writingModes_, GeometryCoordinates line_, std::vector<float> tileDistances_) :
23         anchorPoint(anchorPoint_), segment(segment_), lowerSize(lowerSize_), upperSize(upperSize_),
24         lineOffset(lineOffset_), writingModes(writingModes_), line(std::move(line_)), tileDistances(std::move(tileDistances_)), hidden(false), vertexStartIndex(0)
25     {
26     }
27     Point<float> anchorPoint;
28     uint16_t segment;
29     float lowerSize;
30     float upperSize;
31     std::array<float, 2> lineOffset;
32     WritingModeType writingModes;
33     GeometryCoordinates line;
34     std::vector<float> tileDistances;
35     std::vector<float> glyphOffsets;
36     bool hidden;
37     size_t vertexStartIndex;
38 };
39 
40 class SymbolBucket : public Bucket {
41 public:
42     SymbolBucket(style::SymbolLayoutProperties::PossiblyEvaluated,
43                  const std::map<std::string, std::pair<style::IconPaintProperties::PossiblyEvaluated, style::TextPaintProperties::PossiblyEvaluated>>&,
44                  const style::DataDrivenPropertyValue<float>& textSize,
45                  const style::DataDrivenPropertyValue<float>& iconSize,
46                  float zoom,
47                  bool sdfIcons,
48                  bool iconsNeedLinear,
49                  bool sortFeaturesByY,
50                  const std::string bucketLeaderID,
51                  const std::vector<SymbolInstance>&&);
52 
53     void upload(gl::Context&) override;
54     bool hasData() const override;
55     bool hasTextData() const;
56     bool hasIconData() const;
57     bool hasCollisionBoxData() const;
58     bool hasCollisionCircleData() const;
59 
60     void updateOpacity();
61     void sortFeatures(const float angle);
62 
63     const style::SymbolLayoutProperties::PossiblyEvaluated layout;
64     const bool sdfIcons;
65     const bool iconsNeedLinear;
66     const bool sortFeaturesByY;
67 
68     const std::string bucketLeaderID;
69 
70     optional<float> sortedAngle;
71 
72     bool staticUploaded = false;
73     bool placementChangesUploaded = false;
74     bool dynamicUploaded = false;
75     bool sortUploaded = false;
76 
77     std::vector<SymbolInstance> symbolInstances;
78 
79     std::map<std::string, std::pair<
80         SymbolIconProgram::PaintPropertyBinders,
81         SymbolSDFTextProgram::PaintPropertyBinders>> paintPropertyBinders;
82 
83     std::unique_ptr<SymbolSizeBinder> textSizeBinder;
84 
85     struct TextBuffer {
86         gl::VertexVector<SymbolLayoutVertex> vertices;
87         gl::VertexVector<SymbolDynamicLayoutAttributes::Vertex> dynamicVertices;
88         gl::VertexVector<SymbolOpacityAttributes::Vertex> opacityVertices;
89         gl::IndexVector<gl::Triangles> triangles;
90         SegmentVector<SymbolTextAttributes> segments;
91         std::vector<PlacedSymbol> placedSymbols;
92 
93         optional<gl::VertexBuffer<SymbolLayoutVertex>> vertexBuffer;
94         optional<gl::VertexBuffer<SymbolDynamicLayoutAttributes::Vertex>> dynamicVertexBuffer;
95         optional<gl::VertexBuffer<SymbolOpacityAttributes::Vertex>> opacityVertexBuffer;
96         optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
97     } text;
98 
99     std::unique_ptr<SymbolSizeBinder> iconSizeBinder;
100 
101     struct IconBuffer {
102         gl::VertexVector<SymbolLayoutVertex> vertices;
103         gl::VertexVector<SymbolDynamicLayoutAttributes::Vertex> dynamicVertices;
104         gl::VertexVector<SymbolOpacityAttributes::Vertex> opacityVertices;
105         gl::IndexVector<gl::Triangles> triangles;
106         SegmentVector<SymbolIconAttributes> segments;
107         std::vector<PlacedSymbol> placedSymbols;
108         PremultipliedImage atlasImage;
109 
110         optional<gl::VertexBuffer<SymbolLayoutVertex>> vertexBuffer;
111         optional<gl::VertexBuffer<SymbolDynamicLayoutAttributes::Vertex>> dynamicVertexBuffer;
112         optional<gl::VertexBuffer<SymbolOpacityAttributes::Vertex>> opacityVertexBuffer;
113         optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
114     } icon;
115 
116     struct CollisionBuffer {
117         gl::VertexVector<CollisionBoxLayoutAttributes::Vertex> vertices;
118         gl::VertexVector<CollisionBoxDynamicAttributes::Vertex> dynamicVertices;
119         SegmentVector<CollisionBoxProgram::Attributes> segments;
120 
121         optional<gl::VertexBuffer<CollisionBoxLayoutAttributes::Vertex>> vertexBuffer;
122         optional<gl::VertexBuffer<CollisionBoxDynamicAttributes::Vertex>> dynamicVertexBuffer;
123     };
124 
125     struct CollisionBoxBuffer : public CollisionBuffer {
126         gl::IndexVector<gl::Lines> lines;
127         optional<gl::IndexBuffer<gl::Lines>> indexBuffer;
128     } collisionBox;
129 
130     struct CollisionCircleBuffer : public CollisionBuffer {
131         gl::IndexVector<gl::Triangles> triangles;
132         optional<gl::IndexBuffer<gl::Triangles>> indexBuffer;
133     } collisionCircle;
134 
135     uint32_t bucketInstanceId = 0;
136     bool justReloaded = false;
137 
138     std::shared_ptr<std::vector<size_t>> featureSortOrder;
139 };
140 
141 template <>
is() const142 inline bool Bucket::is<SymbolBucket>() const {
143     return layerType == style::LayerType::Symbol;
144 }
145 
146 } // namespace mbgl
147