diff --git a/docs/re/movie-decode-vs-rotate-preregistration.md b/docs/re/movie-decode-vs-rotate-preregistration.md new file mode 100644 index 00000000..de42a7c4 --- /dev/null +++ b/docs/re/movie-decode-vs-rotate-preregistration.md @@ -0,0 +1,69 @@ +# Pre-registration — did the guest DECODE a frame, or just ROTATE a buffer? + +**Written and committed BEFORE the capture.** 2026-09-01. This is the experiment +named by [`guest-frame-rate-WITHDRAWN.md`](guest-frame-rate-WITHDRAWN.md) as the +one that settles what that page withdrew. + +--- + +## Why this exists + +I measured "one movie luma **base address** change per present", read it as one +decode per present, and concluded 30 fps / 60 units/s. That was withdrawn: a +triple buffer **rotating** once per present visits the same three addresses +whether or not anything was decoded into them, so base identity cannot separate: + +* **D — decode per present.** The guest decodes a new movie frame every present. + With `ADV.wmv` authored at 30.000 fps, the guest presents at 30 fps ⇒ **60 + units/s** ⇒ the plate's `t = 236` is 3.93 s. +* **R — rotate per present.** The guest presents twice per decoded frame. Then it + presents at 60 fps ⇒ **120 units/s** ⇒ the plate is at 1.97 s and the port is + ~2 s late, which is the size of the play-test complaint. + +## The instrument + +The draw logger now emits a **content hash** beside every sampled texture — +FNV-1a over 4096 bytes spread across the allocation, `h=` omitted rather than +faked when the address does not translate, so a missing hash can never read as a +matching one. Built and linked; `command_processor.cc` only. + +## 🔴 The predictions, stated now + +Over consecutive presents during attract-movie playback, the fraction of pairs +whose **luma content hash differs**: + +| | fraction of consecutive presents with changed luma content | +|---|---| +| **D** — decode per present ⇒ 60 units/s | **≈ 1.00** | +| **R** — rotate per present ⇒ 120 units/s | **≈ 0.50** | + +I will accept D within `1.00 −0.10` and R within `0.50 ± 0.10`, and report +"neither" otherwise rather than taking the closer. Under R I additionally expect +the *repeat pattern* to be period-2 — each hash appearing on exactly two adjacent +presents — and I will report the run-length distribution, not just the fraction. + +## 🔴 The control, and this time it tests the thing the last one did not + +**A static texture must hash constant.** The splash sprite page `0x11A50000` +(1280×768) is a fixed atlas: it is uploaded once and sampled for both splashes. +If its hash varies between presents, the hash is unstable — reading raw guest +memory at draw time can race the decoder — and **nothing else in the log may be +read**. This control fails loudly in the direction that would otherwise +manufacture the D result, which is exactly the property my previous control +lacked. + +Second control, the other direction: the movie's luma hash must **not** be +constant across the whole movie region either. A hash that never changes would +mean I am hashing the wrong bytes, and would manufacture R. + +## What would still not be settled + +Whether Canary's presentation cadence equals a real console's. This measures what +the guest does *here*. The vblank-interval evidence (one vblank 71.7 %, two +24.6 %) is consistent with R and is what motivated re-opening this, but it is host +time and cannot stand alone. + +⚠️ And a third possibility the two hypotheses do not cover: the guest may decode +at a rate unrelated to both, in which case the fraction lands between the bands +and the honest answer is "neither", with the movie ruler abandoned rather than +stretched to fit.