Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support protocol.MTLDevice.methods."newTextureWithDescriptor:iosurface:plane:" #643

Closed
sotaroikeda opened this issue Aug 1, 2024 · 10 comments
Labels
A-framework Affects the framework crates and the translator for them enhancement New feature or request

Comments

@sotaroikeda
Copy link

The newTextureWithDescriptor:iosurface:plane: is not supported. It is necessary for
gfx-rs/wgpu#5641 to be used by gecko see Bug 1910043.

@madsmtm madsmtm added enhancement New feature or request A-framework Affects the framework crates and the translator for them labels Aug 11, 2024
@madsmtm
Copy link
Owner

madsmtm commented Aug 11, 2024

Indeed, it is intentionally skipped because we don't expose IOSurfaceRef in any shape or form.

The proper solution needs support for CoreFoundation, for now you can do something like:

#[repr(transparent)]
struct IOSurfaceRefWrapper(io_surface::IOSurfaceRef);

// SAFETY: `IOSurfaceRefWrapper` is `#[repr(transparent)]` over
// `IOSurfaceRef`, which is a typedef to `struct __IOSurface *`.
unsafe impl Encode for IOSurfaceRefWrapper {
    const ENCODING: Encoding = Encoding::Pointer(&Encoding::Struct("__IOSurface", &[]));
}

pub fn new_with_descriptor_surface_plane(
    device: &ProtocolObject<dyn MTLDevice>,
    descriptor: &MTLTextureDescriptor,
    surface: io_surface::IOSurfaceRef,
    plane: NSUInteger,
) -> Retained<ProtocolObject<dyn MTLTexture>> {
    let surface = IOSurfaceRefWrapper(surface);
    msg_send_id![device, newTextureWithDescriptor: descriptor, iosurface: surface, plane: plane]
}

This approach is somewhat documented in here.

@madsmtm
Copy link
Owner

madsmtm commented Jan 9, 2025

Update: We now have fairly good support for CoreFoundation, and by extension IOSurfaceRef from the IOSurface framework too.

So I've now un-skipped the newTextureWithDescriptor:iosurface:plane: method, to be released soon.

@madsmtm madsmtm closed this as completed Jan 9, 2025
@ericssz
Copy link

ericssz commented Jan 25, 2025

@madsmtm May I ask how it is possible to create an IOSurface reference (IOSurfaceRef) from IOSurface?

let surface = IOSurface::new();

The created surface is a Retained<IOSurface>.

I need it for functions such as IOSurfaceLock and IOSurfaceGetBaseAddress.

pub fn IOSurfaceLock(
  buffer: &IOSurfaceRef,
  options: IOSurfaceLockOptions,
  seed: *mut u32,
) -> libc::kern_return_t;

Thanks.

@madsmtm
Copy link
Owner

madsmtm commented Jan 25, 2025

It should be possible, since the Objective-C IOSurface is toll-free bridged to IOSurfaceRef, but it isn't yet, see #693.

@madsmtm
Copy link
Owner

madsmtm commented Jan 25, 2025

For now, you can do something like:

use objc2_core_foundation::CFRetained;
use objc2::rc::Retained;
use objc2_io_surface::{IOSurfaceRef, IOSurface};

let iosurface = IOSurface::new();
let iosurface_ref: CFRetained<IOSurfaceRef> = unsafe { CFRetained::from_raw(NonNull::new(Retained::into_raw(iosurface)).unwrap().cast()) };

@ericssz
Copy link

ericssz commented Jan 26, 2025

Thanks for your reply.

I noticed there are methods (e.g, lockWithOptions_seed) that I can with the IOSurface, but I still require an IOSurfaceRef for the CVPixelBufferCreateWithIOSurface function. For now, I added my own function, until that is implemented.

I would also like to make suggestion for a function similar to NSDictionary's from_slice method, but for creating an IOSurface with properties.

Right now, I have to do the following:

let keys: &[&IOSurfacePropertyKey; 2] = &[
  IOSurfacePropertyKeyWidth,
  IOSurfacePropertyKeyHeight,
  // ...
];

let values: &[&AnyObject; 2] = &[
  &*NSNumber::new_u32(width),
  &*NSNumber::new_u32(height),
  // ...
];

let properties = NSDictionary::from_slices(keys, values);

IOSurface::initWithProperties(IOSurface::alloc(), &*properties).unwrap()

Maybe there could be a method to do the allocation?

@madsmtm
Copy link
Owner

madsmtm commented Jan 26, 2025

Adding more methods to CFDictionary is tracked in #692 (and I agree that it's a glaring omission).

Maybe there could be a method to do the allocation?

I'm not sure what you mean by this?

@ericssz
Copy link

ericssz commented Jan 26, 2025

Adding more methods to CFDictionary is tracked in #692 (and I agree that it's a glaring omission).

Maybe there could be a method to do the allocation?

I'm not sure what you mean by this?

Could there be a method added to IOSurface that takes in properties, allocates an IOSurface, initalizes an IOSurface with the properties, and returns it?

For example:

fn from_properties(
  properties: &NSDictionary<IOSurfacePropertyKey, AnyObject>,
) -> Option<Retained<Self>> {
  unsafe { Self::initWithProperties(Self::alloc(), properties) }
}

@madsmtm
Copy link
Owner

madsmtm commented Jan 26, 2025

Ah, I understand now.

I'm fairly reluctant to add such simple helpers, as it obscures what's actually happening (you now have to look at the method definition to know that it's calling the Objective-C method initWithProperties:).

Instead, I'd rather mark initWithProperties as safe, and then wait for arbitrary self types (which are fairly close to stabilization), then your code would become as simple as:

IOSurface::alloc().initWithProperties(properties)

@ericssz
Copy link

ericssz commented Jan 26, 2025

Ah, I understand now.

I'm fairly reluctant to add such simple helpers, as it obscures what's actually happening (you now have to look at the method definition to know that it's calling the Objective-C method initWithProperties:).

Instead, I'd rather mark initWithProperties as safe, and then wait for arbitrary self types (which are fairly close to stabilization), then your code would become as simple as:

IOSurface::alloc().initWithProperties(properties)

Ok, that seems better. Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-framework Affects the framework crates and the translator for them enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants