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:
iris-ai committed 2026-09-20 23:56:12 -04:00
1 parent cbccfb600a
commit 97fca76108
17 files changed
+588 -149

No files matched your search

+28 -2
View File
@@ -1,5 +1,6 @@
//! The adapter and the surface configuration the GPU measurement rigs share,
//! so the two cannot probe for a device in two different ways.
//! The adapter, the surface configuration and the target the GPU rigs share,
//! so no two of them can probe for a device or make a target in different
//! ways.
use wgpu::*;
@@ -38,3 +39,28 @@ pub fn config(format: TextureFormat, size: u32) -> SurfaceConfiguration {
view_formats: vec![],
}
}
/// A square colour target to draw a pass into. `copy` adds the usage a rig
/// that reads the pixels back needs; one that only times the pass does not.
// This module is compiled into each rig target separately, so a helper the
// ones that make no target of their own do not call is dead code there.
#[allow(dead_code)]
pub fn target(device: &Device, format: TextureFormat, size: u32, copy: bool) -> Texture {
device.create_texture(&TextureDescriptor {
label: Some("gpu rig target"),
size: Extent3d {
width: size,
height: size,
depth_or_array_layers: 1,
},
mip_level_count: 1,
sample_count: 1,
dimension: TextureDimension::D2,
format,
usage: match copy {
true => TextureUsages::RENDER_ATTACHMENT | TextureUsages::COPY_SRC,
false => TextureUsages::RENDER_ATTACHMENT,
},
view_formats: &[],
})
}