core_video/
opengl_texture_cache.rs1use std::ptr::{null, null_mut};
2
3use core_foundation::{
4 base::{kCFAllocatorDefault, CFAllocatorRef, CFType, CFTypeID, TCFType},
5 dictionary::{CFDictionary, CFDictionaryRef},
6 impl_CFTypeDescription, impl_TCFType,
7 string::{CFString, CFStringRef},
8};
9use libc::c_void;
10
11use crate::{
12 base::CVOptionFlags,
13 image_buffer::{CVImageBuffer, CVImageBufferRef},
14 opengl_texture::{CVOpenGLTexture, CVOpenGLTextureRef},
15 r#return::{kCVReturnSuccess, CVReturn},
16 CGLContextObj, CGLPixelFormatObj,
17};
18
19#[repr(C)]
20pub struct __CVOpenGLTextureCache(c_void);
21
22pub type CVOpenGLTextureCacheRef = *mut __CVOpenGLTextureCache;
23
24extern "C" {
25 pub static kCVOpenGLTextureCacheChromaSamplingModeKey: CFStringRef;
26 pub static kCVOpenGLTextureCacheChromaSamplingModeAutomatic: CFStringRef;
27 pub static kCVOpenGLTextureCacheChromaSamplingModeHighestQuality: CFStringRef;
28 pub static kCVOpenGLTextureCacheChromaSamplingModeBestPerformance: CFStringRef;
29
30 pub fn CVOpenGLTextureCacheGetTypeID() -> CFTypeID;
31 pub fn CVOpenGLTextureCacheRetain(textureCache: CVOpenGLTextureCacheRef) -> CVOpenGLTextureCacheRef;
32 pub fn CVOpenGLTextureCacheRelease(textureCache: CVOpenGLTextureCacheRef);
33 pub fn CVOpenGLTextureCacheCreate(
34 allocator: CFAllocatorRef,
35 cacheAttributes: CFDictionaryRef,
36 cglContext: CGLContextObj,
37 cglPixelFormat: CGLPixelFormatObj,
38 textureAttributes: CFDictionaryRef,
39 cacheOut: *mut CVOpenGLTextureCacheRef,
40 ) -> CVReturn;
41 pub fn CVOpenGLTextureCacheCreateTextureFromImage(
42 allocator: CFAllocatorRef,
43 textureCache: CVOpenGLTextureCacheRef,
44 sourceImage: CVImageBufferRef,
45 attributes: CFDictionaryRef,
46 textureOut: *mut CVOpenGLTextureRef,
47 ) -> CVReturn;
48 pub fn CVOpenGLTextureCacheFlush(textureCache: CVOpenGLTextureCacheRef, options: CVOptionFlags);
49}
50
51pub enum CVOpenGLTextureCacheKeys {
52 ChromaSamplingMode,
53}
54
55impl From<CVOpenGLTextureCacheKeys> for CFStringRef {
56 fn from(key: CVOpenGLTextureCacheKeys) -> Self {
57 unsafe {
58 match key {
59 CVOpenGLTextureCacheKeys::ChromaSamplingMode => kCVOpenGLTextureCacheChromaSamplingModeKey,
60 }
61 }
62 }
63}
64
65impl From<CVOpenGLTextureCacheKeys> for CFString {
66 fn from(key: CVOpenGLTextureCacheKeys) -> Self {
67 unsafe { CFString::wrap_under_get_rule(CFStringRef::from(key)) }
68 }
69}
70
71pub enum CVOpenGLTextureCacheChromaSamplingMode {
72 Automatic,
73 HighestQuality,
74 BestPerformance,
75}
76
77impl From<CVOpenGLTextureCacheChromaSamplingMode> for CFStringRef {
78 fn from(mode: CVOpenGLTextureCacheChromaSamplingMode) -> Self {
79 unsafe {
80 match mode {
81 CVOpenGLTextureCacheChromaSamplingMode::Automatic => kCVOpenGLTextureCacheChromaSamplingModeAutomatic,
82 CVOpenGLTextureCacheChromaSamplingMode::HighestQuality => kCVOpenGLTextureCacheChromaSamplingModeHighestQuality,
83 CVOpenGLTextureCacheChromaSamplingMode::BestPerformance => kCVOpenGLTextureCacheChromaSamplingModeBestPerformance,
84 }
85 }
86 }
87}
88
89impl From<CVOpenGLTextureCacheChromaSamplingMode> for CFString {
90 fn from(mode: CVOpenGLTextureCacheChromaSamplingMode) -> Self {
91 unsafe { CFString::wrap_under_get_rule(CFStringRef::from(mode)) }
92 }
93}
94
95pub struct CVOpenGLTextureCache(CVOpenGLTextureCacheRef);
96
97impl Drop for CVOpenGLTextureCache {
98 fn drop(&mut self) {
99 unsafe { CVOpenGLTextureCacheRelease(self.0) }
100 }
101}
102
103impl_TCFType!(CVOpenGLTextureCache, CVOpenGLTextureCacheRef, CVOpenGLTextureCacheGetTypeID);
104impl_CFTypeDescription!(CVOpenGLTextureCache);
105
106impl CVOpenGLTextureCache {
107 #[inline]
108 pub unsafe fn new(
109 cache_attributes: Option<&CFDictionary<CFString, CFString>>,
110 cgl_context: CGLContextObj,
111 cgl_pixel_format: CGLPixelFormatObj,
112 texture_attributes: Option<&CFDictionary<CFString, CFType>>,
113 ) -> Result<CVOpenGLTextureCache, CVReturn> {
114 let mut cache: CVOpenGLTextureCacheRef = null_mut();
115 let status = unsafe {
116 CVOpenGLTextureCacheCreate(
117 kCFAllocatorDefault,
118 cache_attributes.map_or(null(), |attrs| attrs.as_concrete_TypeRef()),
119 cgl_context,
120 cgl_pixel_format,
121 texture_attributes.map_or(null(), |attrs| attrs.as_concrete_TypeRef()),
122 &mut cache,
123 )
124 };
125 if status == kCVReturnSuccess {
126 Ok(unsafe { TCFType::wrap_under_create_rule(cache) })
127 } else {
128 Err(status)
129 }
130 }
131
132 #[inline]
133 pub fn create_texture_from_image(
134 &self,
135 source_image: &CVImageBuffer,
136 attributes: Option<&CFDictionary<CFString, CFType>>,
137 ) -> Result<CVOpenGLTexture, CVReturn> {
138 let mut texture: CVOpenGLTextureRef = null_mut();
139 let status = unsafe {
140 CVOpenGLTextureCacheCreateTextureFromImage(
141 kCFAllocatorDefault,
142 self.as_concrete_TypeRef(),
143 source_image.as_concrete_TypeRef(),
144 attributes.map_or(null(), |attrs| attrs.as_concrete_TypeRef()),
145 &mut texture,
146 )
147 };
148 if status == kCVReturnSuccess {
149 Ok(unsafe { TCFType::wrap_under_create_rule(texture) })
150 } else {
151 Err(status)
152 }
153 }
154
155 #[inline]
156 pub fn flush(&self, options: CVOptionFlags) {
157 unsafe { CVOpenGLTextureCacheFlush(self.as_concrete_TypeRef(), options) }
158 }
159}