Skip to content

Move the Metal renderer and CoreVideo surfaces onto objc2-metal and objc2-core-video - #3

Merged
chris-addison merged 1 commit into
unity/a11y-automationfrom
unity/objc2-migration
Sep 27, 2026
Merged

chris-addison merged 1 commit into
unity/a11y-automationfrom
unity/objc2-migration

Conversation

@chris-addison

Copy link
Copy Markdown
Collaborator

Moves gpui's macOS code off the legacy objc 0.2, block 0.1, metal 0.33 and core-video 0.5 crates onto objc2-metal and objc2-core-video 0.3.2. Both were already in the lockfile, so this adds no crates and changes no versions. block 0.1.6 is what triggered rustc's "code that will be rejected by a future version of Rust" warning.

Removed from the tree: block, objc, malloc_buf, metal, core-video, core-graphics2, io-surface, cgl, leak, leaky-cow. cargo tree --workspace -e all --target all -i <crate> finds none of them.

Scope

  • Our own legacy code was small: one block::ConcreteBlock in metal_renderer.rs and one use objc::* in the gpui_media bindings. gpui_macos already used objc2::msg_send! throughout.
  • block and objc only left the tree once metal and core-video were replaced too: metal 0.33 depends on both, and core-video 0.5.2 depends on block even without its metal feature.
  • Public API (macOS only), required to drop core-video and metal:
    • SurfaceSource::Surface carries CFRetained<objc2_core_video::CVPixelBuffer>.
    • ScreenCaptureFrame.0 is CFRetained<CVImageBuffer>.
    • MetalRenderer::layer() and layer_ptr() return objc2's CAMetalLayer.
    • media::core_media and media::core_video take and return objc2 types.
  • Retain semantics are preserved. Results from create/new calls are taken as owned, and getter results are retained.
  • Allocation failures now fail loudly. A Metal call that can fail (buffer, texture, queue, sampler, encoder) panics with a clear message instead of carrying a null pointer. The exceptions return an error: render_scene_to_image when the blit encoder can't be created, and draw_primitives_to_texture on a command-buffer failure.
  • Buffers crossing threads. Instance buffers returned from Metal's completion thread are wrapped in PooledBuffer (unsafe impl Send), with the justification next to it. The old metal crate made the same claim for its buffer type.
  • gpui_macos no longer depends on gpui_media: screen capture reads the image buffer through objc2-core-media.

Verification

  • cargo clippy --locked --workspace --all-targets -- -D warnings passes on macOS, and the future-incompatibility warning is gone.
  • cargo test passes for gpui-ce (356), gpui_ce_apple (13, including the 9 headless Metal pixel checks for quads, borders, shadows, blur, sprites and paths), gpui_ce_macos (13) and gpui_ce_wgpu (42).
  • The hello_world and blur examples open on-screen windows and run cleanly. No visual capture: the session had no Screen Recording permission.
  • cargo fmt --all -- --check is clean.
  • Already failing on the base commit 79ace671, unchanged by this PR:
    • redundant_clone in gpui_macos/src/screen_capture.rs when the screen-capture feature is on;
    • the bench-support feature doesn't compile.

🤖 Generated with Claude Code

…bjc2-core-video

block 0.1.6 trips rustc's future-incompatibility warning, and it only
reached the tree through the legacy objc 0.2 stack: our own
metal_renderer used block::ConcreteBlock, gpui_media used objc, and the
metal 0.33 and core-video 0.5 crates (plus core-graphics2 under
core-video) depend on block and objc unconditionally. Removing our own
uses was not enough, so this replaces both crates.

- gpui_apple: the Metal renderer and atlas use objc2-metal and
  objc2-quartz-core's CAMetalLayer directly. Selectors, blend state,
  storage modes and pass structure are unchanged; the completed
  handler is a block2 RcBlock. Instance buffers are wrapped in a
  PooledBuffer that is Send, restating the ownership contract the
  metal crate's Send impls asserted (objc2 leaves MTLBuffer !Send).
- gpui, gpui_wgpu, gpui_macos: CVPixelBuffer/CVImageBuffer come from
  objc2-core-video as CFRetained values. This changes the type carried
  by SurfaceSource::Surface and ScreenCaptureFrame on macOS.
- gpui_macos: screen capture reads the image buffer through
  objc2-core-media and no longer depends on gpui_media; the layer's
  contentsScale is set through the typed CALayer setter.
- gpui_media: its core_video module takes and returns objc2 types, and
  the unused objc glob import in the bindgen wrapper is gone.

block, objc, malloc_buf, metal, core-video, core-graphics2, io-surface,
cgl, leak and leaky-cow leave Cargo.lock. No remaining version moves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chris-addison
chris-addison merged commit 512f0ab into unity/a11y-automation Sep 27, 2026
18 checks passed
@chris-addison
chris-addison deleted the unity/objc2-migration branch September 27, 2026 04:45
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