unity-native-plugin 0.9.0

Unity Native Plugin API for Rust
Documentation
use objc2::{rc::Retained, runtime::ProtocolObject};
use objc2_foundation::NSBundle;
use objc2_metal::{
    MTLCommandBuffer, MTLCommandEncoder, MTLCommandQueue, MTLDevice, MTLRenderPassDescriptor,
    MTLTexture,
};
use unity_native_plugin_sys::UnityRenderBuffer;

use crate::graphics;
use crate::interface::UnityInterface;

pub trait UnityGraphicsMetalV1Interface {
    fn metal_bundle(&self) -> Option<Retained<NSBundle>>;
    fn metal_device(&self) -> Option<Retained<ProtocolObject<dyn MTLDevice>>>;
    fn current_command_buffer(&self) -> Option<Retained<ProtocolObject<dyn MTLCommandBuffer>>>;
    fn current_command_encoder(&self) -> Option<Retained<ProtocolObject<dyn MTLCommandEncoder>>>;
    fn end_current_command_encoder(&self);
    fn current_render_pass_descriptor(&self) -> Option<Retained<MTLRenderPassDescriptor>>;
    unsafe fn render_buffer_from_handle(
        &self,
        buffer_handle: *mut ::std::os::raw::c_void,
    ) -> graphics::RenderBuffer;
    unsafe fn texture_from_render_buffer(
        &self,
        buffer: UnityRenderBuffer,
    ) -> Option<Retained<ProtocolObject<dyn MTLTexture>>>;
    unsafe fn aa_resolved_texture_from_render_buffer(
        &self,
        buffer: UnityRenderBuffer,
    ) -> Option<Retained<ProtocolObject<dyn MTLTexture>>>;
    unsafe fn stencil_texture_from_render_buffer(
        &self,
        buffer: UnityRenderBuffer,
    ) -> Option<Retained<ProtocolObject<dyn MTLTexture>>>;
}

pub use UnityGraphicsMetalV1Interface as IUnityGraphicsMetalV1;

