# ✅ What Canary does between the guest's draw and a captured pixel — and which of our measurements it touches **Status: ✅ decoded from Canary's own source.** Instrument: ⟨canary-source⟩, with ⟨capture⟩ for the dumped guest shader. 2026-09-02. Answers question 3 of [`../agents/PLAYTEST-2026-09-02.md`](../agents/PLAYTEST-2026-09-02.md) — *"present cadence, and any resolve, scale or gamma between the guest's draw and a capture's pixels."* --- ## 1 — gamma: **Canary applies none** `VdGetCurrentDisplayGamma` is the export the play-test warns about. Reading it: ```cpp void VdGetCurrentDisplayGamma_entry(lpdword_t type_ptr, lpfloat_t power_ptr) { *type_ptr = cvars::kernel_display_gamma_type; // default 2 = TV (BT.709) *power_ptr = float(cvars::kernel_display_gamma_power); } DECLARE_XBOXKRNL_EXPORT1(VdGetCurrentDisplayGamma, kVideo, kStub); ``` **It is declared `kStub` and it transforms nothing.** It *reports* a gamma type to the guest, which D3D would use to build a ramp. So the question becomes whether the **guest** applies one — and for the splash it demonstrably does not. The splash pixel shader, dumped from the running game, is four ALU ops: ``` tfetch2D r2, r1.xy, tf0 mul r1.___w, r2.wwww, r0.wwww mul r0.xyz_, r2.xyzz, r0.xyzz mul r1.xyz_, r0.xyzz, r1.wwww max oC0, r1, r1 ``` **No `pow`, no ramp, no lookup.** Nothing in the splash path applies gamma — neither side of the emulation boundary. ## 2 — geometry: **yes, the presenter resamples** `presenter.cc` defaults: | cvar | default | effect | |---|---|---| | `present_letterbox` | **true** | aspect preserved, bars added rather than stretching | | `present_safe_area_x` / `_y` | **100** | nothing cropped | So the guest's 1280×720 is **scaled to fit the host window and letterboxed**. That is a resample, and it explains a number the corpus has carried without accounting for it: captures measure the game surface at **1279×675**, not 1280×720. A single-pixel oracle placed at 1280×720 coordinates read the copyright line instead — which is exactly the failure `wait_title.sh` was found to have. ## 3 — 🔴 So there are TWO measurement paths, and only one has Canary in it | path | route | Canary processing | |---|---|---| | **pixels** | guest draw → EDRAM → resolve → front buffer → **presenter (scale + letterbox)** → X11 → `screenshot` → PNG | **a resample**, plus whatever the window system does | | **vertex stream** | guest CPU writes a vertex buffer → **the draw logger reads guest memory directly** | **none** | 📌 **The per-frame alpha series is the second path.** The `k_8_8_8_8` colour is read out of the guest's own vertex buffer *before* it reaches a shader, a render target, a resolve or the presenter. **There is no Canary processing between the guest's intent and that number** — which is why [`splash-interpolates-every-frame.md`](splash-interpolates-every-frame.md) can state per-frame alphas as the game's values rather than as pixels we measured. ⚠️ **Everything in this corpus measured off a PNG carries the resample.** That includes every RMSE against a capture, every glyph count, every surface mean, and the `motion-census` numbers the play-test quotes for the port. It does not make them wrong — a resample preserves *change*, which is what a motion census measures — but it does mean a pixel-exact comparison is comparing through a filter nobody has characterised. ## Refutation attempt, recorded per the adversarial duty **Target:** this corpus's own founding principle, stated at the top of three documents — *"the oracle is the real game running in Xenia Canary, captured."* **Result: it SURVIVES, but it needs a qualifier it has never carried.** A capture is the oracle **plus a resample** whenever it is a PNG. For ordering, counts, durations and change — the quantities `TEMPORAL-VERIFICATION.md` already tells us to prefer — the resample is harmless. For anything pixel-exact it is a filter in the path, and the corpus has been treating PNG captures and vertex-stream captures as the same kind of evidence when one has an uncharacterised transform in it and the other has none. **The vertex stream is the stronger oracle** and should be preferred wherever the question can be asked of it. ## Reach ⟨canary-source⟩ for the gamma stub and the presenter defaults — these are facts about *this build*, and a different `--present_*` or `kernel_display_gamma_type` would change them. ⟨capture⟩ for the shader, which is the splash's; **other screens' shaders have not been checked for gamma** and the negative in §1 covers the splash only. ❔ **Not measured here: the resample's actual filter.** I read the cvars that say scaling happens, not the kernel that does it. What a 1280×720 → 1279×675 resample does to a thin glyph is unquantified, and that is the number anyone doing pixel-exact work against a PNG would need.