Skip to main content

mtl_gpu/
command_buffer_encoder_info.rs

1//! Command buffer encoder info.
2//!
3//! Corresponds to `MTL::CommandBufferEncoderInfo` in `Metal/MTLCommandBuffer.hpp`.
4//!
5//! Provides information about encoders that have been used in a command buffer,
6//! useful for debugging and error handling.
7
8use std::ffi::c_void;
9use std::ptr::NonNull;
10
11use mtl_foundation::Referencing;
12use mtl_sys::{msg_send_0, sel};
13
14use crate::enums::CommandEncoderErrorState;
15
16/// Information about an encoder in a command buffer.
17///
18/// C++ equivalent: `MTL::CommandBufferEncoderInfo`
19///
20/// This type provides debugging information about encoders that have
21/// contributed to a command buffer, including their error state and
22/// debug signposts.
23#[repr(transparent)]
24pub struct CommandBufferEncoderInfo(pub(crate) NonNull<c_void>);
25
26impl CommandBufferEncoderInfo {
27    /// Create from a raw pointer.
28    #[inline]
29    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
30        NonNull::new(ptr).map(Self)
31    }
32
33    /// Get the raw pointer.
34    #[inline]
35    pub fn as_raw(&self) -> *mut c_void {
36        self.0.as_ptr()
37    }
38
39    /// Get the label of the encoder.
40    ///
41    /// C++ equivalent: `NS::String* label() const`
42    pub fn label(&self) -> Option<String> {
43        unsafe {
44            let ptr: *mut c_void = msg_send_0(self.as_ptr(), sel!(label));
45            if ptr.is_null() {
46                return None;
47            }
48            let utf8_ptr: *const std::ffi::c_char =
49                mtl_sys::msg_send_0(ptr as *const c_void, sel!(UTF8String));
50            if utf8_ptr.is_null() {
51                return None;
52            }
53            let c_str = std::ffi::CStr::from_ptr(utf8_ptr);
54            Some(c_str.to_string_lossy().into_owned())
55        }
56    }
57
58    /// Get the error state of the encoder.
59    ///
60    /// C++ equivalent: `CommandEncoderErrorState errorState() const`
61    #[inline]
62    pub fn error_state(&self) -> CommandEncoderErrorState {
63        unsafe { msg_send_0(self.as_ptr(), sel!(errorState)) }
64    }
65
66    /// Get the debug signposts as raw pointer.
67    ///
68    /// Returns a pointer to an NSArray of debug signpost strings.
69    ///
70    /// C++ equivalent: `NS::Array* debugSignposts() const`
71    #[inline]
72    pub fn debug_signposts_ptr(&self) -> *mut c_void {
73        unsafe { msg_send_0(self.as_ptr(), sel!(debugSignposts)) }
74    }
75}
76
77impl Clone for CommandBufferEncoderInfo {
78    fn clone(&self) -> Self {
79        unsafe {
80            msg_send_0::<*mut c_void>(self.as_ptr(), sel!(retain));
81        }
82        Self(self.0)
83    }
84}
85
86impl Drop for CommandBufferEncoderInfo {
87    fn drop(&mut self) {
88        unsafe {
89            msg_send_0::<()>(self.as_ptr(), sel!(release));
90        }
91    }
92}
93
94impl Referencing for CommandBufferEncoderInfo {
95    #[inline]
96    fn as_ptr(&self) -> *const c_void {
97        self.0.as_ptr()
98    }
99}
100
101unsafe impl Send for CommandBufferEncoderInfo {}
102unsafe impl Sync for CommandBufferEncoderInfo {}
103
104impl std::fmt::Debug for CommandBufferEncoderInfo {
105    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106        f.debug_struct("CommandBufferEncoderInfo")
107            .field("label", &self.label())
108            .field("error_state", &self.error_state())
109            .finish()
110    }
111}
112
113#[cfg(test)]
114mod tests {
115    use super::*;
116
117    #[test]
118    fn test_type_size() {
119        assert_eq!(
120            std::mem::size_of::<CommandBufferEncoderInfo>(),
121            std::mem::size_of::<*mut c_void>()
122        );
123    }
124}