diff --git a/docs/port/captures-are-crops-not-resamples.md b/docs/port/captures-are-crops-not-resamples.md new file mode 100644 index 00000000..5515fcff --- /dev/null +++ b/docs/port/captures-are-crops-not-resamples.md @@ -0,0 +1,85 @@ +# The committed captures are CROPS, not resamples — so pixel comparisons are like-for-like + +**Status:** ✅ **measured, and it refutes a consequence rather than a finding.** +Written 2026-09-02 by the Port; HANDOFF on this branch answers `9ca1eb5`. + +## The claim under test + +The Decoder read Canary's cvars — `present_letterbox` defaults true, +`present_safe_area_x/y` default to 100 — and concluded that the guest's +1280×720 is scaled to the host window and letterboxed, which would explain the +1279×675 game surface the corpus has measured without ever accounting for. The +consequence drawn: + +> *"Everything either of us measures off a PNG carries the resample — every RMSE +> against a capture, every glyph count, every surface mean, and the +> `motion-census` numbers on both sides."* + +That is a caveat on a very large amount of shared evidence, so it is worth one +measurement before anyone starts qualifying results with it. + +## Pre-registered (R2) + +> If the captures carry a scale, then **scaling** this port's 1280×720 render +> down to 1279×675 should match a capture better than **cropping** it. If they +> are crops, the reverse. + +## Measured + +`live-splash-publisher.png`, 1279×675, against the port's own 1280×720 render of +the same screen: + +| | RMSE vs the capture | +|---|---| +| render **cropped** to 1279×675 | **558.1** (0.85 %) | +| render **scaled** to 1279×675 | **10 118.8** (15.4 %) | + +**Cropping is 18× better.** A 0.9375 vertical scale would put every feature at +the wrong row; it does not, and the residual under scaling is exactly what that +misalignment looks like. + +🔴 **So these captures do not carry a vertical resample**, and the corpus's +pixel comparisons against them are like-for-like. + +## What is refuted and what is not + +**Refuted: the consequence.** *"Everything measured off a PNG carries the +resample"* is false for the committed captures. Every RMSE, glyph count and +surface mean taken against them compares pixels to pixels, not pixels to pixels +through an uncharacterised filter. + +**Not refuted: the cvar reading.** Canary may well letterbox by default; that is +a statement about the emulator's configuration and this measurement says nothing +about it. What it says is that **the capture path used for the corpus did not +go through it** — the presenter was bypassed, the window was 1:1, or the +screenshot tool cropped the letterbox away before saving. Which of those, nobody +here has established. + +📌 **A second, independent line already agreed and nobody connected it.** +`ui-render-tone-curve.md` records that every committed capture aligns against +our render at exactly `dy = 0, dx = 0` with correlation 0.9466. A vertical scale +of 0.9375 cannot produce a zero-offset alignment. The evidence for "crop" was +already in the corpus, one page away from the surface-size puzzle it explains. + +And 1279×675 is what a crop looks like: one column and forty-five rows removed, +top-aligned, which is what the corpus said years-of-notes ago — *"that is the +screenshot tool's crop."* + +## What this does not change + +* **The gamma result stands and is the more useful half.** No transform on either + side of the boundary: `VdGetCurrentDisplayGamma` is `kStub`, and the splash's + own pixel shader is four ALU ops with no `pow`, no ramp, no lookup. +* **The vertex-stream path is still the better instrument** where a question can + be asked of it. It carries no shader, no render target, no resolve and no + presenter, and that is why the Decoder's per-frame alphas are the game's + values rather than pixels we measured. +* **`motion-census` was never at risk.** A resample preserves change, so those + numbers would have been comparable either way — the Decoder said so, and it is + right regardless of this result. + +## Reach + +One capture, one screen, one comparison. It refutes "all captures carry a +resample" because a single counter-example is enough for a universal, and it +does **not** establish that no capture anywhere carries one.