gpui_kit_grid/state/stats.rs
1//! Timing knobs, profiling counters and the profiling clock.
2
3use std::time::Duration;
4
5use web_time::Instant;
6
7use crate::store::SNAPSHOT_INTERVAL;
8
9/// Timing knobs of a grid.
10#[derive(Clone, Copy, Debug)]
11pub struct GridTuning {
12 pub(super) min_rebuild_interval: Duration,
13 pub(super) pull_interval: Duration,
14}
15
16impl Default for GridTuning {
17 fn default() -> Self {
18 Self {
19 min_rebuild_interval: Duration::from_millis(100),
20 pull_interval: SNAPSHOT_INTERVAL,
21 }
22 }
23}
24
25impl GridTuning {
26 /// Rebuilds caused by data start at most this often (user actions
27 /// rebuild at once). Default 100 ms, like LiveGrid.
28 pub fn with_min_rebuild_interval(mut self, interval: Duration) -> Self {
29 self.min_rebuild_interval = interval;
30 self
31 }
32
33 /// Snapshots are pulled from the store at most this often. Default 8 ms,
34 /// the store's default publish interval
35 /// ([`StoreOptions::with_publish_interval`](crate::StoreOptions::with_publish_interval)).
36 pub fn with_pull_interval(mut self, interval: Duration) -> Self {
37 self.pull_interval = interval;
38 self
39 }
40}
41
42/// Counters for profiling a grid.
43#[derive(Clone, Copy, Debug, Default)]
44pub struct GridStats {
45 pub(super) frames: u64,
46 pub(super) rebuilds: u64,
47 pub(super) last_rebuild: Duration,
48 pub(super) max_rebuild: Duration,
49 pub(super) last_prepaint: Duration,
50 pub(super) last_header_render: Duration,
51 pub(super) last_pull: Duration,
52 pub(super) fade_wakeups: u64,
53 pub(super) visible_cells: usize,
54 pub(super) icons: usize,
55 pub(super) snapshots: u64,
56 pub(super) compactions: u64,
57 pub(super) tombstones: usize,
58 pub(super) fading_lines: usize,
59 pub(super) painted_captions: usize,
60 pub(super) a11y_rows: usize,
61 pub(super) a11y_cells: usize,
62 pub(super) last_a11y_plan: Duration,
63 // The tree.
64 pub(super) tree_cycles: usize,
65 // Elements in the body's rows.
66 pub(super) cell_hosts: usize,
67 pub(super) last_hosts_prepaint: Duration,
68 // Images in cells.
69 pub(super) images: usize,
70 // The drop target of the last drag move.
71 pub(super) last_drop_target: Duration,
72}
73
74impl GridStats {
75 /// Frames painted.
76 pub fn frames(&self) -> u64 {
77 self.frames
78 }
79
80 /// Projection rebuilds finished.
81 pub fn rebuilds(&self) -> u64 {
82 self.rebuilds
83 }
84
85 /// CPU time of the last rebuild (background thread).
86 pub fn last_rebuild(&self) -> Duration {
87 self.last_rebuild
88 }
89
90 /// CPU time of the slowest rebuild.
91 pub fn max_rebuild(&self) -> Duration {
92 self.max_rebuild
93 }
94
95 /// CPU time of the last frame plan (prepaint of the body).
96 pub fn last_prepaint(&self) -> Duration {
97 self.last_prepaint
98 }
99
100 /// CPU time of the last header build (its elements, in `render`).
101 pub fn last_header_render(&self) -> Duration {
102 self.last_header_render
103 }
104
105 /// CPU time of applying the last store snapshot on the UI thread: the
106 /// pull, with what removals do to the selection and the focus.
107 pub fn last_pull(&self) -> Duration {
108 self.last_pull
109 }
110
111 /// Repaints caused only by the highlight fade timer.
112 pub fn fade_wakeups(&self) -> u64 {
113 self.fade_wakeups
114 }
115
116 /// Cells planned in the last frame.
117 pub fn visible_cells(&self) -> usize {
118 self.visible_cells
119 }
120
121 /// Icons painted in the body in the last frame: change arrows
122 /// (`CellStyle::set_trend`), icons at the start of cells and icons of
123 /// `CellValue::Icon` cells.
124 pub fn icons(&self) -> usize {
125 self.icons
126 }
127
128 /// Images painted in the body in the last frame: the `CellValue::Image`
129 /// cells whose image was ready.
130 pub fn images(&self) -> usize {
131 self.images
132 }
133
134 /// Store snapshots pulled.
135 pub fn snapshots(&self) -> u64 {
136 self.snapshots
137 }
138
139 /// Projections compacted after removals (no sorting).
140 pub fn compactions(&self) -> u64 {
141 self.compactions
142 }
143
144 /// Removed rows skipped while painting the last frame, before the
145 /// projection caught up: rows without a removal fade, and fading rows
146 /// whose fade ended.
147 pub fn tombstones(&self) -> usize {
148 self.tombstones
149 }
150
151 /// Removed rows painted fading out in the last frame
152 /// ([`HighlightPolicy::with_removal_fade`]).
153 ///
154 /// [`HighlightPolicy::with_removal_fade`]: crate::HighlightPolicy::with_removal_fade
155 pub fn fading_lines(&self) -> usize {
156 self.fading_lines
157 }
158
159 /// Group captions painted in the last frame.
160 pub fn painted_captions(&self) -> usize {
161 self.painted_captions
162 }
163
164 /// Row nodes of the accessibility tree planned in the last frame: the
165 /// painted data and pinned rows, and group captions. Zero while
166 /// accessibility is off.
167 pub fn a11y_rows(&self) -> usize {
168 self.a11y_rows
169 }
170
171 /// Synthetic cell nodes planned in the last frame: the painted cells
172 /// but the focused one. Zero while accessibility is off.
173 pub fn a11y_cells(&self) -> usize {
174 self.a11y_cells
175 }
176
177 /// CPU time of the last frame's accessibility plan, after the cell walk
178 /// gathered its texts. Zero while accessibility is off. With
179 /// `LiveGridState::set_a11y_forced` in a window whose accessibility is
180 /// off (headless tests and benchmarks), it also builds the nodes GPUI
181 /// would build from the plan, so it times both.
182 pub fn last_a11y_plan(&self) -> Duration {
183 self.last_a11y_plan
184 }
185
186 // The tree's cycles.
187
188 /// Rows of the tree shown made roots because their parents form a cycle
189 /// (`Projection::tree_cycles`); 0 for a flat or grouped view. A row
190 /// that is its own parent is a root but no cycle.
191 pub fn tree_cycles(&self) -> usize {
192 self.tree_cycles
193 }
194
195 // Elements in the body's rows.
196
197 /// Cell hosts planned in the last frame: real elements in cells, such
198 /// as the elements of `Element` and `Control` columns and an open
199 /// editor.
200 pub fn cell_hosts(&self) -> usize {
201 self.cell_hosts
202 }
203
204 /// CPU time of the layout and prepaint of the last frame's row
205 /// elements, when it had cell hosts; zero otherwise.
206 pub fn last_hosts_prepaint(&self) -> Duration {
207 self.last_hosts_prepaint
208 }
209
210 /// Main-thread time the last move of a drag over the rows took to place
211 /// it: the hit test and the drop policy (S38).
212 pub fn last_drop_target(&self) -> Duration {
213 self.last_drop_target
214 }
215
216 /// These counters with `tree_cycles` of the projection shown.
217 pub(super) fn with_tree_cycles(mut self, tree_cycles: usize) -> Self {
218 self.tree_cycles = tree_cycles;
219 self
220 }
221}
222
223/// Profiling clock for job and frame durations: `std::time::Instant` on
224/// native targets and `performance.now()` in the browser (`web_time`), where
225/// `std::time::Instant::now` panics.
226pub(super) fn profile_start() -> Option<Instant> {
227 Some(Instant::now())
228}
229
230pub(super) fn profile_elapsed(started: Option<Instant>) -> Duration {
231 started.map_or(Duration::ZERO, |started| started.elapsed())
232}