Answer "have I asked this child?" in one read
A container's draw asked it once per child by searching the list of children it had added so far, and four other per-child steps searched a list too, so one draw cost the square of its children: 70% of a 1,600-child redraw was those searches. A draw takes a DrawId and leaves it on every widget it asks about; one note per widget is enough because the handle a container holds a child by cannot be cloned. tests/children_cost.rs is the rig that shows it, and it is the only one here that varies width: 3.680 ms to 0.811 ms at 1,600 children, and flat per child. Beside it, the rest of the fourteenth sweep of #19: a mask's rectangle resolved once per fragment instead of once per instance, which takes the storage buffers out of the fragment stage and is 8.8x on a screenful of deeply nested clips; TextBuffer::shape copying its attrs before the check that would not need them, which allocated once per named-family text per frame; a should_panic test on a debug assertion that made cargo test --release fail; Fixed::div, reached only by its own test; Moves::remove re-uploading an array it cannot have changed; and two comments the branch itself falsified. docs/LAYOUT_LOG.md has all eight with their measurements, the five things looked at and left, and what was verified.
This commit is contained in:
1 parent
cbccfb600a
commit
97fca76108
17 files changed
+588
-149
No files matched your search
@@ -1563,3 +1563,30 @@ fn a_contract_this_window_is_outside_is_not_kept() {
|
||||
"the leaf settled once and its parent kept what it settled"
|
||||
);
|
||||
}
|
||||
|
||||
/// A container that measures a child by drawing it, takes that drawing back,
|
||||
/// and then places the child, which `place_at` answers by asking again: taking
|
||||
/// a child back takes it out of the child list, and the note on the child
|
||||
/// saying it is in there has to go with it, or the placement re-expresses a
|
||||
/// drawing that no longer exists.
|
||||
#[test]
|
||||
fn a_child_taken_back_and_placed_again_is_asked_again() {
|
||||
struct Retake(StrongWidget);
|
||||
|
||||
impl Widget for Retake {
|
||||
fn draw(&mut self, painter: &mut Painter) -> Size {
|
||||
painter.widget(&self.0);
|
||||
painter.undraw(&self.0);
|
||||
painter.place_at(&self.0, PlaceDesc::WHOLE).size()
|
||||
}
|
||||
}
|
||||
|
||||
let mut h = Harness::new((600, 200));
|
||||
let child = rect(Color::RED).add_strong(&mut h.rsc);
|
||||
let id = child.id();
|
||||
let root = Retake(child).add(&mut h.rsc);
|
||||
h.set_root(root);
|
||||
h.frame();
|
||||
|
||||
assert_corners!(h, id, (0, 0), (600, 200));
|
||||
}
|
||||
@@ -127,6 +127,11 @@ fn wrapping_content_beside_a_fixed_length_is_stable_warm_and_cold() {
|
||||
/// parent would place the part it cut off, and the framework would put a
|
||||
/// drawing longer than its box somewhere. `Masked` is the second of these
|
||||
/// after `Scroll`, and the assertion in `draw_at` is what says so.
|
||||
// What it checks is a debug assertion, which a release build does not compile
|
||||
// -- and a `should_panic` test of one fails there rather than passing
|
||||
// vacuously, so it is not built either. Every measurement rig here is run in
|
||||
// release, so `cargo test --release` has to pass.
|
||||
#[cfg(debug_assertions)]
|
||||
#[test]
|
||||
#[should_panic = "clips to"]
|
||||
fn a_clipping_widget_reporting_more_than_its_box_is_caught() {
|
||||
|
||||
Reference in new issue
Block a user