Repository navigation
perf(rendering): convert IOSurface frames straight into the layer frame texture - #2601
Merged
Merged
Conversation
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Member
Author
|
hey @greptileai, please re-review the PR |
richiemcilroy
force-pushed
the
perf/rendering-convert-into-layer-texture
branch
from
October 14, 2026 22:01
573e0c6 to
b1b0e81
Compare
Member
Author
|
hey @greptileai, please re-review the PR |
Member
Author
|
@greptileai review |
richiemcilroy
force-pushed
the
perf/rendering-convert-into-layer-texture
branch
from
October 15, 2026 07:42
b1b0e81 to
5f5082f
Compare
richiemcilroy
force-pushed
the
perf/rendering-convert-into-layer-texture
branch
from
October 18, 2026 15:04
5f5082f to
2f41dab
Compare
richiemcilroy
changed the base branch from
fix/export-camera-frame-runaway
to
main
October 18, 2026 15:04
Member
Author
|
@greptileai review |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On macOS the display and camera layers now convert decoded IOSurface frames straight into their own frame texture. This removes a full-size copy per frame and the converter's own pair of output textures. The source
CVPixelBufferis still held until the GPU has read it.flowchart LR subgraph Before A1[Decoded IOSurface NV12] -->|NV12 compute| B1[Converter output x2<br/>3072x1984 RGBA, 24 MB each] B1 -->|copy every frame| C1[Layer frame texture x2] end subgraph After A2[Decoded IOSurface NV12] -->|NV12 compute| C2[Layer frame texture x2] end C1 --> D[Composite pass] C2 --> Dframe_source = screen_frame .with_image_buf(|image_buf| { self.yuv_converter .convert_nv12_from_iosurface_into(device, encoder, image_buf, &self.frame_texture_views[next_texture]) .ok() }) .flatten(); // ... RetainedImageBuf::replace(queue, &mut self.frame_sources[next_texture], frame_source);Changes
convert_nv12_from_iosurface_into(crates/rendering/src/yuv_converter.rs:1115) runs the existing NV12 shader, bind layout and dispatch, but writes into a caller-owned view.convert_nv12_from_iosurface_to_encodershares the same encode helper (yuv_converter.rs:1134).crates/rendering/src/layers/display.rs:781,crates/rendering/src/layers/camera.rs:478). Every fallback path (CPU NV12, YUV420P, RGBA, CUDA, D3D11) and every other platform is unchanged.yuv_converter.rs:108). They grow on first use only if a fallback conversion needs them. Exports no longer pre-size them (crates/rendering/src/lib.rs:7359), and the camera sizes them only on fallback (camera.rs:493).RENDER_ATTACHMENT(crates/rendering/src/composite_frame.rs:424). Nothing renders into them. With that flag, wgpu's lazy zero-init ran a render pass ahead of the first conversion.Source buffer lifetime
convert_nv12_from_iosurface_intoreturns aRetainedImageBuf. Each layer stores it per frame-texture slot (display.rs:947,camera.rs:575).queue.on_submitted_work_done(yuv_converter.rs:445) instead of being dropped in place. By then the encoder that sampled it has always been submitted, so the release waits for that GPU work to finish. Slot reuse alone would not be enough: the pipelined export (finish_encoder_nv12_pooled) only waits for the previous frame, and transitions (produce_transition_texture,crates/rendering/src/lib.rs:8023) prepare the layers twice per frame. Tying the release to queue completion covers that case without depending on how many conversions are in flight, the same case the 4-slot ring from fix(rendering): keep IOSurface sources alive until the GPU has sampled them #2625 covers for the converter-owned path.Results
Rebased on
main(fa92b8556)#2595 was closed in favour of #2638, so this PR now carries only its own four commits on top of
main. M4 Max,cap export --fps 60, main and this PR built with the same profile, interleaved, 2 rounds. Fixtures are two real camera recordings: a 3024x1964 display (1243 output frames) and a 1706x1200 area (1162 frames).--force-ffmpeg-decoderEarlier, on the #2595 base
M4 Max. The baseline is the #2595 head (
905e0933d). Runs are interleaved A/B.Editor, studio-cam-60s (3024x1964 display + 720p camera). The editor is opened, renders its first frame, idles for 2.5 s, seeks 4 times, plays for 3 s, then closes. Footprint is sampled every 2 ms, 3 pairs:
Steady playback, 600 sequential frames from 10 s. GPU time is summed
GPUEndTime - GPUStartTimeper command buffer, 12 pairs:cap export --fps 60 --resolution 1920x1080:#2595's hole-map fix reverted, so camera frames are evicted from the decoder cache straight away. With theRetainedImageBufrelease disabled, two re-runs of studio-cam-180s differed from the first in 2344 and 1345 frames. With it, all 3 runs were bit-identical.Metal driver memory
MTLDevice.currentAllocatedSizestays flat, and the memory turns reclaimable about 1.5 s after the GPU goes idle.

Confidence Score: 5/5
The PR appears safe to merge; no actionable issues remain in the reviewed changes.Summary
On macOS, display and camera layers now convert IOSurface frames directly into their frame textures.
Reviews (5) · Last reviewed commit: "perf(rendering): start the YUV converter..." · Reviewed by Greptile