Resolve deferred size comparisons before allocating span slots
This commit is contained in:
1 parent
de1eb7e406
commit
8780b40bb7
23 files changed
+1471
-130
No files matched your search
@@ -0,0 +1,80 @@
|
||||
use iris::{harness::Harness, prelude::*};
|
||||
use std::{
|
||||
alloc::{GlobalAlloc, Layout, System},
|
||||
cell::Cell,
|
||||
};
|
||||
|
||||
struct Counting;
|
||||
thread_local! {
|
||||
static COUNT: Cell<Option<usize>> = const { Cell::new(None) };
|
||||
}
|
||||
fn count() {
|
||||
COUNT.with(|count| {
|
||||
if let Some(n) = count.get() {
|
||||
count.set(Some(n + 1));
|
||||
}
|
||||
});
|
||||
}
|
||||
// The wrapper preserves System's allocation and deallocation contracts;
|
||||
// observing calls here also counts allocations hidden inside layout helpers.
|
||||
unsafe impl GlobalAlloc for Counting {
|
||||
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
|
||||
count();
|
||||
unsafe { System.alloc(layout) }
|
||||
}
|
||||
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
|
||||
unsafe { System.dealloc(ptr, layout) }
|
||||
}
|
||||
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, size: usize) -> *mut u8 {
|
||||
count();
|
||||
unsafe { System.realloc(ptr, layout, size) }
|
||||
}
|
||||
}
|
||||
#[global_allocator]
|
||||
static ALLOCATOR: Counting = Counting;
|
||||
|
||||
#[test]
|
||||
fn unchanged_tree_reuses_layout_storage() {
|
||||
for deferred in [false, true] {
|
||||
let mut h = Harness::new((600, 200));
|
||||
let mut children: Vec<StrongWidget> = Vec::new();
|
||||
for _ in 0..8 {
|
||||
let a = rect(Color::RED).add(&mut h.rsc);
|
||||
if deferred {
|
||||
h.rsc
|
||||
.widgets_mut()
|
||||
.set_size_rule(a, Axis::X, leftover(1).clamp(20, 80).into());
|
||||
}
|
||||
let row = (a, rect(Color::BLUE))
|
||||
.span(Dir::RIGHT)
|
||||
.add_strong(&mut h.rsc);
|
||||
children.push(row);
|
||||
}
|
||||
let root = h.rsc.widgets_mut().add_strong(Span {
|
||||
children,
|
||||
dir: Dir::DOWN,
|
||||
gap: Px::ZERO,
|
||||
});
|
||||
h.state.root = Some(root);
|
||||
h.frame();
|
||||
let ids: Vec<_> = h.render.active.keys().copied().collect();
|
||||
for frame in 0..8 {
|
||||
for &id in &ids {
|
||||
h.rsc.widgets_mut().mark_for_redraw(id);
|
||||
}
|
||||
h.resize((600 + frame % 2, 200));
|
||||
h.frame();
|
||||
}
|
||||
COUNT.set(Some(0));
|
||||
for frame in 0..100 {
|
||||
for &id in &ids {
|
||||
h.rsc.widgets_mut().mark_for_redraw(id);
|
||||
}
|
||||
h.resize((600 + frame % 2, 200));
|
||||
h.frame();
|
||||
}
|
||||
let allocations = COUNT.replace(None).unwrap();
|
||||
println!("deferred={deferred}: {allocations} allocations over 100 resize frames");
|
||||
assert_eq!(allocations, 0);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user