re: reconcile the two ink counts -- we agree at >1 and not at >0

The port agent produced a genuine second witness for the pixel-cost claim: it
re-checked GP_TITLE entry 12 in Godot, which shares no code with compose,
swapping only paint_order. 59 530 px ink with the rule, exactly 0 without it.
The strong form -- the screen ceasing to exist, not merely changing a lot --
now has two real renderers behind it on that entry.

Its figures did not match ours, so I counted the same composite every way:

    RGB > 0    ours 49 771   Godot 59 530    16 %  apart
    RGB > 1    ours 48 043   Godot 48 368    0.68 % apart

The entire disagreement lives in pixels whose value is exactly 1. That is a
1-LSB sampling artefact between two samplers, not a different set of inked
pixels. So '>0' is not a portable ink convention between renderers on a
mostly-dark frame and '>1' is; any future cross-renderer ink figure should say
which it used.

Also worth recording: our 49 771 was never a threshold figure. It is exact RGBA
inequality between the two paint orders, which over a black backdrop coincides
with ink>0 -- so it belongs against the port's 59 530, not its 48 368. Matching
it to the 48 368 would have made the two renderers look like they agreed for
the wrong reason.

The without-the-rule column is 0 at every threshold here too, matching Godot:
the strong form is not threshold-sensitive in either renderer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wuu56cE8vJGTBtn1ppsk8v
This commit is contained in:
sylph-decoder
2026-08-30 07:07:21 +00:00
parent 5c70e5d545
commit 215943e873
3 changed files with 194 additions and 0 deletions

View File

@@ -0,0 +1,90 @@
//! Reconcile two ink counts for one screen that were never counting the same pixels.
//!
//! The port agent double-witnessed the pixel-cost claim in Godot — a renderer
//! sharing no code with `compose` — and got `GP_TITLE` entry 12 at **59 530 px**
//! ink above threshold 0 and **48 368** above 1. This crate reported **49 771**.
//! Neither is wrong; the question is which convention each was using, and on a
//! mostly-dark frame the answer moves thousands of pixels.
//!
//! So: count the same composite every way, and print the family. Whichever row
//! the port's numbers land in is the convention, and then the two renderers can be
//! compared on purpose rather than by coincidence.
//!
//! cargo run -p sylpheed-formats --example forced_backdrop_ink_thresholds
use std::path::PathBuf;
use sylpheed_formats::{pak::PakArchive, ui_layout};
use ui_layout::ComposeOptions;
fn order_without_rule(build: &ui_layout::UiBuild, bundle: &[u8]) -> Vec<usize> {
let mut idx: Vec<usize> = (0..build.elements.len()).collect();
idx.sort_by_key(|&i| {
let el = &build.elements[i];
(
ui_layout::sprite_layer_key(build, bundle, el)
.or_else(|| ui_layout::implied_layer_key(&el.name))
.unwrap_or(u32::MAX),
i,
)
});
idx
}
fn counts(rgba: &[u8], t: u8) -> (usize, usize) {
let rgb = rgba
.chunks_exact(4)
.filter(|p| p[0] > t || p[1] > t || p[2] > t)
.count();
let alpha = rgba.chunks_exact(4).filter(|p| p[3] > t).count();
(rgb, alpha)
}
fn main() {
let root = PathBuf::from(std::env::var("SYLPHEED_DISC").expect("SYLPHEED_DISC"));
let ar = PakArchive::open(root.join("dat/GP_TITLE.pak")).expect("GP_TITLE.pak");
for entry in [12usize, 15] {
let by = ar.read(&ar.entries()[entry]).expect("entry");
let b = ui_layout::parse_build(&by).expect("parse");
for (label, opts) in [
(
"primitives on (what the cost run used)",
ComposeOptions {
include_primitives: true,
backdrop: [0, 0, 0, 255],
..Default::default()
},
),
(
"primitives+focus+animated",
ComposeOptions {
include_primitives: true,
include_focus: true,
include_animated: true,
backdrop: [0, 0, 0, 255],
..Default::default()
},
),
] {
let with = ui_layout::derived_paint_order(&b, &by);
let without = order_without_rule(&b, &by);
let a = ui_layout::compose_with_order(&b, &by, opts.clone(), None, Some(&with));
let c = ui_layout::compose_with_order(&b, &by, opts, None, Some(&without));
println!("\n== GP_TITLE entry {entry}{label} ({}x{})", a.width, a.height);
println!(" threshold | RGB>t with rule | A>t with rule | RGB>t WITHOUT | A>t WITHOUT");
for t in [0u8, 1, 2, 4, 8, 16] {
let (r1, a1) = counts(&a.rgba, t);
let (r0, a0) = counts(&c.rgba, t);
println!(" >{t:<8} | {r1:>16} | {a1:>14} | {r0:>13} | {a0:>11}");
}
let changed = a
.rgba
.chunks_exact(4)
.zip(c.rgba.chunks_exact(4))
.filter(|(x, y)| x != y)
.count();
println!(" exact-RGBA changed pixels between the two orders: {changed}");
}
}
}

View File

