Skip to content

Commit 6e67426

Browse files
Merge pull request #2728 from CapSoftware/perf/cursor-lookup-on-events
perf(recording): read the cursor image only on ticks that record an event
2 parents 2a61427 + 0b42795 commit 6e67426

1 file changed

Lines changed: 33 additions & 1 deletion

File tree

‎crates/recording/src/cursor.rs‎

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,17 @@ pub fn spawn_cursor_recorder(
572572
last_window_position = window_position;
573573
}
574574

575-
let cursor_id = if let Some(data) = get_cursor_data() {
575+
// The cursor image only labels this tick's move and click events,
576+
// and reading it builds a full TIFF of every representation
577+
// (~0.5 ms, ~580 KB on a Retina Mac), so skip it on ticks that
578+
// record neither.
579+
let buttons_changed = buttons_changed(
580+
&last_mouse_state.button_pressed,
581+
&mouse_state.button_pressed,
582+
);
583+
let cursor_id = if !position_changed && !buttons_changed && last_cursor_id.is_some() {
584+
last_cursor_id.clone()
585+
} else if let Some(data) = get_cursor_data() {
576586
let cursor_id = cursor_id_for_image(
577587
data,
578588
&mut response,
@@ -703,6 +713,15 @@ pub fn spawn_cursor_recorder(
703713
}
704714
}
705715

716+
/// Whether any button present in both samples changed state: the same pairs
717+
/// the click events below are generated from.
718+
fn buttons_changed(previous: &[bool], current: &[bool]) -> bool {
719+
previous
720+
.iter()
721+
.zip(current)
722+
.any(|(previous, current)| previous != current)
723+
}
724+
706725
fn cursor_id_for_image(
707726
data: CursorData,
708727
response: &mut CursorActorResponse,
@@ -1634,6 +1653,19 @@ mod cursor_image_tests {
16341653
}
16351654
}
16361655

1656+
#[test]
1657+
fn button_changes_match_the_pairs_clicks_are_built_from() {
1658+
assert!(!buttons_changed(
1659+
&[false, false, false],
1660+
&[false, false, false]
1661+
));
1662+
assert!(buttons_changed(&[false, false], &[false, true]));
1663+
assert!(buttons_changed(&[true], &[false]));
1664+
// Clicks only compare buttons present in both samples.
1665+
assert!(!buttons_changed(&[false], &[false, true]));
1666+
assert!(!buttons_changed(&[], &[true]));
1667+
}
1668+
16371669
#[test]
16381670
fn an_unchanged_cursor_image_reuses_its_id_without_hashing() {
16391671
let dir = tempfile::tempdir().unwrap();

0 commit comments

Comments
 (0)