//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::cell::UnsafeCell;
use core::ffi::*;
use core::marker::{PhantomData, PhantomPinned};
use core::ptr::NonNull;
#[cfg(feature = "objc2")]
use objc2::__framework_prelude::*;
use objc2_core_foundation::*;
#[cfg(feature = "objc2-metal")]
#[cfg(not(target_os = "watchos"))]
use objc2_metal::*;

use crate::*;

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/corevideo/kcvmetaltexturecachemaximumtextureagekey?language=objc)
    pub static kCVMetalTextureCacheMaximumTextureAgeKey: &'static CFString;
}

/// CoreVideo Metal Texture Cache
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corevideo/cvmetaltexturecache?language=objc)
#[doc(alias = "CVMetalTextureCacheRef")]
#[repr(C)]
pub struct CVMetalTextureCache {
    inner: [u8; 0],
    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
}

cf_type!(
    unsafe impl CVMetalTextureCache {}
);
#[cfg(feature = "objc2")]
cf_objc2_type!(
    unsafe impl RefEncode<"__CVMetalTextureCache"> for CVMetalTextureCache {}
);

unsafe impl ConcreteType for CVMetalTextureCache {
    #[doc(alias = "CVMetalTextureCacheGetTypeID")]
    #[inline]
    fn type_id() -> CFTypeID {
        extern "C-unwind" {
            fn CVMetalTextureCacheGetTypeID() -> CFTypeID;
        }
        unsafe { CVMetalTextureCacheGetTypeID() }
    }
}

impl CVMetalTextureCache {
    /// Creates a new Texture Cache.
    ///
    /// Parameter `allocator`: The CFAllocatorRef to use for allocating the cache.  May be NULL.
    ///
    /// Parameter `cacheAttributes`: A CFDictionaryRef containing the attributes of the cache itself.   May be NULL.
    ///
    /// Parameter `metalDevice`: The Metal device for which the texture objects will be created.
    ///
    /// Parameter `textureAttributes`: A CFDictionaryRef containing the attributes to be used for creating the CVMetalTexture objects.  May be NULL.
    ///
    /// Parameter `cacheOut`: The newly created texture cache will be placed here
    ///
    /// Returns: Returns kCVReturnSuccess on success
    ///
    /// # Safety
    ///
    /// - `cache_attributes` generics must be of the correct type.
    /// - `texture_attributes` generics must be of the correct type.
    /// - `cache_out` must be a valid pointer.
    #[doc(alias = "CVMetalTextureCacheCreate")]
    #[cfg(all(feature = "CVReturn", feature = "objc2", feature = "objc2-metal"))]
    #[cfg(not(target_os = "watchos"))]
    #[inline]
    pub unsafe fn create(
        allocator: Option<&CFAllocator>,
        cache_attributes: Option<&CFDictionary>,
        metal_device: &ProtocolObject<dyn MTLDevice>,
        texture_attributes: Option<&CFDictionary>,
        cache_out: NonNull<*mut CVMetalTextureCache>,
    ) -> CVReturn {
        extern "C-unwind" {
            fn CVMetalTextureCacheCreate(
                allocator: Option<&CFAllocator>,
                cache_attributes: Option<&CFDictionary>,
                metal_device: &ProtocolObject<dyn MTLDevice>,
                texture_attributes: Option<&CFDictionary>,
                cache_out: NonNull<*mut CVMetalTextureCache>,
            ) -> CVReturn;
        }
        unsafe {
            CVMetalTextureCacheCreate(
                allocator,
                cache_attributes,
                metal_device,
                texture_attributes,
                cache_out,
            )
        }
    }

    /// Creates a CVMetalTexture object from an existing CVImageBuffer
    ///
    /// Parameter `allocator`: The CFAllocatorRef to use for allocating the CVMetalTexture object.  May be NULL.
    ///
    /// Parameter `textureCache`: The texture cache object that will manage the texture.
    ///
    /// Parameter `sourceImage`: The CVImageBuffer that you want to create a CVMetalTexture from.
    ///
    /// Parameter `textureAttributes`: A CFDictionaryRef containing attributes to be used for creating the CVMetalTexture objects.  May be NULL.
    ///
    /// Parameter `pixelFormat`: Specifies the Metal pixel format.
    ///
    /// Parameter `width`: Specifies the width of the texture image.
    ///
    /// Parameter `height`: Specifies the height of the texture image.
    ///
    /// Parameter `planeIndex`: Specifies the plane of the CVImageBuffer to map bind.  Ignored for non-planar CVImageBuffers.
    ///
    /// Parameter `textureOut`: The newly created texture object will be placed here.
    ///
    /// Returns: Returns kCVReturnSuccess on success
    ///
    /// Creates or returns a cached CVMetalTexture texture object mapped to the CVImageBuffer and
    /// associated params.  This creates a live binding between the CVImageBuffer and underlying
    /// CVMetalTexture texture object.
    ///
    /// IMPORTANT NOTE: Clients should retain CVMetalTexture objects until they are done using the images in them.
    /// Retaining a CVMetalTexture is your way to indicate that you're still using the image in the buffer, and that it should not be recycled yet.
    ///
    /// Note that CoreVideo does not explicitly declare any pixel format types to be Metal compatible.  The assumption
    /// is that if the CVPixelBufferMetalCompatibilityKey has been specified, all buffers will be Metal compatible
    /// (IOSurface backed), and thus it is the developer's responsibility to choose an appropriate Metal pixel format
    /// for the CVPixelBuffers.
    ///
    /// Here are some example mappings:
    ///
    /// Mapping a BGRA buffer:
    /// CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, pixelBuffer, NULL, MTLPixelFormatBGRA8Unorm, width, height, 0,
    /// &outTexture
    /// );
    ///
    /// Mapping the luma plane of a 420v buffer:
    /// CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, pixelBuffer, NULL, MTLPixelFormatR8Unorm, width, height, 0,
    /// &outTexture
    /// );
    ///
    /// Mapping the chroma plane of a 420v buffer as a source texture:
    /// CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, pixelBuffer, NULL, MTLPixelFormatRG8Unorm width/2, height/2, 1,
    /// &outTexture
    /// );
    ///
    /// Mapping a yuvs buffer as a source texture (note: yuvs/f and 2vuy are unpacked and resampled -- not colorspace converted)
    /// CVMetalTextureCacheCreateTextureFromImage(kCFAllocatorDefault, textureCache, pixelBuffer, NULL, MTLPixelFormatGBGR422, width, height, 1,
    /// &outTexture
    /// );
    ///
    /// # Safety
    ///
    /// - `texture_attributes` generics must be of the correct type.
    /// - `texture_out` must be a valid pointer.
    #[doc(alias = "CVMetalTextureCacheCreateTextureFromImage")]
    #[cfg(all(
        feature = "CVBuffer",
        feature = "CVImageBuffer",
        feature = "CVMetalTexture",
        feature = "CVReturn",
        feature = "objc2-metal"
    ))]
    #[cfg(not(target_os = "watchos"))]
    #[inline]
    pub unsafe fn create_texture_from_image(
        allocator: Option<&CFAllocator>,
        texture_cache: &CVMetalTextureCache,
        source_image: &CVImageBuffer,
        texture_attributes: Option<&CFDictionary>,
        pixel_format: MTLPixelFormat,
        width: usize,
        height: usize,
        plane_index: usize,
        texture_out: NonNull<*mut CVMetalTexture>,
    ) -> CVReturn {
        extern "C-unwind" {
            fn CVMetalTextureCacheCreateTextureFromImage(
                allocator: Option<&CFAllocator>,
                texture_cache: &CVMetalTextureCache,
                source_image: &CVImageBuffer,
                texture_attributes: Option<&CFDictionary>,
                pixel_format: MTLPixelFormat,
                width: usize,
                height: usize,
                plane_index: usize,
                texture_out: NonNull<*mut CVMetalTexture>,
            ) -> CVReturn;
        }
        unsafe {
            CVMetalTextureCacheCreateTextureFromImage(
                allocator,
                texture_cache,
                source_image,
                texture_attributes,
                pixel_format,
                width,
                height,
                plane_index,
                texture_out,
            )
        }
    }

    /// Performs internal housekeeping/recycling operations
    ///
    /// This call must be made periodically to give the texture cache a chance to do internal housekeeping operations.
    ///
    /// Parameter `textureCache`: The texture cache object to flush
    ///
    /// Parameter `options`: Currently unused, set to 0.
    #[doc(alias = "CVMetalTextureCacheFlush")]
    #[cfg(feature = "CVBase")]
    #[inline]
    pub fn flush(&self, options: CVOptionFlags) {
        extern "C-unwind" {
            fn CVMetalTextureCacheFlush(
                texture_cache: &CVMetalTextureCache,
                options: CVOptionFlags,
            );
        }
        unsafe { CVMetalTextureCacheFlush(self, options) }
    }
}

extern "C-unwind" {
    #[cfg(all(feature = "CVReturn", feature = "objc2", feature = "objc2-metal"))]
    #[cfg(not(target_os = "watchos"))]
    #[deprecated = "renamed to `CVMetalTextureCache::create`"]
    pub fn CVMetalTextureCacheCreate(
        allocator: Option<&CFAllocator>,
        cache_attributes: Option<&CFDictionary>,
        metal_device: &ProtocolObject<dyn MTLDevice>,
        texture_attributes: Option<&CFDictionary>,
        cache_out: NonNull<*mut CVMetalTextureCache>,
    ) -> CVReturn;
}

extern "C-unwind" {
    #[cfg(all(
        feature = "CVBuffer",
        feature = "CVImageBuffer",
        feature = "CVMetalTexture",
        feature = "CVReturn",
        feature = "objc2-metal"
    ))]
    #[cfg(not(target_os = "watchos"))]
    #[deprecated = "renamed to `CVMetalTextureCache::create_texture_from_image`"]
    pub fn CVMetalTextureCacheCreateTextureFromImage(
        allocator: Option<&CFAllocator>,
        texture_cache: &CVMetalTextureCache,
        source_image: &CVImageBuffer,
        texture_attributes: Option<&CFDictionary>,
        pixel_format: MTLPixelFormat,
        width: usize,
        height: usize,
        plane_index: usize,
        texture_out: NonNull<*mut CVMetalTexture>,
    ) -> CVReturn;
}

#[cfg(feature = "CVBase")]
#[deprecated = "renamed to `CVMetalTextureCache::flush`"]
#[inline]
pub extern "C-unwind" fn CVMetalTextureCacheFlush(
    texture_cache: &CVMetalTextureCache,
    options: CVOptionFlags,
) {
    extern "C-unwind" {
        fn CVMetalTextureCacheFlush(texture_cache: &CVMetalTextureCache, options: CVOptionFlags);
    }
    unsafe { CVMetalTextureCacheFlush(texture_cache, options) }
}
