Measure a child on the layer it draws on, not twice on two
Fixed point cost 3x in layout: `many` went from 0.179 ms a frame to 0.544, and `scroll` from 0.011 to 0.030. The counters said why -- eight more "placed by redrawing" a frame -- and the reason was mine rather than the grid's. A retained drawing belongs to the layer it was made on, which `4e28f10` started enforcing, and `Stack` measures the child that sizes it by drawing it on its own layer and then draws it again on the child layer. So every stacked child redrew twice a frame, forever. `Painter::child_layer_at` addresses a child's layer rather than walking to it, and `Stack` measures on the layer that child ends up on. The second ask is then a reuse. Its glyphs are written once rather than once under the background and once over it. Measured on the same fixture: `scroll` 0.031 ms to 0.020, `many` 0.570 to 0.283, and the scroll phase's counters are back to what they were before fixed point -- 4 widget draws and 12 draw requests a frame, exactly. What is left above that baseline is not this. `ReuseOutcome` could not say "another layer" or "the region-node choice changed"; both returned without a counter, which is why the first look at this said nothing. They have counters now. Checked: fmt, clippy, 105 tests, five shrinker cases at 300 seeds, 100 generated seeds, and the examples byte-identical but for 36 pixels of `random` at one level -- edges that were being drawn twice. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
95fb4f962c
commit
97cc8b32ed
5 files changed
+73
-20
No files matched your search
@@ -307,6 +307,7 @@ impl UiRenderState {
|
||||
region: local,
|
||||
mask: info.mask,
|
||||
layer: info.layer,
|
||||
own_layer: info.layer,
|
||||
id,
|
||||
textures: Vec::new(),
|
||||
primitives: Vec::new(),
|
||||
@@ -349,6 +350,7 @@ impl UiRenderState {
|
||||
under,
|
||||
move_idx,
|
||||
layer,
|
||||
own_layer: _,
|
||||
depth: _,
|
||||
id,
|
||||
} = painter;
|
||||
@@ -586,6 +588,8 @@ impl UiRenderState {
|
||||
}
|
||||
let has_region_node = active.move_idx != active.parent_move;
|
||||
if has_region_node != info.region_node {
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::bump(Counter::ReuseWrongNode);
|
||||
return None;
|
||||
}
|
||||
// Drawn on another layer: the drawing sits in that layer's list and
|
||||
@@ -595,7 +599,10 @@ impl UiRenderState {
|
||||
// on a layer the first answer is not good for.
|
||||
if active.layer != info.layer {
|
||||
#[cfg(feature = "layout-diagnostics")]
|
||||
diag::reuse(id, ReuseOutcome::WrongLayer);
|
||||
{
|
||||
diag::bump(Counter::ReuseWrongLayer);
|
||||
diag::reuse(id, ReuseOutcome::WrongLayer);
|
||||
}
|
||||
return None;
|
||||
}
|
||||
// Drawn somewhere else in the tree: its box is in coordinates it no
|
||||
|
||||
Reference in new issue
Block a user