Skip to main content

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}