use objc2::rc::Retained;
use objc2::runtime::ProtocolObject;
use objc2_metal::MTLTexture;
#[cfg(any(feature = "wgpu-29", feature = "wgpu-30"))]
use objc2_metal::MTLTextureType;
#[cfg(all(
feature = "wgpu-28",
not(feature = "wgpu-29"),
not(feature = "wgpu-30")
))]
use foreign_types_shared::ForeignType;
use crate::{HostWgpuContext, InteropBackend, InteropError, MetalTextureRef};
pub unsafe fn import_metal_texture_borrowed(
raw_metal_texture: *mut std::ffi::c_void,
metadata: crate::FrameMetadata,
host: &HostWgpuContext,
) -> Result<wgpu::Texture, InteropError> {
let texture =
unsafe { Retained::retain(raw_metal_texture.cast::<ProtocolObject<dyn MTLTexture>>()) }
.ok_or_else(|| InteropError::InvalidFrame("raw_metal_texture is null"))?;
import_metal_texture_ref(MetalTextureRef::new(metadata, texture), host)
}
pub fn import_metal_texture_ref(
frame: MetalTextureRef,
host: &HostWgpuContext,
) -> Result<wgpu::Texture, InteropError> {
if host.backend != InteropBackend::Metal {
return Err(InteropError::BackendMismatch {
expected: "Metal",
actual: "non-Metal",
});
}
let metadata = frame.metadata();
let texture = unsafe {
let retained = frame.raw_metal_texture;
#[cfg(all(
feature = "wgpu-28",
not(feature = "wgpu-29"),
not(feature = "wgpu-30")
))]
let metal_texture = metal::Texture::from_ptr(Retained::into_raw(retained).cast());
#[cfg(any(feature = "wgpu-29", feature = "wgpu-30"))]
let metal_texture = retained;
let copy_size = wgpu::hal::CopyExtent {
width: metadata.size.width,
height: metadata.size.height,
depth: 1,
};
#[cfg(feature = "wgpu-30")]
let hal_texture = wgpu::hal::metal::Device::texture_from_raw(
metal_texture,
metadata.format,
MTLTextureType::Type2D,
1, 1, copy_size,
None, );
#[cfg(all(feature = "wgpu-29", not(feature = "wgpu-30")))]
let hal_texture = wgpu::hal::metal::Device::texture_from_raw(
metal_texture,
metadata.format,
MTLTextureType::Type2D,
1, 1, copy_size,
);
#[cfg(all(
feature = "wgpu-28",
not(feature = "wgpu-29"),
not(feature = "wgpu-30")
))]
let hal_texture = wgpu::hal::metal::Device::texture_from_raw(
metal_texture,
metadata.format,
metal::MTLTextureType::D2,
1, 1, copy_size,
);
crate::wgpu_compat::create_texture_from_hal::<wgpu_hal::api::Metal>(
&host.device,
hal_texture,
&wgpu::TextureDescriptor {
label: Some("metal-texture-ref-import"),
size: wgpu::Extent3d {
width: metadata.size.width,
height: metadata.size.height,
depth_or_array_layers: 1,
},
format: metadata.format,
dimension: wgpu::TextureDimension::D2,
mip_level_count: 1,
sample_count: 1,
usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_SRC,
view_formats: &[],
},
wgpu::TextureUses::RESOURCE,
)
};
Ok(texture)
}