core_video/
metal_texture_cache.rs1use std::ptr::{null, null_mut};
2
3use core_foundation::{
4 base::{kCFAllocatorDefault, CFAllocatorRef, CFType, CFTypeID, TCFType},
5 declare_TCFType,
6 dictionary::{CFDictionary, CFDictionaryRef},
7 impl_CFTypeDescription, impl_TCFType,
8 string::{CFString, CFStringRef},
9};
10use libc::{c_void, size_t};
11
12use crate::{
13 base::CVOptionFlags,
14 image_buffer::CVImageBufferRef,
15 metal_texture::{CVMetalTexture, CVMetalTextureRef},
16 r#return::{kCVReturnSuccess, CVReturn},
17};
18
19#[repr(C)]
20pub struct __CVMetalTextureCache(c_void);
21
22pub type CVMetalTextureCacheRef = *mut __CVMetalTextureCache;
23
24extern "C" {
25 pub static kCVMetalTextureCacheMaximumTextureAgeKey: CFStringRef;
26
27 pub fn CVMetalTextureCacheGetTypeID() -> CFTypeID;
28 pub fn CVMetalTextureCacheCreate(
29 allocator: CFAllocatorRef,
30 cacheAttributes: CFDictionaryRef,
31 metalDevice: metal::Device,
32 textureAttributes: CFDictionaryRef,
33 cacheOut: *mut CVMetalTextureCacheRef,
34 ) -> CVReturn;
35 pub fn CVMetalTextureCacheCreateTextureFromImage(
36 allocator: CFAllocatorRef,
37 textureCache: CVMetalTextureCacheRef,
38 sourceImage: CVImageBufferRef,
39 textureAttributes: CFDictionaryRef,
40 pixelFormat: metal::MTLPixelFormat,
41 width: size_t,
42 height: size_t,
43 planeIndex: size_t,
44 textureOut: *mut CVMetalTextureRef,
45 ) -> CVReturn;
46 pub fn CVMetalTextureCacheFlush(textureCache: CVMetalTextureCacheRef, options: CVOptionFlags);
47}
48
49pub enum CVMetalTextureCacheKeys {
50 MaximumTextureAge,
51}
52
53impl From<CVMetalTextureCacheKeys> for CFStringRef {
54 fn from(key: CVMetalTextureCacheKeys) -> Self {
55 unsafe {
56 match key {
57 CVMetalTextureCacheKeys::MaximumTextureAge => kCVMetalTextureCacheMaximumTextureAgeKey,
58 }
59 }
60 }
61}
62
63impl From<CVMetalTextureCacheKeys> for CFString {
64 fn from(key: CVMetalTextureCacheKeys) -> Self {
65 unsafe { CFString::wrap_under_get_rule(CFStringRef::from(key)) }
66 }
67}
68
69declare_TCFType!(CVMetalTextureCache, CVMetalTextureCacheRef);
70impl_TCFType!(CVMetalTextureCache, CVMetalTextureCacheRef, CVMetalTextureCacheGetTypeID);
71impl_CFTypeDescription!(CVMetalTextureCache);
72
73impl CVMetalTextureCache {
74 #[inline]
75 pub fn new(
76 cache_attributes: Option<&CFDictionary<CFString, CFType>>,
77 metal_device: metal::Device,
78 texture_attributes: Option<&CFDictionary<CFString, CFType>>,
79 ) -> Result<CVMetalTextureCache, CVReturn> {
80 let mut cache: CVMetalTextureCacheRef = null_mut();
81 let status = unsafe {
82 CVMetalTextureCacheCreate(
83 kCFAllocatorDefault,
84 cache_attributes.map_or(null(), |attrs| attrs.as_concrete_TypeRef()),
85 metal_device,
86 texture_attributes.map_or(null(), |attrs| attrs.as_concrete_TypeRef()),
87 &mut cache,
88 )
89 };
90 if status == kCVReturnSuccess {
91 Ok(unsafe { TCFType::wrap_under_create_rule(cache) })
92 } else {
93 Err(status)
94 }
95 }
96
97 #[inline]
98 pub fn create_texture_from_image(
99 &self,
100 source_image: CVImageBufferRef,
101 texture_attributes: Option<&CFDictionary<CFString, CFType>>,
102 pixel_format: metal::MTLPixelFormat,
103 width: size_t,
104 height: size_t,
105 plane_index: size_t,
106 ) -> Result<CVMetalTexture, CVReturn> {
107 let mut texture: CVMetalTextureRef = null_mut();
108 let status = unsafe {
109 CVMetalTextureCacheCreateTextureFromImage(
110 kCFAllocatorDefault,
111 self.as_concrete_TypeRef(),
112 source_image,
113 texture_attributes.map_or(null(), |attrs| attrs.as_concrete_TypeRef()),
114 pixel_format,
115 width,
116 height,
117 plane_index,
118 &mut texture,
119 )
120 };
121 if status == kCVReturnSuccess {
122 Ok(unsafe { TCFType::wrap_under_create_rule(texture) })
123 } else {
124 Err(status)
125 }
126 }
127
128 #[inline]
129 pub fn flush(&self, options: CVOptionFlags) {
130 unsafe { CVMetalTextureCacheFlush(self.as_concrete_TypeRef(), options) }
131 }
132}