core_video/
metal_texture_cache.rs1use std::ptr::{null, null_mut};
2
3use core_foundation::{
4 base::{kCFAllocatorDefault, CFAllocatorRef, CFType, CFTypeID, TCFType},
5 dictionary::{CFDictionary, CFDictionaryRef},
6 string::{CFString, CFStringRef},
7};
8use libc::{c_void, size_t};
9
10use crate::{
11 base::CVOptionFlags,
12 image_buffer::CVImageBufferRef,
13 metal_texture::{CVMetalTexture, CVMetalTextureRef},
14 r#return::{kCVReturnSuccess, CVReturn},
15};
16
17#[repr(C)]
18pub struct __CVMetalTextureCache(c_void);
19
20pub type CVMetalTextureCacheRef = *mut __CVMetalTextureCache;
21
22extern "C" {
23 pub static kCVMetalTextureCacheMaximumTextureAgeKey: CFStringRef;
24
25 pub fn CVMetalTextureCacheGetTypeID() -> CFTypeID;
26 pub fn CVMetalTextureCacheCreate(
27 allocator: CFAllocatorRef,
28 cacheAttributes: CFDictionaryRef,
29 metalDevice: metal::Device,
30 textureAttributes: CFDictionaryRef,
31 cacheOut: *mut CVMetalTextureCacheRef,
32 ) -> CVReturn;
33 pub fn CVMetalTextureCacheCreateTextureFromImage(
34 allocator: CFAllocatorRef,
35 textureCache: CVMetalTextureCacheRef,
36 sourceImage: CVImageBufferRef,
37 textureAttributes: CFDictionaryRef,
38 pixelFormat: metal::MTLPixelFormat,
39 width: size_t,
40 height: size_t,
41 planeIndex: size_t,
42 textureOut: *mut CVMetalTextureRef,
43 ) -> CVReturn;
44 pub fn CVMetalTextureCacheFlush(textureCache: CVMetalTextureCacheRef, options: CVOptionFlags);
45}
46
47pub enum CVMetalTextureCacheKeys {
48 MaximumTextureAge,
49}
50
51impl From<CVMetalTextureCacheKeys> for CFStringRef {
52 fn from(key: CVMetalTextureCacheKeys) -> Self {
53 unsafe {
54 match key {
55 CVMetalTextureCacheKeys::MaximumTextureAge => kCVMetalTextureCacheMaximumTextureAgeKey,
56 }
57 }
58 }
59}
60
61impl From<CVMetalTextureCacheKeys> for CFString {
62 fn from(key: CVMetalTextureCacheKeys) -> Self {
63 unsafe { CFString::wrap_under_get_rule(CFStringRef::from(key)) }
64 }
65}
66
67declare_TCFType! {
68 CVMetalTextureCache, CVMetalTextureCacheRef
69}
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}