macro_rules! impl_metal_v1 {
    ($intf:ty) => {
        impl UnityGraphicsMetalV1Interface for $intf {
            fn metal_bundle(&self) -> Option<Retained<NSBundle>> {
                unsafe {
                    Retained::retain(self.interface().MetalBundle.expect("MetalBundle")() as *mut _)
                }
            }

            fn metal_device(&self) -> Option<Retained<ProtocolObject<dyn MTLDevice>>> {
                unsafe {
                    Retained::<ProtocolObject<dyn MTLDevice>>::retain(self
                        .interface()
                        .MetalDevice
                        .expect("MetalDevice")(
                    ) as *mut _)
                }
            }

            fn current_command_buffer(
                &self,
            ) -> Option<Retained<ProtocolObject<dyn MTLCommandBuffer>>> {
                unsafe {
                    Retained::<ProtocolObject<dyn MTLCommandBuffer>>::retain(self
                        .interface()
                        .CurrentCommandBuffer
                        .expect("CurrentCommandBuffer")(
                    )
                        as *mut _)
                }
            }

            fn current_command_encoder(
                &self,
            ) -> Option<Retained<ProtocolObject<dyn MTLCommandEncoder>>> {
                unsafe {
                    Retained::<ProtocolObject<dyn MTLCommandEncoder>>::retain(self
                        .interface()
                        .CurrentCommandEncoder
                        .expect("CurrentCommandEncoder")(
                    )
                        as *mut _)
                }
            }

            fn end_current_command_encoder(&self) {
                unsafe {
                    self.interface()
                        .EndCurrentCommandEncoder
                        .expect("EndCurrentCommandEncoder")()
                }
            }

            fn current_render_pass_descriptor(&self) -> Option<Retained<MTLRenderPassDescriptor>> {
                unsafe {
                    Retained::retain(self
                        .interface()
                        .CurrentRenderPassDescriptor
                        .expect("CurrentRenderPassDescriptor")()
                        as *mut _)
                }
            }

            unsafe fn render_buffer_from_handle(
                &self,
                buffer_handle: *mut ::std::os::raw::c_void,
            ) -> graphics::RenderBuffer {
                unsafe {
                    (self
                        .interface()
                        .RenderBufferFromHandle
                        .expect("RenderBufferFromHandle"))(buffer_handle)
                }
            }

            unsafe fn texture_from_render_buffer(
                &self,
                buffer: graphics::RenderBuffer,
            ) -> Option<Retained<ProtocolObject<dyn MTLTexture>>> {
                unsafe {
                    Retained::<ProtocolObject<dyn MTLTexture>>::retain(self
                        .interface()
                        .TextureFromRenderBuffer
                        .expect("TextureFromRenderBuffer")(
                        buffer
                    ) as *mut _)
                }
            }

            unsafe fn aa_resolved_texture_from_render_buffer(
                &self,
                buffer: graphics::RenderBuffer,
            ) -> Option<Retained<ProtocolObject<dyn MTLTexture>>> {
                unsafe {
                    Retained::<ProtocolObject<dyn MTLTexture>>::retain(self
                        .interface()
                        .AAResolvedTextureFromRenderBuffer
                        .expect("AAResolvedTextureFromRenderBuffer")(
                        buffer
                    ) as *mut _)
                }
            }

            unsafe fn stencil_texture_from_render_buffer(
                &self,
                buffer: graphics::RenderBuffer,
            ) -> Option<Retained<ProtocolObject<dyn MTLTexture>>> {
                unsafe {
                    Retained::<ProtocolObject<dyn MTLTexture>>::retain(self
                        .interface()
                        .StencilTextureFromRenderBuffer
                        .expect("StencilTextureFromRenderBuffer")(
                        buffer
                    ) as *mut _)
                }
            }
        }
    };
}

impl_metal_v1!(UnityGraphicsMetalV1);

define_unity_interface!(
    UnityGraphicsMetalV1,
    unity_native_plugin_sys::IUnityGraphicsMetalV1,
    0x29F8F3D03833465E_u64,
    0x92138551C15D823D_u64
);

pub trait UnityGraphicsMetalV2Interface: UnityGraphicsMetalV1Interface {
    fn commit_current_command_buffer(
        &self,
    ) -> Option<Retained<ProtocolObject<dyn MTLCommandBuffer>>>;
    fn command_queue(&self) -> Option<Retained<ProtocolObject<dyn MTLCommandQueue>>>;
}

pub use UnityGraphicsMetalV2Interface as IUnityGraphicsMetalV2;

macro_rules! impl_metal_v2 {
    ($intf:ty) => {
        impl_metal_v1!($intf);

        impl UnityGraphicsMetalV2Interface for $intf {
            fn commit_current_command_buffer(
                &self,
            ) -> Option<Retained<ProtocolObject<dyn MTLCommandBuffer>>> {
                unsafe {
                    Retained::<ProtocolObject<dyn MTLCommandBuffer>>::retain(self
                        .interface()
                        .CommitCurrentCommandBuffer
                        .expect("CommitCurrentCommandBuffer")(
                    )
                        as *mut _)
                }
            }

            fn command_queue(&self) -> Option<Retained<ProtocolObject<dyn MTLCommandQueue>>> {
                unsafe {
                    Retained::<ProtocolObject<dyn MTLCommandQueue>>::retain(self
                        .interface()
                        .CommandQueue
                        .expect("CommandQueue")(
                    ) as *mut _)
                }
            }
        }
    };
}
impl_metal_v2!(UnityGraphicsMetalV2);

define_unity_interface!(
    UnityGraphicsMetalV2,
    unity_native_plugin_sys::IUnityGraphicsMetalV2,
    0xF58857784FEF46EC_u64,
    0x9DB7A8803B87DA3D_u64
);