Files
ayamir 43a22855a2 perf(graphics): move kitty frame pixels instead of copying them (#388)
A re-transmitting sender like terminal-browser sends a fresh full-window
frame per rendered frame — ~26 MiB of RGBA at Retina resolution. On the
client that buffer was copied twice for no reason on the way to the atlas:
`decode_frame` allocated a new Vec for the payload tail behind the 30-byte
header, and the uncompressed path of `to_rgba8` then cloned it again before
the in-place BGRA swap.

Thread ownership through instead:

- `Image::decode_frame_owned` consumes the frame Vec the reader already owns
  off the socket and drains the header off the front, reusing that allocation
  as the pixel buffer rather than allocating and copying a fresh one.
- `Image::take_rgba8` moves the pixel buffer out on the uncompressed fast
  path (the shm/file transport hands us pixels already in `f=32` layout), so
  `decode` swaps R<->B in place with no clone. The compressed inflate, the
  PNG guard, and the declared-dimension inflate bound are unchanged; `f=24`
  still repacks because RGB->RGBA changes the length.

Removes two ~26 MiB per-frame touches on the client hot path. On a 3216x2160
frame the decode+normalize step drops from ~1.78 ms to ~0.89 ms — ~0.9 ms
saved per frame, ~53 ms/s at 60fps. This does not touch the wire frame layout
or the daemon-side transfer; it is a pure client-side allocation cut.
2026-08-07 23:30:11 +08:00
..