maplibre/render/systems/
graph_runner_system.rs

1//! Executes the [`RenderGraph`] current render graph.
2
3use std::{borrow::Cow, error::Error};
4
5use log::error;
6
7use crate::{
8    context::MapContext,
9    render::{eventually::Eventually::Initialized, graph_runner::RenderGraphRunner, Renderer},
10    tcs::system::{System, SystemError, SystemResult},
11};
12
13/// Updates the [`RenderGraph`] with all of its nodes and then runs it to render the entire frame.
14#[derive(Default)]
15pub struct GraphRunnerSystem;
16
17impl System for GraphRunnerSystem {
18    fn name(&self) -> Cow<'static, str> {
19        "graph_runner".into()
20    }
21
22    fn run(
23        &mut self,
24        MapContext {
25            world,
26            renderer:
27                Renderer {
28                    device,
29                    queue,
30                    resources: state,
31                    render_graph,
32                    ..
33                },
34            ..
35        }: &mut MapContext,
36    ) -> SystemResult {
37        render_graph.update(state);
38
39        if let Err(e) = RenderGraphRunner::run(render_graph, device, queue, state, world) {
40            error!("Error running render graph:");
41            {
42                let mut src: &dyn Error = &e;
43                loop {
44                    error!("> {src}");
45                    match src.source() {
46                        Some(s) => src = s,
47                        None => break,
48                    }
49                }
50            }
51
52            // TODO: Replace panic with a graceful exit in the event loop
53            // if e.should_exit() { *control_flow = ControlFlow::Exit; }
54            panic!("Error running render graph: {e:?}");
55        }
56
57        {
58            let _span = tracing::info_span!("present_frames").entered();
59
60            let Initialized(render_target) = state.render_target.take() else {
61                return Err(SystemError::Dependencies);
62            };
63
64            if let Some(surface_texture) = render_target.take_surface_texture() {
65                surface_texture.present();
66            }
67
68            #[cfg(feature = "tracing-tracy")]
69            tracing::event!(
70                tracing::Level::INFO,
71                message = "finished frame",
72                tracy.frame_mark = true
73            );
74
75            Ok(())
76        }
77    }
78}