Commit e3e5f00d41e2
tarball1 file changed+75-1
@@ -53,7 +53,11 @@ impl Budget {
5353
}5454
5555
pub fn ns(&self) -> u64 {56
- let mut renders: Vec<u64> = self.renders.iter().copied().collect();56
+ let mut buf = [0; Self::KEEP];57
+ let renders = &mut buf[..self.renders.len()];58
+ for (slot, r) in renders.iter_mut().zip(&self.renders) {59
+ *slot = *r;60
+ }5761
renders.sort_unstable();5862
let p90 = renders5963
.get(renders.len().saturating_sub(1) * 9 / 10)@@ -85,3 +89,73 @@ impl Budget {
8589
self.slack_ns = self.slack_ns.saturating_sub(Self::DECAY_NS).max(floor);8690
}8791
}92
+93
+#[cfg(test)]94
+mod tests {95
+ use super::*;96
+97
+ const REFRESH: u64 = 6_060_606;98
+99
+ #[test]100
+ fn one_slow_render_does_not_move_the_budget() {101
+ let mut b = Budget::new();102
+ for _ in 0..31 {103
+ b.record(1_000_000);104
+ }105
+ b.record(9_000_000);106
+ assert_eq!(b.ns(), 1_000_000 + b.slack_ns);107
+ }108
+109
+ #[test]110
+ fn a_miss_holds_its_slack_before_decaying() {111
+ let mut b = Budget::new();112
+ b.missed(REFRESH);113
+ let held = b.slack_ns;114
+ assert_eq!(held, 2_500_000);115
+ let hold = Budget::FLOOR_NS / REFRESH;116
+ for _ in 1..hold {117
+ b.landed();118
+ }119
+ assert_eq!(b.slack_ns, held);120
+ for _ in 0..100 {121
+ b.landed();122
+ }123
+ assert!(b.slack_ns < held);124
+ for _ in 0..1_000_000 {125
+ b.landed();126
+ }127
+ assert_eq!(b.slack_ns, Budget::MIN_SLACK_NS);128
+ }129
+130
+ #[test]131
+ fn misses_never_push_slack_past_half_a_refresh() {132
+ let mut b = Budget::new();133
+ for _ in 0..100 {134
+ b.missed(REFRESH);135
+ }136
+ assert_eq!(b.slack_ns, REFRESH / 2);137
+ }138
+139
+ #[test]140
+ fn deadline_picks_the_first_vblank_still_reachable() {141
+ let last = 1_000_000_000;142
+ let (vblank, start) = deadline(last, REFRESH, 2_000_000, last + 1).unwrap();143
+ assert_eq!(144
+ (vblank, start),145
+ (last + REFRESH, last + REFRESH - 2_000_000)146
+ );147
+ let late = last + REFRESH - 1_000_000;148
+ assert_eq!(149
+ deadline(last, REFRESH, 2_000_000, late).unwrap().0,150
+ last + 2 * REFRESH151
+ );152
+ let stale = last + 10 * REFRESH + 1;153
+ assert_eq!(154
+ deadline(last, REFRESH, 0, stale).unwrap().0,155
+ last + 11 * REFRESH156
+ );157
+ let (vblank, start) = deadline(last, REFRESH, 3 * REFRESH, last).unwrap();158
+ assert_eq!(vblank - start, REFRESH);159
+ assert_eq!(deadline(last, 0, 0, last), None);160
+ }161
+}