Skip to content

perf(producer): cache transfer-converted hdr image buffers per render job#384

Open
vanceingalls wants to merge 1 commit intovance/logger-level-gatingfrom
vance/hdr-image-transfer-cache
Open

perf(producer): cache transfer-converted hdr image buffers per render job#384
vanceingalls wants to merge 1 commit intovance/logger-level-gatingfrom
vance/hdr-image-transfer-cache

Conversation

@vanceingalls
Copy link
Copy Markdown
Collaborator

@vanceingalls vanceingalls commented Apr 21, 2026

Summary

Add HdrImageTransferCache — a per-render-job bounded LRU keyed by (imageId, targetTransfer) — so static HDR image layers whose source transfer differs from the render's effective transfer (PQ↔HLG) are converted once per job instead of once per composited frame.

Why

Chunk 8B of plans/hdr-followups.md. blitHdrImageLayer was running Buffer.from + convertTransfer on every composited frame, even though the converted buffer is identical for the entire job. For a multi-second comp at 30 fps this is hundreds of redundant transfer conversions on the hot path.

What changed

  • New packages/producer/src/services/hdrImageTransferCache.ts — bounded LRU keyed by (imageId, targetTransfer) that owns the converted HDR rgb48 buffer for static HDR image layers:
    • Same-transfer requests return the source buffer untouched (zero copy).
    • Cross-transfer requests pay one Buffer.from + convertTransfer on first miss, reuse the cached copy on every subsequent frame.
  • Wired into renderOrchestrator.ts via HdrCompositeContext.hdrImageTransferCache, instantiated once per render job, and consumed by blitHdrImageLayer on both the main composite path and the transition path.

Test plan

  • packages/producer/src/services/hdrImageTransferCache.test.ts — 12 tests:
    • hit/miss semantics
    • distinct keys per image and per target transfer
    • LRU eviction + promotion
    • maxEntries=0 passthrough
    • source-buffer immutability for cached entries
    • invalid options
  • Re-ran the Chunk 8A HDR benchmark — for the hdr-regression fixture (which has cross-transfer image layers) the cache hits 100% after the first frame; for HDR fixtures without cross-transfer images the same-transfer passthrough is a no-op.

Stack

Chunk 8B of plans/hdr-followups.md. Sits on top of Chunk 8C (logger gating) and Chunk 8A (benchmark harness) so the win is measurable.

Copy link
Copy Markdown
Collaborator Author

vanceingalls commented Apr 21, 2026

Warning

This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from 55a41a8 to 349f0f6 Compare April 22, 2026 22:13
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from b71cf6f to 3c4754f Compare April 22, 2026 22:13
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from 349f0f6 to cd65ab0 Compare April 22, 2026 22:54
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch 2 times, most recently from e49a01f to a801330 Compare April 22, 2026 23:26
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from 5409b1a to c6a8280 Compare April 23, 2026 00:07
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from a801330 to 2af81de Compare April 23, 2026 00:08
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from c6a8280 to 2ce89a5 Compare April 23, 2026 00:12
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from 2af81de to a3d4984 Compare April 23, 2026 00:12
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from 2ce89a5 to b8d319d Compare April 23, 2026 00:45
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from a3d4984 to b3241ce Compare April 23, 2026 00:45
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from b8d319d to d222b31 Compare April 23, 2026 01:58
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from b3241ce to 8b636ec Compare April 23, 2026 01:58
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from d222b31 to e72f484 Compare April 23, 2026 02:59
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from 8b636ec to 6bc1dd6 Compare April 23, 2026 03:00
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from e72f484 to 5338173 Compare April 23, 2026 03:22
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from 6bc1dd6 to b03a62f Compare April 23, 2026 03:23
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from 5338173 to b99006d Compare April 23, 2026 03:44
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from b03a62f to 31915d0 Compare April 23, 2026 03:45
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from b99006d to 644607f Compare April 23, 2026 04:52
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from 31915d0 to 90bd43b Compare April 23, 2026 04:53
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from 644607f to 0d7dd4c Compare April 23, 2026 05:12
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from 90bd43b to 4555013 Compare April 23, 2026 05:13
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from 0d7dd4c to 50cc3df Compare April 23, 2026 05:47
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from 4555013 to 1f61054 Compare April 23, 2026 05:48
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from 50cc3df to bd2cbff Compare April 23, 2026 06:07
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from 1f61054 to 0b54ff2 Compare April 23, 2026 06:07
@vanceingalls vanceingalls force-pushed the vance/logger-level-gating branch from bd2cbff to 732d2d4 Compare April 23, 2026 07:00
… job

Static HDR image layers whose source transfer differs from the render's effective
transfer (PQ↔HLG) were re-running `Buffer.from` + `convertTransfer` on every
composited frame, even though the converted buffer is identical for the entire
job. Added `HdrImageTransferCache` — a per-render-job bounded LRU keyed by
`(imageId, targetTransfer)` that converts once and reuses on every subsequent
frame, while leaving same-transfer requests as a zero-copy passthrough.

Wired into `renderOrchestrator.ts` via `HdrCompositeContext.hdrImageTransferCache`,
instantiated once per job and consumed by `blitHdrImageLayer` on both the main
composite path and the transition path. Covered by `hdrImageTransferCache.test.ts`
(hit/miss, distinct keys per image and per target transfer, LRU eviction +
promotion, `maxEntries=0` passthrough, source-buffer immutability for cached
entries, invalid options).

Made-with: Cursor
@vanceingalls vanceingalls force-pushed the vance/hdr-image-transfer-cache branch from 0b54ff2 to 0afa982 Compare April 23, 2026 07:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants