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