maplibre/vector/
queue_system.rs

1//! Queues [PhaseItems](crate::render::render_phase::PhaseItem) for rendering.
2use crate::{
3    context::MapContext,
4    render::{
5        eventually::{Eventually, Eventually::Initialized},
6        render_commands::DrawMasks,
7        render_phase::{DrawState, LayerItem, RenderPhase, TileMaskItem},
8        tile_view_pattern::WgpuTileViewPattern,
9    },
10    tcs::{
11        system::{SystemError, SystemResult},
12        tiles::Tile,
13    },
14    vector::{
15        render_commands::{DrawLineTiles, DrawVectorTiles},
16        VectorBufferPool,
17    },
18};
19
20pub fn queue_system(MapContext { world, .. }: &mut MapContext) -> SystemResult {
21    let Some((
22        Initialized(tile_view_pattern),
23        Initialized(buffer_pool),
24        mask_phase,
25        layer_item_phase,
26    )) = world.resources.query_mut::<(
27        &mut Eventually<WgpuTileViewPattern>,
28        &mut Eventually<VectorBufferPool>,
29        &mut RenderPhase<TileMaskItem>,
30        &mut RenderPhase<LayerItem>,
31    )>()
32    else {
33        return Err(SystemError::Dependencies);
34    };
35
36    let buffer_pool_index = buffer_pool.index();
37
38    for view_tile in tile_view_pattern.iter() {
39        let coords = &view_tile.coords();
40        tracing::trace!("Drawing tile at {coords}");
41
42        // draw tile normal or the source e.g. parent or children
43        view_tile.render(|source_shape| {
44            // Draw masks for all source_shapes
45            mask_phase.add(TileMaskItem {
46                draw_function: Box::new(DrawState::<TileMaskItem, DrawMasks>::new()),
47                source_shape: source_shape.clone(),
48            });
49
50            if let Some(layer_entries) = buffer_pool_index.get_layers(source_shape.coords()) {
51                for layer_entry in layer_entries {
52                    // Choose fill vs line pipeline based on layer type
53                    let is_line = layer_entry.style_layer.type_ == "line";
54                    let draw_function: Box<dyn crate::render::render_phase::Draw<LayerItem>> =
55                        if is_line {
56                            Box::new(DrawState::<LayerItem, DrawLineTiles>::new())
57                        } else {
58                            Box::new(DrawState::<LayerItem, DrawVectorTiles>::new())
59                        };
60
61                    layer_item_phase.add(LayerItem {
62                        draw_function,
63                        index: layer_entry.style_layer.index,
64                        is_line,
65                        style_layer: layer_entry.style_layer.id.clone(),
66                        tile: Tile {
67                            coords: layer_entry.coords,
68                        },
69                        source_shape: source_shape.clone(),
70                    });
71                }
72            }
73        });
74    }
75
76    Ok(())
77}