Skip to content

perf(rendering): wake macOS surface exports on Metal completion instead of polling - #2648

Merged
richiemcilroy merged 2 commits into
mainfrom
fix/macos-surface-completion-wait
Oct 16, 2026
Merged

richiemcilroy merged 2 commits into
mainfrom
fix/macos-surface-completion-wait

Conversation

@richiemcilroy

@richiemcilroy richiemcilroy commented Oct 16, 2026 •

Copy link
Copy Markdown
Member

macOS hardware exports render each frame into an IOSurface for VideoToolbox. They then waited for the GPU by polling wgpu and sleeping for up to 1 ms per poll. Waking on Metal's own completion handler instead makes exports 18 to 27% faster, with byte-identical output.

sequenceDiagram
    participant Export
    participant wgpu
    participant Metal
    Export->>wgpu: submit NV12 surface conversion
    Export->>Metal: commit empty marker command buffer on the same queue
    Metal-->>Export: marker completed handler (oneshot)
    Export->>wgpu: one non-blocking poll to retire wgpu's own work
    Export->>Export: hand the IOSurface to VideoToolbox
Loading
  • RgbaToNv12Converter::after_submit commits an empty command buffer on wgpu's Metal queue, holding the HAL queue lock. Its completed handler sends the buffer status over a oneshot (crates/rendering/src/frame_pipeline.rs:896).
  • A Metal queue runs its command buffers in commit order, so the marker completes only after the conversion submitted before it. wgpu's own submission tracking relies on the same ordering.
  • PendingNv12Surface::wait awaits the oneshot under the existing export or playback deadline. A marker that completes with an error status, or a dropped handler, still fails with BufferMapWaitingFailed.
  • Only the macOS surface path changes. Readback output, Windows and Linux compile to the same code as before.

Export wall time

Apple silicon, release build, 8 interleaved control/candidate pairs per workload, median:

Workload main This PR Change Instructions
export/basic/* 29.35 s 24.02 s -18.2% -0.55%
export/jitter-camera-120s/* 104.28 s 76.64 s -26.5% -0.16%
  • All 63 exported files from export/* (full tier) have the same per-frame video MD5s and the same PCM as main's.
  • Seek and playback workloads do not reach this code: surface output is enabled only by render_video_to_channel_nv12.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no actionable issues were found.

Summary

macOS NV12 surface exports now await a Metal completion signal instead of repeatedly polling wgpu.

  • macOS surface exports wake when Metal finishes each frame.

Reviews (1) · Last reviewed commit: "fix: wake macOS surface exports on GPU c..." · Reviewed by Greptile

@vercel

vercel Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
cap-status Ready Ready Preview Oct 16, 2026 2:17pm UTC

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

View 1 other finding in Capy.

Open in Capy

@capy-ai capy-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capy found no issues.

Open in Capy

@richiemcilroy
richiemcilroy merged commit b49ed4b into main Oct 16, 2026
52 checks passed

This branch was successfully deployed

2 active deployments
Preview – cap-web — 604a7803 Deployed Oct 16, 2026 by vercel[bot]
Preview – cap-status — 604a7803 Deployed Oct 16, 2026 by vercel[bot]
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.

1 participant