Generated by PerfBench.ControlModel.exe --demo. 39 PNGs (13 benches × 3
variants) under
LAPTOP-4MEP83VI/2026-05-25-arm64/screenshots/.
Captured via win32 PrintWindow(PW_RENDERFULLCONTENT). Each screenshot
shows the bench window after DemoMount finishes laying out, before the
next (bench, variant) takes the parent panel.
This file is the contract for what each screenshot is expected to
contain — a quick visual sanity check that the bench actually exercises
the WinUI rendering path. If a screenshot doesn't match, the bench is
broken; if it matches, the perf numbers in summary.md are measuring
the right thing.
| Bench | Expected visual |
|---|---|
| M1 Direct | Label "M1 Direct: 'hi'" + plain TextBlock reading "hi" |
| M1 Today / V2 | Label "M1 {variant}: 'hi'" + Reactor-mounted TextBlock "hi" |
| M2 Direct | "M2 Direct: ToggleSwitch + OnIsOnChanged" + a plain WinUI ToggleSwitch (off) |
| M2 Today / V2 | Same shape, Reactor-mounted ToggleSwitch |
| M3 Direct | "M3 Direct: Button + 3 callbacks" + a Button "Click" |
| M3 Today / V2 | Same shape, Reactor-mounted Button "Click" |
| M4 Direct / Today / V2 | "M4 {variant}: one of each element type (cold)" + a column of: TextBlock, Button, ToggleSwitch, CheckBox, Slider, (3 invisible containers: HStack/VStack/Grid). The three containers are empty so they appear as a slim gap below the Slider — that's expected: they're real WinUI controls with no content. |
| M5 Direct / Today / V2 | Same as M4 visually but labeled "M5 {variant}: one of each element type (warm — PGO hot)". M5 reuses M4's bench but the runner warms PGO first. |
| M6 Direct | "M6 Direct: RegisterType external" + "(no registry under Direct)" — Direct has no registry path, this is by design. |
| M6 Today / V2 | Label + a TextBlock reading "registered ExtElement" — exercises the _typeRegistry lookup. |
| M7 Direct | One small "x" in the top-left. This looks empty but is correct. The fixture mounts a 1000-element TextBlock("x") tree into a Grid with no row/col definitions; all 1000 stack at (0,0). The perf measurement is the no-change update cost, not layout — see summary §M7. |
| M7 Today / V2 | Same — 1000 elements stacked at (0,0). |
| M8 Direct / Today / V2 | Same all-on-top stack as M7, with one leaf alternating "a"/"b". |
| M9 Direct / Today / V2 | Same all-on-top stack as M7, but mid-mutation. |
| M10 Direct | "M10 Direct: ToggleSwitch + alloc-counted wiring" + a ToggleSwitch (off). |
| M10 Today / V2 | Same with Reactor-mounted ToggleSwitch. |
| M11 Direct | Header bar empty — Direct doesn't run M11 (no ModifierEventHandlerState concept). Screenshot will show just the demo title. |
| M11 Today / V2 | A 1000-element mixed tree (TextBlock + Button + ToggleSwitch + Slider + Border, with OnPointerPressed on every 10th element) stacked at (0,0). You'll see overlapping outlines of a Slider, a ToggleSwitch, and a "z" character — that's the top of the pile. |
| M12 Direct | "M12 Direct: poolable TextBlock cycle" + "(no pool under Direct)". |
| M12 Today / V2 | "M12 {variant}: poolable TextBlock cycle" + a TextBlock "rented/returned x". |
| M13 Direct | Nothing rendered — M13 is correctness-only and only runs on Reactor variants. |
| M13 Today / V2 | A ToggleSwitch in the ON position (blue). This is the §8.2 bug rendered visually: the bench wires OnIsOnChanged and .Set(ts => ts.IsOn = true). The setter writes IsOn=true, the engine doesn't suppress the echo, the callback fires (counter = 1), and the toggle ends up On. Phase 1's §8.2 fix should still leave the toggle On (Set is meant to write) but should set OnIsOnChangedFireCount = 0 (no spurious callback). |
The benches at M7/M8/M9/M11 mount large trees into a Grid without
row/column definitions. WinUI places every child at (0,0) in this case,
so all 1000 (or 5000) elements stack on top of each other and only the
last-painted one is visible. This is intentional — the perf
measurement is the per-element mount/diff cost, not layout cost; adding
row/col defs would change what we're measuring. The screenshots prove
the elements exist in the visual tree; the perf numbers are valid.
If you need a visually clear layout for one of these (for debugging),
add a WrapPanel / StackPanel wrapper in the bench's RunOne —
acknowledge that this changes the measured cost.
- M5 label says "M5 …" after the Phase-0 fix (the original capture
shown in the live screenshots said "M4 ReactorToday: one of each
element type (cold)" because M5 delegated
DemoMountto M4's inner without patching the header). Re-capture after the cosmetic fix lands if you regenerate the screenshots. - M13 Direct is intentionally blank (no fixture for Direct).
- Container elements (HStack / VStack / Grid in M4 / M5) render as 0-height rows because they have no content — that's correct WinUI behavior, not a bench bug.