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