1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use std::time::{Duration, Instant};

use freya_core::plugins::{FreyaPlugin, PluginEvent};
use freya_engine::prelude::{Color, ParagraphBuilder, ParagraphStyle, TextShadow, TextStyle};

#[derive(Default)]
pub struct PerformanceOverlayPlugin {
    frames: Vec<Instant>,
    started_render: Option<Instant>,
    started_layout: Option<Instant>,
    finished_layout: Option<Duration>,
}

impl FreyaPlugin for PerformanceOverlayPlugin {
    fn on_event(&mut self, event: &PluginEvent) {
        match event {
            PluginEvent::StartedLayout(_) => self.started_layout = Some(Instant::now()),
            PluginEvent::FinishedLayout(_) => {
                self.finished_layout = Some(self.started_layout.unwrap().elapsed())
            }
            PluginEvent::StartedRender(_canvas, _font_collection) => {
                self.started_render = Some(Instant::now())
            }
            PluginEvent::FinishedRender(canvas, font_collection) => {
                let started_render = self.started_render.take().unwrap();
                let finished_layout = self.finished_layout.unwrap();

                let now = Instant::now();

                self.frames
                    .retain(|frame| now.duration_since(*frame).as_millis() < 1000);

                self.frames.push(now);

                // Render the texts
                let mut paragraph_builder =
                    ParagraphBuilder::new(&ParagraphStyle::default(), *font_collection);
                let mut text_style = TextStyle::default();
                text_style.set_color(Color::from_rgb(63, 255, 0));
                text_style.add_shadow(TextShadow::new(
                    Color::from_rgb(60, 60, 60),
                    (0.0, 1.0),
                    1.0,
                ));
                paragraph_builder.push_style(&text_style);

                // FPS
                let mut text_style = TextStyle::default();
                text_style.set_color(Color::from_rgb(63, 255, 0));
                text_style.add_shadow(TextShadow::new(
                    Color::from_rgb(60, 60, 60),
                    (0.0, 1.0),
                    1.0,
                ));
                text_style.set_font_size(30.0);
                paragraph_builder.push_style(&text_style);
                paragraph_builder.add_text(format!("{} \n", self.frames.len()));

                // Rendering time
                let mut text_style = TextStyle::default();
                text_style.set_color(Color::from_rgb(63, 255, 0));
                text_style.add_shadow(TextShadow::new(
                    Color::from_rgb(60, 60, 60),
                    (0.0, 1.0),
                    1.0,
                ));
                text_style.set_font_size(18.0);
                paragraph_builder.push_style(&text_style);
                paragraph_builder.add_text(format!(
                    "Rendering: {}ms \n",
                    started_render.elapsed().as_millis()
                ));

                // Layout time
                let mut text_style = TextStyle::default();
                text_style.set_color(Color::from_rgb(63, 255, 0));
                text_style.add_shadow(TextShadow::new(
                    Color::from_rgb(60, 60, 60),
                    (0.0, 1.0),
                    1.0,
                ));
                text_style.set_font_size(18.0);
                paragraph_builder.push_style(&text_style);
                paragraph_builder.add_text(format!("Layout: {}ms \n", finished_layout.as_millis()));

                let mut paragraph = paragraph_builder.build();
                paragraph.layout(f32::MAX);
                paragraph.paint(canvas, (5.0, 0.0));
            }
            _ => {}
        }
    }
}