Say why a reuse was refused, on every path that refuses one

Three of the eight rejections in `try_reuse` were invisible or half-visible
to the diagnostics: a changed inherited mask counted nothing and traced
nothing, an undrawn record traced without counting, and a changed
region-node choice counted without tracing. The mask one is the rejection
this branch's repair was about, so "why did that redraw?" was exactly the
question the rig could not answer.

Adding a counter meant editing a variant list and a name list at the same
index, which renames every total after a slip and says nothing. The two
lists are one declaration now.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
iris-aiandClaude Opus 5 committed 2026-09-20 00:20:23 -04:00
1 parent 713e3e747b
commit 8088a1fa59
2 files changed
+78 -92

No files matched your search

+62 -90
View File
@@ -23,100 +23,70 @@ use std::{
time::Instant, time::Instant,
}; };
#[derive(Clone, Copy)] /// Declares a counter or timer kind beside the name its report prints. Two
pub(crate) enum Counter { /// lists in the same order was one list too many: a variant inserted without
Updates, /// its label moving with it renames every total after it, and nothing says
DrawRequests, /// so.
WidgetDraws, macro_rules! labelled {
RegionNodeDraws, ($(#[$meta:meta])* $vis:vis enum $Name:ident { $($variant:ident = $label:literal,)* }) => {
SizeReads, $(#[$meta])*
HintHits, #[derive(Clone, Copy)]
HintMisses, $vis enum $Name { $($variant,)* }
ReuseAttempts,
ReuseExact, impl $Name {
ReuseMoved, const COUNT: usize = [$($label,)*].len();
ReuseDirty, const NAMES: [&'static str; Self::COUNT] = [$($label,)*];
ReuseWrongParent, }
ReuseRemapped, };
ReuseOutside,
ReuseWrongLayer,
ReuseWrongNode,
QueuePops,
DepthReads,
LocalRedraws,
SizeChanges,
ReaderEdges,
PrimitiveWrites,
TextRenders,
TextShapeHits,
TextShapes,
TextBreaks,
GlyphPlacements,
OutsidePinnedLen,
OutsideRelBase,
OutsideRegion,
} }
impl Counter { labelled! {
const COUNT: usize = Self::OutsideRegion as usize + 1; pub(crate) enum Counter {
Updates = "updates",
const NAMES: [&'static str; Self::COUNT] = [ DrawRequests = "draw requests",
"updates", WidgetDraws = "widget draws",
"draw requests", RegionNodeDraws = "region-node draws",
"widget draws", SizeReads = "draw-result size reads",
"region-node draws", HintHits = "hint hits",
"draw-result size reads", HintMisses = "hint misses",
"hint hits", ReuseAttempts = "reuse attempts",
"hint misses", ReuseExact = "reuse exact",
"reuse attempts", ReuseMoved = "reuse moved",
"reuse exact", ReuseDirty = "reuse: dirty",
"reuse moved", ReuseUndrawn = "reuse: nothing drawn to keep",
"reuse: dirty", ReuseWrongParent = "reuse: wrong parent",
"reuse: wrong parent", ReuseRemapped = "reuse remapped",
"reuse remapped", ReuseOutside = "reuse: outside what it holds for",
"reuse: outside what it holds for", ReuseWrongLayer = "reuse: another layer",
"reuse: another layer", ReuseWrongNode = "reuse: region-node choice changed",
"reuse: region-node choice changed", ReuseWrongMask = "reuse: a different inherited mask",
"redraw queue pops", QueuePops = "redraw queue pops",
"depth reads", DepthReads = "depth reads",
"local redraws", LocalRedraws = "local redraws",
"size changes", SizeChanges = "size changes",
"reader edges", ReaderEdges = "reader edges",
"primitive writes", PrimitiveWrites = "primitive writes",
"text renders", TextRenders = "text renders",
"text shape hits", TextShapeHits = "text shape hits",
"text shapes", TextShapes = "text shapes",
"text line breaks", TextBreaks = "text line breaks",
"glyph placements", GlyphPlacements = "glyph placements",
"reuse outside: the length it was pinned to", OutsidePinnedLen = "reuse outside: the length it was pinned to",
"reuse outside: a rel base", OutsideRelBase = "reuse outside: a rel base",
"reuse outside: a region length", OutsideRegion = "reuse outside: a region length",
]; }
} }
#[derive(Clone, Copy)] labelled! {
pub(crate) enum TimerKind { pub(crate) enum TimerKind {
Update, Update = "update total",
FullLayout, FullLayout = "full layout",
IncrementalLayout, IncrementalLayout = "incremental layout",
TextRender, TextRender = "text render",
TextShape, TextShape = "text shape",
TextBreak, TextBreak = "text line break",
GlyphPlacement, GlyphPlacement = "glyph placement",
} }
impl TimerKind {
const COUNT: usize = Self::GlyphPlacement as usize + 1;
const NAMES: [&'static str; Self::COUNT] = [
"update total",
"full layout",
"incremental layout",
"text render",
"text shape",
"text line break",
"glyph placement",
];
} }
#[derive(Clone)] #[derive(Clone)]
@@ -251,6 +221,8 @@ pub enum ReuseOutcome {
Dirty, Dirty,
WrongParent, WrongParent,
WrongLayer, WrongLayer,
WrongMask,
WrongNode,
Remapped, Remapped,
Outside, Outside,
Undrawn, Undrawn,
+16 -2
View File
@@ -569,12 +569,18 @@ impl UiRenderState {
}; };
if !active.drawn { if !active.drawn {
#[cfg(feature = "layout-diagnostics")] #[cfg(feature = "layout-diagnostics")]
diag::reuse(id, ReuseOutcome::Undrawn); {
diag::bump(Counter::ReuseUndrawn);
diag::reuse(id, ReuseOutcome::Undrawn);
}
return false; return false;
} }
if active.is_region_node() != info.region_node { if active.is_region_node() != info.region_node {
#[cfg(feature = "layout-diagnostics")] #[cfg(feature = "layout-diagnostics")]
diag::bump(Counter::ReuseWrongNode); {
diag::bump(Counter::ReuseWrongNode);
diag::reuse(id, ReuseOutcome::WrongNode);
}
return false; return false;
} }
// Drawn on another layer: the drawing sits in that layer's list and // Drawn on another layer: the drawing sits in that layer's list and
@@ -590,7 +596,15 @@ impl UiRenderState {
} }
return false; return false;
} }
// Its primitives name the mask it inherited, and a masking parent
// that redrew pushed another: keeping them would clip them by one
// nothing updates again.
if active.parent_mask != info.mask { if active.parent_mask != info.mask {
#[cfg(feature = "layout-diagnostics")]
{
diag::bump(Counter::ReuseWrongMask);
diag::reuse(id, ReuseOutcome::WrongMask);
}
return false; return false;
} }
// Drawn somewhere else in the tree: its box is in coordinates it no // Drawn somewhere else in the tree: its box is in coordinates it no