@@ -0,0 +1,61 @@
# Reconciling two ink counts for GP_TITLE entries 12/15 that were never
# counting the same pixels.
#
# Produced by: cargo run -p sylpheed-formats --example forced_backdrop_ink_thresholds
# 2026-08-30, SYLPHEED_DISC=/disc, 1280x720, black backdrop.
#
# The port agent's Godot second witness for entry 12 (build_12, --pose=rest):
# >0 59 530 px >1 48 368 px without the rule: 0 at both
#
# This crate, same entry, primitives-on (the convention the cost run used):
# >0 49 771 px >1 48 043 px without the rule: 0 at every threshold
#
# CONCLUSION: the >1 counts agree to 0.68 % (325 px). The >0 counts differ by
# 16 %. So the disagreement lives entirely in pixels whose value is exactly 1 --
# a 1-LSB artefact of a different sampler, not a different set of inked pixels.
# >0 is NOT portable between these two renderers on a mostly-dark frame; >1 is.
#
# Note also: our reported 49 771 was never an ink THRESHOLD figure. It is exact
# RGBA inequality between the two paint orders, which over a black backdrop
# coincides with ink>0 -- so it belongs against the port's 59 530, not its 48 368.
#
== GP_TITLE entry 12 — primitives on (what the cost run used) (1280x720)
threshold | RGB>t with rule | A>t with rule | RGB>t WITHOUT | A>t WITHOUT
>0 | 49771 | 921600 | 0 | 921600
>1 | 48043 | 921600 | 0 | 921600
>2 | 44884 | 921600 | 0 | 921600
>4 | 41946 | 921600 | 0 | 921600
>8 | 38409 | 921600 | 0 | 921600
>16 | 32760 | 921600 | 0 | 921600
exact-RGBA changed pixels between the two orders: 49771
== GP_TITLE entry 12 — primitives+focus+animated (1280x720)
threshold | RGB>t with rule | A>t with rule | RGB>t WITHOUT | A>t WITHOUT
>0 | 54968 | 921600 | 0 | 921600
>1 | 52058 | 921600 | 0 | 921600
>2 | 48171 | 921600 | 0 | 921600
>4 | 44396 | 921600 | 0 | 921600
>8 | 40064 | 921600 | 0 | 921600
>16 | 33791 | 921600 | 0 | 921600
exact-RGBA changed pixels between the two orders: 54968
== GP_TITLE entry 15 — primitives on (what the cost run used) (1280x720)
threshold | RGB>t with rule | A>t with rule | RGB>t WITHOUT | A>t WITHOUT
>0 | 49771 | 921600 | 0 | 921600
>1 | 48043 | 921600 | 0 | 921600
>2 | 44884 | 921600 | 0 | 921600
>4 | 41946 | 921600 | 0 | 921600
>8 | 38409 | 921600 | 0 | 921600
>16 | 32760 | 921600 | 0 | 921600
exact-RGBA changed pixels between the two orders: 49771
== GP_TITLE entry 15 — primitives+focus+animated (1280x720)
threshold | RGB>t with rule | A>t with rule | RGB>t WITHOUT | A>t WITHOUT
>0 | 54968 | 921600 | 0 | 921600
>1 | 52058 | 921600 | 0 | 921600
>2 | 48171 | 921600 | 0 | 921600
>4 | 44396 | 921600 | 0 | 921600
>8 | 40064 | 921600 | 0 | 921600
>16 | 33791 | 921600 | 0 | 921600
exact-RGBA changed pixels between the two orders: 54968

View File

@@ -289,6 +289,49 @@ builds across seven archives rather than argued on two.
For the port's two: `GP_TITLE` entries 12 and 15 each move **49 771 px = 5.40 %** of
the frame, which is their entire ink.
### ✅ Second witness (2026-08-30): the strong form holds in Godot too
The port agent re-checked the 38-`.prm` result in **Godot**, which shares no code
with `compose`, applying this crate's fallback to its own element list and swapping
**only** `paint_order` on one screen file — renderer, textures and pose all held
fixed, so the order is the single variable. `GP_TITLE` entry 12 came out at
**59 530 px** ink with the rule and **exactly 0 without it**, at both of its
thresholds.
That is the claim that needed a second renderer, because it is the strong form: not
"a large difference" but *the screen ceasing to exist*. Two renderers, and this
time genuinely two — unlike the necessity census, where the port's re-run was this
crate's code executed twice.
#### ⚠️ …and the two ink figures were never counting the same pixels
The port reported 59 530 (>0) and 48 368 (>1); this page said 49 771. Counting the
same composite every way
([`../data/forced-backdrop-ink-thresholds.txt`](../data/forced-backdrop-ink-thresholds.txt)):
| threshold | this crate | Godot | gap |
|---|---|---|---|
| RGB > 0 | 49 771 | **59 530** | 16 % |
| RGB > 1 | **48 043** | **48 368** | **0.68 %** |
**The whole disagreement lives in pixels whose value is exactly 1.** Above that the
two renderers agree to 325 px on a 921 600-px frame. So it is a 1-LSB sampling
artefact — a different sampler putting a faint non-zero where this one puts exact
zero — and not a different set of inked pixels.
Two things to carry from that:
* **`> 0` is not a portable ink convention between renderers on a mostly-dark
frame; `> 1` is.** Any future cross-renderer ink comparison should say which.
* **The 49 771 in this page was never a threshold figure at all.** It is exact RGBA
inequality between the two paint orders, which over a black backdrop coincides
with ink > 0 — so it belongs against the port's 59 530, not its 48 368. Reading it
as the `>1` number would have made the two renderers look like they agreed for the
wrong reason.
✅ The *without-the-rule* column is **0 at every threshold** here as well, matching
Godot. The strong form is not threshold-sensitive in either renderer.
### 🔴 The zero on the 24 `.tbm` builds is my instrument, not a finding
**The control I wrote was the wrong control and it passed anyway.** It asked