apple_cf/cv/
metal_texture_cache.rs1#![allow(clippy::missing_panics_doc)]
4
5use crate::cv::CVPixelBuffer;
14use crate::ffi;
15use std::ffi::c_void;
16use std::fmt;
17
18#[link(name = "CoreVideo", kind = "framework")]
19extern "C" {
20 fn CVMetalTextureCacheGetTypeID() -> usize;
21 fn CVMetalTextureGetTypeID() -> usize;
22 fn CVMetalTextureCacheCreate(
23 allocator: *const c_void,
24 cache_attributes: *const c_void,
25 metal_device: *mut c_void,
26 texture_attributes: *const c_void,
27 cache_out: *mut *mut c_void,
28 ) -> i32;
29 fn CVMetalTextureCacheCreateTextureFromImage(
30 allocator: *const c_void,
31 texture_cache: *mut c_void,
32 source_image: *mut c_void,
33 texture_attributes: *const c_void,
34 pixel_format: usize,
35 width: usize,
36 height: usize,
37 plane_index: usize,
38 texture_out: *mut *mut c_void,
39 ) -> i32;
40 fn CVMetalTextureGetTexture(image: *mut c_void) -> *mut c_void;
41}
42
43const CV_RETURN_INVALID_ARGUMENT: i32 = -6661;
44const CV_RETURN_ALLOCATION_FAILED: i32 = -6662;
45
46pub struct CVMetalTextureCache(*mut c_void);
48
49impl CVMetalTextureCache {
50 #[must_use]
52 pub fn system_default() -> Option<Self> {
53 let ptr = unsafe { ffi::cv_metal_texture_cache_create_system_default() };
54 unsafe { Self::from_raw(ptr) }
55 }
56
57 #[must_use]
65 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
66 if ptr.is_null() {
67 None
68 } else {
69 Some(Self(ptr))
70 }
71 }
72
73 #[must_use]
80 pub unsafe fn from_raw_borrowed(ptr: *mut c_void) -> Option<Self> {
81 if ptr.is_null() {
82 None
83 } else {
84 let retained = unsafe { ffi::cf_type_retain(ptr) };
85 unsafe { Self::from_raw(retained) }
86 }
87 }
88
89 #[must_use]
91 pub const fn as_ptr(&self) -> *mut c_void {
92 self.0
93 }
94
95 #[must_use]
97 pub fn type_id() -> usize {
98 unsafe { CVMetalTextureCacheGetTypeID() }
99 }
100
101 pub fn flush(&self) {
103 unsafe { ffi::cv_metal_texture_cache_flush(self.0) };
104 }
105
106 #[allow(clippy::missing_safety_doc, clippy::missing_errors_doc)]
107 pub unsafe fn with_device(device: *mut c_void) -> Result<Self, i32> {
108 if device.is_null() {
109 return Err(CV_RETURN_INVALID_ARGUMENT);
110 }
111 let mut cache = std::ptr::null_mut();
112 let status = unsafe {
113 CVMetalTextureCacheCreate(
114 std::ptr::null(),
115 std::ptr::null(),
116 device,
117 std::ptr::null(),
118 &raw mut cache,
119 )
120 };
121 if status != 0 {
122 return Err(status);
123 }
124 unsafe { Self::from_raw(cache) }.ok_or(CV_RETURN_ALLOCATION_FAILED)
125 }
126
127 #[allow(clippy::missing_errors_doc)]
128 pub fn create_texture_from_image(
129 &self,
130 image: &CVPixelBuffer,
131 pixel_format: usize,
132 width: usize,
133 height: usize,
134 plane_index: usize,
135 ) -> Result<CVMetalTexture, i32> {
136 let mut texture = std::ptr::null_mut();
137 let status = unsafe {
138 CVMetalTextureCacheCreateTextureFromImage(
139 std::ptr::null(),
140 self.0,
141 image.as_ptr(),
142 std::ptr::null(),
143 pixel_format,
144 width,
145 height,
146 plane_index,
147 &raw mut texture,
148 )
149 };
150 if status != 0 {
151 return Err(status);
152 }
153 unsafe { CVMetalTexture::from_raw(texture) }.ok_or(CV_RETURN_ALLOCATION_FAILED)
154 }
155}
156
157pub struct CVMetalTexture(*mut c_void);
158
159unsafe impl Send for CVMetalTexture {}
160unsafe impl Sync for CVMetalTexture {}
161
162impl CVMetalTexture {
163 #[allow(clippy::missing_safety_doc)]
164 #[must_use]
165 pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
166 if ptr.is_null() {
167 None
168 } else {
169 Some(Self(ptr))
170 }
171 }
172
173 #[must_use]
174 pub const fn as_ptr(&self) -> *mut c_void {
175 self.0
176 }
177
178 #[must_use]
179 pub fn type_id() -> usize {
180 unsafe { CVMetalTextureGetTypeID() }
181 }
182
183 #[must_use]
184 pub fn texture(&self) -> *mut c_void {
185 unsafe { CVMetalTextureGetTexture(self.0) }
186 }
187}
188
189crate::utils::retained::cf_retained!(
190 CVMetalTexture,
191 retain = ffi::cf_type_retain,
192 release = ffi::cf_type_release,
193);
194
195impl fmt::Debug for CVMetalTexture {
196 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
197 f.debug_struct("CVMetalTexture")
198 .field("ptr", &self.0)
199 .finish()
200 }
201}
202
203crate::utils::retained::cf_retained!(
204 CVMetalTextureCache,
205 retain = ffi::cf_type_retain,
206 release = ffi::cf_type_release,
207);
208
209impl PartialEq for CVMetalTextureCache {
210 fn eq(&self, other: &Self) -> bool {
211 self.0 == other.0
212 }
213}
214
215impl Eq for CVMetalTextureCache {}
216
217impl std::hash::Hash for CVMetalTextureCache {
218 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
219 unsafe { ffi::cf_type_hash(self.0) }.hash(state);
220 }
221}
222
223impl fmt::Debug for CVMetalTextureCache {
224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225 f.debug_struct("CVMetalTextureCache")
226 .field("ptr", &self.0)
227 .field("type_id", &Self::type_id())
228 .finish()
229 }
230}