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.
Description
Use the
objc2-metal
crate instead of themetal
crate. This will:Arc
andMutex
, as Metal objects are already reference-counted (depending on thread-safety details, not entirely sure).objc_retainAutoreleasedReturnValue
underneath the hood to avoid putting objects into the autorelease pool when possible, reducing memory pressure.Background
The
metal
crate contains bindings to the Metal framework. This usesobjc
to manually perform the message sends, which is quite error-prone, see gfx-rs/metal-rs#284, gfx-rs/metal-rs#319 and gfx-rs/metal-rs#209 for a few examples of unsoundness (out of many).To solve such problems in the Rust ecosystem in general, I created a successor to
objc
calledobjc2
, which contains most notably the smart-pointerRetained
and the macromsg_send_id!
, which together ensure that Objective-C's memory-management rules are upheld correctly.This is only part of the solution though - we'd still have to write the bindings manually. To solve this, I created a tool (planning to integrate it with
bindgen
, but that's likely a multi-year project) to generate such framework crates automatically. In acknowledgement that this tool is by far not perfect, and never will be, I've ensured that there's a bunch of options to modify each generated crate.The modifications for
objc2-metal
in particular are currently just a few hundred lines of code, weak evidence that the generator is fairly good at this point. I'll also bring attention to the file whereunsafe
methods are marked safe - I have plans to investigate ways to semi-automatically figure out if something is safe or not, or at least reduce the burden of doing so, but it's a hard problem to ensure is completely sound, so for now it's a bit verbose.Connections
gpu-allocator
is also transitioning toobjc2-metal
in Traverse-Research/gpu-allocator#225.gfx-rs/metal-rs#241 is an old open PR for using
objc2
inmetal
internally instead. There currently isn't really a clear path forwards there, and it's a lot of work for less direct benefits to the ecosystem (wgpu-hal
is by far the biggest user ofmetal
). But more fundamentally IMO, it's a problem of separation of concerns;metal
defines several Foundation types likeNSArray
,NSString
,NSError
and so on, and evenCAMetalLayer
from QuartzCore, and that's a bad idea for interoperability compared to having separate crates for each of these frameworks.Implementation
The first commit removes the
link
feature which is not available in these crates. This was added by @crowlKats in #3853, but Deno doesn't actually use it from what I can tell, they instead specify this using-weak_framework
, which is the correct solution to this problem IMO. (If I'm wrong about this, please say so, I could be persuaded to add a similar feature to theobjc2-...
crates).The second commit implements the actual migration, by using a branch of
objc2
, with a method naming scheme that (more closely) matchesmetal
, to make it easier to review and test what's changed.The third commit moves to the real naming scheme that
objc2
uses.I'd strongly recommend you review these two commits separately.
Testing
Tested by using the checklist below, as well as running each example individually, and checking that they seem to work.
During the development of this I made two quite critical typos, which were luckily found by the test suite, but there's bound to be at least one more lurking in here somewhere, please test this thoroughly!
Checklist
cargo fmt
.cargo clippy
.cargo xtask test
to run tests.CHANGELOG.md
. See simple instructions inside file.