maplibre/sdf/
upload_system.rs1use std::iter;
4
5use crate::{
6 context::MapContext,
7 coords::ViewRegion,
8 render::{
9 eventually::{Eventually, Eventually::Initialized},
10 shaders::{SDFShaderFeatureMetadata, ShaderLayerMetadata},
11 tile_view_pattern::DEFAULT_TILE_SIZE,
12 view_state::ViewStatePadding,
13 Renderer,
14 },
15 sdf::{SymbolBufferPool, SymbolLayerData, SymbolLayersDataComponent},
16 style::{layer::LayerPaint, Style},
17 tcs::{
18 system::{SystemError, SystemResult},
19 tiles::Tiles,
20 },
21};
22
23pub fn upload_system(
24 MapContext {
25 world,
26 style,
27 view_state,
28 renderer: Renderer { queue, .. },
29 ..
30 }: &mut MapContext,
31) -> SystemResult {
32 let Some(Initialized(symbol_buffer_pool)) = world
33 .resources
34 .query_mut::<&mut Eventually<SymbolBufferPool>>()
35 else {
36 return Err(SystemError::Dependencies);
37 };
38
39 let view_region = view_state.create_view_region(
40 view_state.zoom().zoom_level(DEFAULT_TILE_SIZE),
41 ViewStatePadding::Loose,
42 );
43
44 let zoom = view_state.zoom().level();
45
46 if let Some(view_region) = &view_region {
47 upload_symbol_layer(
48 symbol_buffer_pool,
49 queue,
50 &mut world.tiles,
51 style,
52 view_region,
53 zoom,
54 );
55 }
56
57 Ok(())
58}
59
60fn upload_symbol_layer(
62 symbol_buffer_pool: &mut SymbolBufferPool,
63 queue: &wgpu::Queue,
64 tiles: &mut Tiles,
65 style: &Style,
66 view_region: &ViewRegion,
67 zoom: f32,
68) {
69 for coords in view_region.iter() {
71 let Some(vector_layers) = tiles.query_mut::<&SymbolLayersDataComponent>(coords) else {
72 continue;
73 };
74
75 let loaded_layers = symbol_buffer_pool
76 .get_loaded_style_layers_at(coords)
77 .unwrap_or_default();
78
79 let available_layers = vector_layers
80 .layers
81 .iter()
82 .filter(|data| !loaded_layers.contains(data.source_layer.as_str()))
83 .collect::<Vec<_>>();
84
85 for style_layer in &style.layers {
86 let layer_id = &style_layer.id;
87 let source_layer = match style_layer.source_layer.as_ref() {
88 Some(layer) => layer,
89 None => {
90 log::trace!("style layer {layer_id} does not have a source layer");
91 continue;
92 }
93 };
94
95 let Some(SymbolLayerData {
96 coords,
97 features,
98 new_buffer: buffer,
100 ..
101 }) = available_layers
102 .iter()
103 .find(|layer| source_layer.as_str() == layer.source_layer)
104 else {
105 continue;
106 };
107
108 let metadata_count = if features.is_empty() {
111 buffer.buffer.vertices.len()
112 } else {
113 features
114 .last()
115 .map(|feature| feature.indices.end)
116 .unwrap_or_default()
117 };
118 let feature_metadata = iter::repeat(SDFShaderFeatureMetadata { opacity: 1.0 })
119 .take(metadata_count)
120 .collect::<Vec<_>>();
121
122 if buffer.buffer.indices.is_empty() {
124 continue;
125 }
126
127 let text_size = match &style_layer.paint {
129 Some(LayerPaint::Symbol(paint)) => paint
130 .text_size
131 .as_ref()
132 .map(|s| s.evaluate_at_zoom(zoom))
133 .unwrap_or(16.0),
134 _ => 16.0,
135 };
136
137 log::debug!("Allocating geometry at {coords}");
138 symbol_buffer_pool.allocate_layer_geometry(
139 queue,
140 *coords,
141 style_layer.clone(),
142 buffer,
143 ShaderLayerMetadata {
144 z_index: style_layer.index as f32,
145 line_width: text_size, },
147 &feature_metadata,
148 );
149 }
150 }
151}