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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
//! A realtime performance HUD for GPUI applications: frames per second, a
//! rolling frame time chart, and this process' GPU, CPU and memory usage.
//!
//! Frame data comes from GPUI's own frame trace
//! ([`gpui::FrameTimingCollector`]). The interval counts frames *presented*,
//! stamped with their own present time, so it agrees with the platform's
//! overlay (Metal's HUD counts the same drawables); the frame cost is what the
//! framework actually spent in `Window::draw`, rather than an approximation
//! measured from the outside. The headline rate is derived from that cost —
//! the HUD never drives the frame loop, so nothing it reports is something it
//! caused.
//!
//! Render it wherever it should appear, guarded by your own flag:
//!
//! ```no_run
//! # use gpui::{prelude::*, *};
//! # use gpui_fps::fps_monitor;
//! # struct Example { show_fps: bool }
//! # impl Render for Example {
//! fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
//! div()
//! .relative()
//! .size_full()
//! .child("your app")
//! .when(self.show_fps, |this| this.child(fps_monitor(window, cx)))
//! }
//! # }
//! ```
//!
//! The returned overlay can change its corner and its frame budget. A custom palette or an
//! embedded rather than overlaid HUD is built by composing [`FpsMonitor`] and
//! [`FpsOverlay`] directly.
//!
//! This crate depends only on `gpui`, so it can be used from any GPUI
//! application.
pub use FpsMonitor;
pub use FpsOverlay;
use ;
use ;
/// The performance HUD, pinned to the top right of its parent.
///
/// The parent element must be `relative()`, since the HUD positions itself
/// absolutely. Call this at most once per window — a second call renders the
/// same monitor twice.
///
/// Whether the HUD is on screen is the caller's to decide; render this only
/// when it should be visible:
///
/// ```no_run
/// # use gpui::{prelude::*, *};
/// # use gpui_fps::fps_monitor;
/// # struct Example { show_fps: bool }
/// # impl Render for Example {
/// fn render(&mut self, window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
/// div()
/// .relative()
/// .size_full()
/// .child("your app")
/// .when(self.show_fps, |this| this.child(fps_monitor(window, cx)))
/// }
/// # }
/// ```
///
/// The monitor behind it is created on first use and reused afterwards, one per
/// window, so this can be called straight from `render` every frame.
/// The monitor [`fps_monitor`] reuses for each window.
///
/// Entries outlive their window; the leak is one small entity per window that
/// ever showed the HUD, which is not worth tracking window closes for.
;
static TRACE_STATE: = new;
/// Keeps GPUI's frame trace enabled for as long as it is alive.
///
/// [`gpui::profiler::set_trace_enabled`] is a process-wide switch, and turning it
/// off clears the recorded buffer. A monitor therefore must not disable it
/// while another monitor — or the host application's own profiling — still
/// depends on it, so guards are reference counted and the switch is only
/// restored by the last one. If tracing was already on before the first guard,
/// it is never turned off.
pub