Files
LlamaCasty/HANDOFF.md
T
gramps a3a4681aac Per-element composite timing + scene dump (measurement only)
The cadence work ended with a question the log could not answer: the compositor
manages 6.8 composites/s at ~141ms while the 10:03 take did 29-34ms on the "same
scene shape" (full-render split=0 elements=6 dynamic=5). Nothing in the stats line
said WHICH of the six elements cost what, and nothing recorded the scene itself, so
the two takes could only be compared by eye. This closes that gap and nothing else:
no fix is attempted until a real take names the culprit.

- Services/Compositor/CompositeTimings.cs (new): per-window collector.
  Add(stage, ticks) accumulates; Describe(renders, minMs = 0.1) prints the averaged
  breakdown slowest-first, dropping sub-0.1ms noise.
- SceneCompositor.Render / CompositeLayers / BakeStaticBase / BlitBakedElement /
  BlitCachedLayer + SceneGraph.GetBakedBase: trailing optional CompositeTimings?
  Every stage is timed (backdrop, base, flash, social, ticker, zoom, scale, overlay,
  bake backdrop, bake overlays) and EVERY element gets its own entry keyed by
  z-index + name ("#2 Webcam"), with the nested "raster" sub-stage recording the
  paste-cache rasterize miss - the split between "re-samples every tick" and "slow
  paste" without a second session. Bake-pass elements are prefixed "bake #..." so a
  one-off rebake cannot masquerade as a per-composite cost. Callers that pass
  nothing (thumbnails, existing tests) are unaffected and pay nothing.
- FramePump: owns the collector, threads it through RenderScene/RenderFull/
  GetBakedBase/CompositeLayers, and logs "FramePump parts (N renders/5s): ..." once
  per 5s window beside the stats line (averaged per render, so it compares directly
  with "avg render"), then resets it. Also dumps the scene - "FramePump scene dump:"
  header plus one line per element (z-index, name, kind, source type, visibility,
  rect, opacity, clip) - at pump start and on every scene change.
- One Good Dog integration test (ytLive.Tests/CompositeTimingTests.cs): a real
  composite of a full-canvas element plus a 64x64 one through the real collector
  must rank the full-canvas element first, carry the raster sub-stage and the fixed
  stages, and the dump must name both elements with z-index/type/rect and echo the
  split point.

