Skip to content

DecodeBufferPool silently defeated for HAP: acquire/release size-bucket mismatch #77

Description

@duremovich

From the 2026-07-03 comprehensive review.

The decode thread pre-sizes the scratch buffer as RGBA8 (prepareDecodeBuffer(frame, decW, decH, RGBA8_UNORM), DecodeSystem.cpp:963-970 → decWdecH4 bucket). HAPDecoder::decodeFrame moves it into hap.textureData (HAPDecoder.cpp:303); parseHapPacket does textureData.clear() then resize(uncompressedSize) (HapFormat.cpp:320,156) — shrinking size() to the BC block count (4-8x smaller). On eviction the FrameCache deleter releases keyed by buf.size() = BC size (DecodeBufferPool.cpp:33), but the next acquire asks for the RGBA8 size (:11) → different buckets → released HAP buffers are never re-acquired.

Net effect: every HAP frame does a fresh value-initialized (zeroed) std::vector(decW*decH*4) — exactly the churn the pool exists to kill, on the codec ADR-0002 designates as THE tuned playback path. Under stress_8layer / stress_16screen (6x HAP) this is multi-GB/s of malloc+zero.

Fix: size the decode buffer by the decoder's actual output format/size instead of hardcoded RGBA8, so acquire and release use the same bucket. Verify with a Tracy capture on stress_16screen_progressive before/after (decode-zone p95 + allocation plots).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingtier:coreLives in core (GPLv3, in-repo); always free, fully featured

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions