objc2-metal-performance-shaders 0.3.2

Bindings to the MetalPerformanceShaders framework
Documentation
//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
use objc2_foundation::*;
use objc2_metal::*;

use crate::*;

extern_class!(
    /// The MPSImageEDLInes class implements the EDLines line segmenting algorithm using edge-drawing (ED)
    /// described here
    /// https://ieeexplore.ieee.org/document/6116138
    ///
    /// The EDLInes algorithm consists of 5 steps, the first 4 of which describe the ED algorithm:
    /// 1. Blur the source image using a Gaussian blur with a sigma parameter
    /// 2. Use horizontal and vertical Sobel filters to find a gradient magnitude and
    /// direction.
    /// G = sqrt(Sx^2 + Sy^2)
    /// G_ang = arctan(Sy / Sx)
    /// 3. Compute anchor points, points with a high probability of being edge pixels.
    /// Anchor points are local maxima, in the gradient image that lie on row and column
    /// multiples of the detailRatio. This parameter effectively downsamples the gradient
    /// image, and directly influences the density of anchor points. A larger detailRatio results
    /// in fewer fine grained details, leaving long, main lines.
    /// 4. Anchor points are traced in a forward and backward direction along the gradient direction, until
    /// the gradient falls below some gradientThreshold parameter or the edge of the image is reached.
    /// The paths traced become an edge map of the image.
    /// 5. Points in the edges are fit to a line), and extended along the edge until the line error crosses a
    /// lineErrorThreshold. Lines which are beyond a minimum length are labelled line segments and
    /// will be outputs of the algorithm.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpsimageedlines?language=objc)
    #[unsafe(super(MPSKernel, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
    pub struct MPSImageEDLines;
);

#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
extern_conformance!(
    unsafe impl NSCoding for MPSImageEDLines {}
);

#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
extern_conformance!(
    unsafe impl NSCopying for MPSImageEDLines {}
);

#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
unsafe impl CopyingHelper for MPSImageEDLines {
    type Result = Self;
}

#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
extern_conformance!(
    unsafe impl NSObjectProtocol for MPSImageEDLines {}
);

#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
extern_conformance!(
    unsafe impl NSSecureCoding for MPSImageEDLines {}
);

#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
impl MPSImageEDLines {
    extern_methods!(
        /// Initialize an EDLines kernel on a given device with specified parameters.
        ///
        /// Parameter `device`: The device the filter will run on
        ///
        /// Parameter `gaussianSigma`: The standard deviation of gaussian blur filter.
        /// Gaussian weight, centered at 0, at integer grid i is given as
        ///
        /// ```text
        ///                           w(i) = 1/sqrt(2*pi*sigma) * exp(-i^2/(2*sigma^2))
        /// ```
        ///
        /// If we take cut off at 1% of w(0) (max weight) beyond which weights
        /// are considered 0, we have
        ///
        /// ```text
        ///                           ceil (sqrt(-log(0.01)*2)*sigma) ~ ceil(3.7*sigma)
        /// ```
        ///
        /// as rough estimate of filter width
        ///
        /// Parameter `minLineLength`: The minimum length of output line segments.
        ///
        /// Parameter `maxLines`: The maximum amount of lines for the EDLines algorithm to output. The size of the
        /// endpointBuffer supplied at encode must be >= maxLines * 4 * sizeof(unsigned short) + sizeof(uint32_t).
        ///
        /// Parameter `detailRatio`: The detailRatio to use in the EDLines algorithm, which
        /// inversely effects the number of anchor points
        ///
        /// Parameter `gradientThreshold`: Any pixel with a gradient below the gradientThreshold will
        /// not be considerd an edge
        ///
        /// Parameter `lineErrorThreshold`: The limit of how much error a line segment can have relative
        /// to the edge it represents
        ///
        /// Parameter `mergeLocalityThreshold`: Determines how many pixels apart two lines can deviate spatially and still be merged.
        /// This value is normalized to the diagonal length of the image.
        ///
        /// Returns: A valid object or nil, if failure.
        #[unsafe(method(initWithDevice:gaussianSigma:minLineLength:maxLines:detailRatio:gradientThreshold:lineErrorThreshold:mergeLocalityThreshold:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithDevice_gaussianSigma_minLineLength_maxLines_detailRatio_gradientThreshold_lineErrorThreshold_mergeLocalityThreshold(
            this: Allocated<Self>,
            device: &ProtocolObject<dyn MTLDevice>,
            gaussian_sigma: c_float,
            min_line_length: c_ushort,
            max_lines: NSUInteger,
            detail_ratio: c_ushort,
            gradient_threshold: c_float,
            line_error_threshold: c_float,
            merge_locality_threshold: c_float,
        ) -> Retained<Self>;

        /// NSSecureCoding compatability
        ///
        /// While the standard NSSecureCoding/NSCoding method
        /// -initWithCoder: should work, since the file can't
        /// know which device your data is allocated on, we
        /// have to guess and may guess incorrectly.  To avoid
        /// that problem, use initWithCoder:device instead.
        ///
        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
        ///
        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
        ///
        /// Returns: A new MPSKernel object, or nil if failure.
        ///
        /// # Safety
        ///
        /// `a_decoder` possibly has further requirements.
        #[unsafe(method(initWithCoder:device:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithCoder_device(
            this: Allocated<Self>,
            a_decoder: &NSCoder,
            device: &ProtocolObject<dyn MTLDevice>,
        ) -> Option<Retained<Self>>;

        /// Encode the filter to a command buffer using a MTLComputeCommandEncoder.
        ///
        /// The filter will not begin to execute until after the command
        /// buffer has been enqueued and committed.
        ///
        ///
        /// Parameter `commandBuffer`: A valid MTLCommandBuffer.
        ///
        /// Parameter `source`: A valid MTLTexture containing the source image for the filter
        ///
        /// Parameter `dest`: A valid MTLTexture containing the destination image for the filter. If not nil, the output will be the edges
        /// found through the Edge Drawing algorithm.
        ///
        /// Parameter `endpointBuffer`: A valid MTLBuffer to receive the line segment count and endpoint results.
        ///
        /// Parameter `endpointOffset`: Byte offset into endpoint buffer at which to write the  line segment endpoint results. Must be a multiple of 32 bytes.
        /// The total line segment count and the line segment endpoints are written to the endpoint buffer. The count
        /// is written as a uint32_t at the start of the buffer. The line segments are written to the endpoint buffer as
        /// start and end pixel coordinates of the segment. Coordinates are stored as unsigned short pairs, and a
        /// single line segment will consist of two pairs, or four total unsigned shorts. The endpoint buffer size must
        /// be >= 4 * maxLines * sizeof(unsigned short) + sizeof(uint32_t).
        ///
        /// # Safety
        ///
        /// - `source` may need to be synchronized.
        /// - `source` may be unretained, you must ensure it is kept alive while in use.
        /// - `dest` may need to be synchronized.
        /// - `dest` may be unretained, you must ensure it is kept alive while in use.
        /// - `endpoint_buffer` may need to be synchronized.
        /// - `endpoint_buffer` may be unretained, you must ensure it is kept alive while in use.
        /// - `endpoint_buffer` contents should be of the correct type.
        #[unsafe(method(encodeToCommandBuffer:sourceTexture:destinationTexture:endpointBuffer:endpointOffset:))]
        #[unsafe(method_family = none)]
        pub unsafe fn encodeToCommandBuffer_sourceTexture_destinationTexture_endpointBuffer_endpointOffset(
            &self,
            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
            source: &ProtocolObject<dyn MTLTexture>,
            dest: Option<&ProtocolObject<dyn MTLTexture>>,
            endpoint_buffer: &ProtocolObject<dyn MTLBuffer>,
            endpoint_offset: NSUInteger,
        );

        /// The source rectangle to use when reading data.
        ///
        /// A MTLRegion that indicates which part of the source to read. If the clipRectSource does not lie
        /// completely within the source image, the intersection of the image bounds and clipRectSource will
        /// be used. The clipRectSource replaces the MPSUnaryImageKernel offset parameter for this filter.
        /// The latter is ignored.   Default: MPSRectNoClip, use the entire source texture.
        #[unsafe(method(clipRectSource))]
        #[unsafe(method_family = none)]
        pub unsafe fn clipRectSource(&self) -> MTLRegion;

        /// Setter for [`clipRectSource`][Self::clipRectSource].
        #[unsafe(method(setClipRectSource:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setClipRectSource(&self, clip_rect_source: MTLRegion);

        /// Read-only sigma value used in performing Gaussian blur of the image.
        /// Default is 2.0
        #[unsafe(method(gaussianSigma))]
        #[unsafe(method_family = none)]
        pub unsafe fn gaussianSigma(&self) -> c_float;

        /// Read-write value used to set the minimum length of a line segment.
        /// Default is 32
        #[unsafe(method(minLineLength))]
        #[unsafe(method_family = none)]
        pub unsafe fn minLineLength(&self) -> c_ushort;

        /// Setter for [`minLineLength`][Self::minLineLength].
        #[unsafe(method(setMinLineLength:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMinLineLength(&self, min_line_length: c_ushort);

        /// Read-write value used to set the max number of line segments to be written out.
        /// The endpointBuffer at encode must be >= maxLines * 4 * sizeof(unsigned short) + sizeof(uint32_t).
        /// Default is 256
        #[unsafe(method(maxLines))]
        #[unsafe(method_family = none)]
        pub unsafe fn maxLines(&self) -> NSUInteger;

        /// Setter for [`maxLines`][Self::maxLines].
        #[unsafe(method(setMaxLines:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMaxLines(&self, max_lines: NSUInteger);

        /// Read-write value used to set the detailRatio to use in the EDLines algorithm
        /// Default is 32
        #[unsafe(method(detailRatio))]
        #[unsafe(method_family = none)]
        pub unsafe fn detailRatio(&self) -> c_ushort;

        /// Setter for [`detailRatio`][Self::detailRatio].
        #[unsafe(method(setDetailRatio:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setDetailRatio(&self, detail_ratio: c_ushort);

        /// Read-write value used to set the threshold for a pixel to be considered an edge
        /// Default is 0.2
        #[unsafe(method(gradientThreshold))]
        #[unsafe(method_family = none)]
        pub unsafe fn gradientThreshold(&self) -> c_float;

        /// Setter for [`gradientThreshold`][Self::gradientThreshold].
        #[unsafe(method(setGradientThreshold:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setGradientThreshold(&self, gradient_threshold: c_float);

        /// Read-write value used to set the limit on error for a line segment relative to the edge it fits
        /// Default is 0.05
        #[unsafe(method(lineErrorThreshold))]
        #[unsafe(method_family = none)]
        pub unsafe fn lineErrorThreshold(&self) -> c_float;

        /// Setter for [`lineErrorThreshold`][Self::lineErrorThreshold].
        #[unsafe(method(setLineErrorThreshold:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setLineErrorThreshold(&self, line_error_threshold: c_float);

        /// Read-write value used to set how many pixels apart two lines can deviate spatially and still be merged.
        /// Default is 0.0025
        #[unsafe(method(mergeLocalityThreshold))]
        #[unsafe(method_family = none)]
        pub unsafe fn mergeLocalityThreshold(&self) -> c_float;

        /// Setter for [`mergeLocalityThreshold`][Self::mergeLocalityThreshold].
        #[unsafe(method(setMergeLocalityThreshold:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMergeLocalityThreshold(&self, merge_locality_threshold: c_float);
    );
}

/// Methods declared on superclass `MPSKernel`.
#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
impl MPSImageEDLines {
    extern_methods!(
        /// Standard init with default properties per filter type
        ///
        /// Parameter `device`: The device that the filter will be used on. May not be NULL.
        ///
        /// Returns: a pointer to the newly initialized object. This will fail, returning
        /// nil if the device is not supported. Devices must be
        /// MTLFeatureSet_iOS_GPUFamily2_v1 or later.
        #[unsafe(method(initWithDevice:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithDevice(
            this: Allocated<Self>,
            device: &ProtocolObject<dyn MTLDevice>,
        ) -> Retained<Self>;

        /// Called by NSCoder to decode MPSKernels
        ///
        /// This isn't the right interface to decode a MPSKernel, but
        /// it is the one that NSCoder uses. To enable your NSCoder
        /// (e.g. NSKeyedUnarchiver) to set which device to use
        /// extend the object to adopt the MPSDeviceProvider
        /// protocol. Otherwise, the Metal system default device
        /// will be used.
        ///
        /// # Safety
        ///
        /// `a_decoder` possibly has further requirements.
        #[unsafe(method(initWithCoder:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithCoder(
            this: Allocated<Self>,
            a_decoder: &NSCoder,
        ) -> Option<Retained<Self>>;
    );
}

/// Methods declared on superclass `NSObject`.
#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
impl MPSImageEDLines {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}