Derivative work (AGENTS.md): OBS's answer to "which source is slow" is the Source
Profiler - average execution time of each source's tick and render functions
(https://docs.obsproject.com/reference-libobs-util-source-profiler, util/profiler.h).
Same shape here: one timer per element per composite, reported as an average, plus
the stage split this case needs.

Docs in the same commit: ai.md (new subsection "Per-element composite timing + scene
dump", the closed gap corrected in "Frame cadence"), Services/index.md (new file row
+ FramePump/SceneCompositor rows), TASKS.md (unit marked shipped, next = creator
take), HANDOFF.md (rewritten: unpushed commit, next step, verify.sh whitelist hole).

Also recorded this session (from the creator): the launch command is
`dotnet run -c Release` - Release is the DEFAULT, Debug only when explicitly named,
and perf takes must read Release. ai.md -> Run updated.

Full suite 428 tests, 0 warnings; the only failures are the known audio env flakes
(both pass in isolation). Scope check passed.
2026-10-16 18:23:20 -07:00

71 lines
5.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# HANDOFF — 2026-10-16 (work committed locally; NOT pushed — push at the next milestone)
## At a glance
- **Branch** main, tracking `origin/main`. **origin/main = `931ab46`; HEAD = the tip commit "Per-element
composite timing + scene dump (measurement only)"** — **2 ahead, 0 behind** (nothing pushed this
session; per the commit/push policy, push only at sub-milestones/milestones, when the creator says
so). This file cannot record its own commit's hash — amending a commit changes that hash — so the tip
is named by subject.
- The two local-only commits are `3cb29ea` (**the previous session's HANDOFF refresh — the old
handoff claimed it was pushed; it never was**) and the tip. So "0 ahead" in the 2026-10-14 handoff
was wrong — check `git log origin/main..HEAD`, never the handoff's own claim.
- Working tree **clean** after the commit.
- No app run, recording, or test session happened 2026-10-11 → 10-16 (verified against
`%APPDATA%\ytLlive\startup.log`: last activity 2026-10-10 13:26). The creator was away for a family
emergency and has only just returned — **there is still no take of the instrumented build.**
## This session's unit (committed, unpushed — the tip commit)
- **Per-element composite timing + scene dump — MEASUREMENT ONLY (2026-10-16).** Closes the gap the
cadence work left: the 141ms take and the 30ms take could not be compared because the log named no
element and recorded no scene.
- `Services/Compositor/CompositeTimings.cs` (new): collector; `Describe(renders, minMs = 0.1)`
prints the averaged breakdown slowest-first.
- `SceneCompositor.Render` / `CompositeLayers` / `BakeStaticBase` / `BlitBakedElement` /
`BlitCachedLayer` + `SceneGraph.GetBakedBase`: trailing optional `CompositeTimings?` — every stage
and every element timed (`#<i> <name>`, nested `raster` = paste-cache miss). Existing callers
unaffected.
- `FramePump`: `FramePump parts (N renders/5s): …` per stats window; `FramePump scene dump:` block
(header + one line per element) at pump start and on scene change.
- Gate test: `ytLive.Tests/CompositeTimingTests.cs` (one `[Fact]`, real composite through the real
collector + dump formatter). Full suite 428 tests; 0 warnings; scope check passed.
- Derivative citation: OBS Source Profiler (per-source tick/render average) — see `ai.md`
"Per-element composite timing + scene dump".
## Next step
- **Creator take on the instrumented build, Release** (`"/mnt/c/Program Files/dotnet/dotnet.exe" run
-c Release`). Read the two new lines in `%APPDATA%\ytLlive\startup.log`:
`FramePump parts (N renders/5s): …` (which element / which stage eats the budget) and the
`FramePump scene dump:` block (the shape the take was made from). **No fix is to be attempted until
the parts line names the element** — the 10:03 → 12:01 regression (29–34ms → 143–155ms) is still
unexplained, and the competing explanations in the map (21:9 source rect vs. same-shape regression)
are unresolved on purpose until a reading decides it.
## Also still open (operational)
- **verify.sh's known-failure whitelist is too loose (found 2026-10-16):** it counts matching names and
passes if `KNOWN > 0`, so a NEW third failure rides along unnoticed. This session's full run showed
`AudioPipelineTests.MasterLimiter_CapsTheLiveMix_OnThePipe` failing beside the two known ones — it
passes in isolation (29/29), so it is an audio-device env flake like
`Mix_HonorsProviderGains…` (system audio playing). **Follow-up: tighten the script** (require EVERY
failure line to be in the whitelist) and add `MasterLimiter_CapsTheLiveMix_OnThePipe` to the list.
Not fixed in this unit — out of scope (`scripts/verify.sh` was not in the declared file list).
- **Vertical-format regression (STALE, not fixed):** 1080p60-vertical selection no longer shrinks the
capture border in the preview. Mechanism mapped in `Controls/PreviewPane.xaml:319-322` (crop Rectangle
bound to `OutputRectX/Y/W/H` + `IsOutputCropped`, driven by `MainViewModel.Streaming.cs`
`ApplyStreamQuality`; `DimRects` in `MainViewModel.cs:91-94`). Root cause unknown — paused.
- ⛔ Sudo password rotation pending (user; then update both password lines in `CREDENTIALS.md`).
- TASK 56 secret scan before `gramps/LlamaCasty` goes public.
- TASK 55 disk hygiene queued (`startup.log` uncapped — now 22MB and growing with the new lines).
## Tests
- Full suite **426 passed / 2 failed / 0 skipped / 0 warnings** (2026-10-16, 428 total incl. the new
test). Both failures are the audio env flake (see above) and pass in isolation.
- Pre-commit gate: `./scripts/verify.sh "<file1>" "<file2>" ...` (clean build + full suite + scope check).
**Read its output — it can pass with an unlisted failure present (see the landmine above).**
## Secrets / paths (do not re-hunt)
- Layout DB: `%APPDATA%\ytLlive\ytLlive.db` (SQLite, full-rewrite per save). Auth: `%APPDATA%\ytLlive\ytLlive.auth`
(DPAPI). Startup log: `%APPDATA%\ytLlive\startup.log`.
- LAN credentials: `CREDENTIALS.md` (gitignored). Google Cloud OAuth project number `198374416003`,
owned by `llamachile.shop@gmail.com` — verify at
`https://console.cloud.google.com/apis/credentials?project=198374416003`.