Skip to main content

apple_cf/cv/
metal_texture_cache.rs

1//! `CVMetalTextureCache` wrapper.
2//!
3#![allow(clippy::missing_panics_doc)]
4
5//! ```rust,no_run
6//! use apple_cf::cv::CVMetalTextureCache;
7//!
8//! if let Some(cache) = CVMetalTextureCache::system_default() {
9//!     cache.flush();
10//! }
11//! ```
12
13use crate::ffi;
14use std::ffi::c_void;
15use std::fmt;
16
17#[link(name = "CoreVideo", kind = "framework")]
18extern "C" {
19    fn CVMetalTextureCacheGetTypeID() -> usize;
20}
21
22/// Owned wrapper around `CVMetalTextureCacheRef`.
23pub struct CVMetalTextureCache(*mut c_void);
24
25impl CVMetalTextureCache {
26    /// Create a texture cache using the system-default Metal device.
27    #[must_use]
28    pub fn system_default() -> Option<Self> {
29        let ptr = unsafe { ffi::cv_metal_texture_cache_create_system_default() };
30        unsafe { Self::from_raw(ptr) }
31    }
32
33    /// Adopts a +1 retained `CVMetalTextureCacheRef` and returns `None` for null.
34    ///
35    /// # Safety
36    ///
37    /// A non-null `ptr` must be a live `CVMetalTextureCacheRef` of the exact
38    /// type carrying one retain transferred to this wrapper. The caller must
39    /// not release or separately adopt that transferred retain.
40    #[must_use]
41    pub unsafe fn from_raw(ptr: *mut c_void) -> Option<Self> {
42        if ptr.is_null() {
43            None
44        } else {
45            Some(Self(ptr))
46        }
47    }
48
49    /// Retains a +0 borrowed cache pointer and returns an owned wrapper.
50    ///
51    /// # Safety
52    ///
53    /// A non-null `ptr` must be a live `CVMetalTextureCacheRef` of the exact
54    /// type for the duration of the retain call.
55    #[must_use]
56    pub unsafe fn from_raw_borrowed(ptr: *mut c_void) -> Option<Self> {
57        if ptr.is_null() {
58            None
59        } else {
60            let retained = unsafe { ffi::cf_type_retain(ptr) };
61            unsafe { Self::from_raw(retained) }
62        }
63    }
64
65    /// Borrow the raw +0 cache pointer while `self` remains alive.
66    #[must_use]
67    pub const fn as_ptr(&self) -> *mut c_void {
68        self.0
69    }
70
71    /// Core Video type identifier.
72    #[must_use]
73    pub fn type_id() -> usize {
74        unsafe { CVMetalTextureCacheGetTypeID() }
75    }
76
77    /// Flush pending cached textures.
78    pub fn flush(&self) {
79        unsafe { ffi::cv_metal_texture_cache_flush(self.0) };
80    }
81}
82
83crate::utils::retained::cf_retained!(
84    CVMetalTextureCache,
85    retain = ffi::cf_type_retain,
86    release = ffi::cf_type_release,
87);
88
89impl PartialEq for CVMetalTextureCache {
90    fn eq(&self, other: &Self) -> bool {
91        self.0 == other.0
92    }
93}
94
95impl Eq for CVMetalTextureCache {}
96
97impl std::hash::Hash for CVMetalTextureCache {
98    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
99        unsafe { ffi::cf_type_hash(self.0) }.hash(state);
100    }
101}
102
103impl fmt::Debug for CVMetalTextureCache {
104    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105        f.debug_struct("CVMetalTextureCache")
106            .field("ptr", &self.0)
107            .field("type_id", &Self::type_id())
108            .finish()
109    }
110}