`Readbacks::new` spawned a thread that slept 100 ms and checked for expired readbacks forever,
whether or not anything was pending: ten wakeups a second for the life of every desktop session
with a GPU compositor (12–13 idle wakeups/s measured, against 0.4–1.8 for the sibling apps).
The worker now waits on a condition: indefinitely while nothing is pending, otherwise until the
earliest deadline or until what is pending changes (start, complete, cancel, retire poke it).
It owns the state behind an `Arc<Inner>` rather than the `Readbacks`, so dropping the context
closes it instead of leaking the thread. Timeout, exactly-once callbacks, panic isolation and the
browser's timer path are unchanged.
Measured on an M2 Max (release build, window on screen, 60 s samples, A/B interleaved): idle
wakeups 12.15/s → 2.63/s not frontmost, 12.36/s → 2.72/s frontmost.
Tests: an idle worker does not wake; a due deadline wakes it when due; dropping the context stops
it; the existing panic/strand test moves deadlines through a hook that notifies the worker.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Refraction samples are clamped to the layer rectangle instead of the buffer, so a sample past the
layer's edge in a buffer with transparent padding (a half-resolution preview's, a text or shape
layer's) repeats the layer's edge pixels rather than reaching the pale colour that stands in for
transparent ones. Transparent pixels inside the layer still show it. Same bounds on the GPU path.
Re-pins the four half-resolution CC Bubbles golden hashes (aarch64 macOS); the full-resolution
ones are unchanged. Adds a CPU test and a GPU-vs-CPU parity test on padded buffers.
ffmpeg 4.2 writes 2 in the sample entry of an AAC PCE layout and FilmCraft
decodes as many channels as that names, so the 6.1 check now reads a copy
naming all seven instead of skipping. Configuration 12 moves to the
synthetic layout tests.
Tones encoded with FilmCraft's AAC encoder, with the configuration rewritten
to 11, 12 or ffmpeg's 6.1 PCE where the coded elements fit it, so nothing
depends on ffmpeg or skips. Expected gains come from each channel's speaker.
The gains of an AAC source now come from the configuration FilmCraft decodes
it with, read from MP4/MOV (esds), Matroska (CodecPrivate) and LATM in MPEG
TS/PS (its first StreamMuxConfig). Channel configurations 3 to 6, 11 and 12
arrive reordered to WAVE order, 4 as L R C Cs, 7 in element order. A program
config element goes by its element positions, except the six structures in
which ffmpeg's encoder fills its own channel order across them (an LFE in a
side SCE, a back centre in a side pair), recognised by its "Lavc" comment.
ADTS can only signal configurations 1 to 7 that FilmCraft decodes, which the
channel count tells apart. A decode of fewer channels than the layout keeps
its first ones (7 of configuration 7's 8 in MPEG-TS LATM).
The README quoted 306 effects in three places while the registry (and the
generated docs/effects.md) had 307, now 308. A catalog test checks every
effect count the README gives against the registry.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dragging a mask or shape vertex, a tangent or a Pen point against the
edge of the Composition panel now pans the view toward that edge, faster
the further out the pointer is, and the point keeps moving with it, so
zoomed-in rotoscoping no longer stops at the panel edge (as in After
Effects).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ci(deps): bump storytold/craft-common-actions/.github/workflows/windows-arm64.yml from 8bb4e5ab95443171104ad88113fe1ef9b0e5ce3f to fa5ef18780cf5e7d5d3b8de068de56cffc83cac5 in the actions group
The encoder's first-frame user_data_unregistered SEI now lists its settings
("... - options: rc=vbr bitrate=10000 ... scenecut=1", 211 bytes where
"filmcraft-h264enc 0.1.1 - clean-room H.264 encoder" took 50): +161 bytes.
The same build gives (104322, 11051847956767423392), the pin Linux CI took on
a base before the 19-byte nclx colr box, when that box is left out, so the
bytes match across platforms.