Creating or freeing a frame or region re-derives only what it touches (#915)
Any write that changed the layout graph's roster (a frame or region created, freed, re-owned or re-pointed) made the next resolve derive the whole graph: about 1.35 ms for one `CreateTexture` or `CreateFrame` on the stock UI, against 0.05 ms for a no-op. A write now names the nodes it touched, and the resolve re-derives just those in the cached graph: a joining node is added with its edges, a leaving one is removed and its dependents seeded, a staying one has its edges and inputs re-synced. The full derivation stays the fallback. A region's owner and an art change are now layout inputs that name their region. Verify now also compares the graph itself. A randomized test checks rects and graph against a scratch solve after every batch of creates, frees, re-owns and re-anchors. `CreateTexture` now costs 0.14 ms, `CreateFrame` 0.15 ms, a backdrop rebuild 0.22 ms. Fixes #903 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
55729baff9
commit
fa5568dcdc
@@ -331,16 +331,13 @@ impl Installed {
|
||||
/// the next resolve runs them. Each piece is a fresh Texture linked at the tail of the region
|
||||
/// list, so a second backdrop's pieces come after any region made in between.
|
||||
pub(crate) fn install(model: &mut Model, fh: FrameHandle, spec: Option<Backdrop>) {
|
||||
// One layout touch for the whole swap, the pieces it frees and the ones it builds: the next
|
||||
// resolve re-derives the graph once either way.
|
||||
// Each freed piece names its node, and each built one below, so the next resolve takes the
|
||||
// swap through the cached graph.
|
||||
let old = model.backdrops.remove(&fh);
|
||||
for rh in old.iter().flat_map(|o| o.pieces).flatten() {
|
||||
super::region::release_region(model, rh);
|
||||
super::region::free_region(model, rh);
|
||||
}
|
||||
let Some(spec) = spec.filter(|_| model.arena.frame(fh).is_some()) else {
|
||||
if old.is_some() {
|
||||
model.touch_layout();
|
||||
}
|
||||
return;
|
||||
};
|
||||
let owner = model.frame_id(fh);
|
||||
@@ -399,6 +396,9 @@ pub(crate) fn install(model: &mut Model, fh: FrameHandle, spec: Option<Backdrop>
|
||||
);
|
||||
}
|
||||
}
|
||||
for rh in pieces.iter().flatten() {
|
||||
model.touch_layout_region(*rh);
|
||||
}
|
||||
model.backdrops.insert(
|
||||
fh,
|
||||
Installed {
|
||||
@@ -407,7 +407,6 @@ pub(crate) fn install(model: &mut Model, fh: FrameHandle, spec: Option<Backdrop>
|
||||
ran_for: None,
|
||||
},
|
||||
);
|
||||
model.touch_layout();
|
||||
if let Some(rect) = model.resolved.get(&fh).copied() {
|
||||
run_texcoords(model, fh, rect);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user