core_video/
opengl_buffer_pool.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 opengl_buffer::{CVOpenGLBuffer, CVOpenGLBufferRef},
12 r#return::{kCVReturnSuccess, CVReturn},
13};
14
15#[repr(C)]
16pub struct __CVOpenGLBufferPool(c_void);
17
18pub type CVOpenGLBufferPoolRef = *mut __CVOpenGLBufferPool;
19
20extern "C" {
21 pub static kCVOpenGLBufferPoolMinimumBufferCountKey: CFStringRef;
22 pub static kCVOpenGLBufferPoolMaximumBufferAgeKey: CFStringRef;
23
24 pub fn CVOpenGLBufferPoolGetTypeID() -> CFTypeID;
25 pub fn CVOpenGLBufferPoolRetain(openGLBufferPool: CVOpenGLBufferPoolRef) -> CVOpenGLBufferPoolRef;
26 pub fn CVOpenGLBufferPoolRelease(openGLBufferPool: CVOpenGLBufferPoolRef);
27 pub fn CVOpenGLBufferPoolCreate(
28 allocator: CFAllocatorRef,
29 poolAttributes: CFDictionaryRef,
30 openGLBufferAttributes: CFDictionaryRef,
31 poolOut: *mut CVOpenGLBufferPoolRef,
32 ) -> CVReturn;
33 pub fn CVOpenGLBufferPoolGetAttributes(pool: CVOpenGLBufferPoolRef) -> CFDictionaryRef;
34 pub fn CVOpenGLBufferPoolGetOpenGLBufferAttributes(pool: CVOpenGLBufferPoolRef) -> CFDictionaryRef;
35 pub fn CVOpenGLBufferPoolCreateOpenGLBuffer(
36 allocator: CFAllocatorRef,
37 openGLBufferPool: CVOpenGLBufferPoolRef,
38 openGLBufferOut: *mut CVOpenGLBufferRef,
39 ) -> CVReturn;
40}
41
42pub enum CVOpenGLBufferPoolKeys {
43 MinimumBufferCount,
44 MaximumBufferAge,
45}
46
47impl From<CVOpenGLBufferPoolKeys> for CFStringRef {
48 fn from(key: CVOpenGLBufferPoolKeys) -> Self {
49 unsafe {
50 match key {
51 CVOpenGLBufferPoolKeys::MinimumBufferCount => kCVOpenGLBufferPoolMinimumBufferCountKey,
52 CVOpenGLBufferPoolKeys::MaximumBufferAge => kCVOpenGLBufferPoolMaximumBufferAgeKey,
53 }
54 }
55 }
56}
57
58impl From<CVOpenGLBufferPoolKeys> for CFString {
59 fn from(key: CVOpenGLBufferPoolKeys) -> Self {
60 unsafe { CFString::wrap_under_get_rule(CFStringRef::from(key)) }
61 }
62}
63
64pub struct CVOpenGLBufferPool(CVOpenGLBufferPoolRef);
65
66impl Drop for CVOpenGLBufferPool {
67 fn drop(&mut self) {
68 unsafe { CVOpenGLBufferPoolRelease(self.0) }
69 }
70}
71
72impl_TCFType!(CVOpenGLBufferPool, CVOpenGLBufferPoolRef, CVOpenGLBufferPoolGetTypeID);
73impl_CFTypeDescription!(CVOpenGLBufferPool);
74
75impl CVOpenGLBufferPool {
76 #[inline]
77 pub fn new(
78 pool_attributes: Option<&CFDictionary<CFString, CFType>>,
79 opengl_buffer_attributes: Option<&CFDictionary<CFString, CFType>>,
80 ) -> Result<CVOpenGLBufferPool, CVReturn> {
81 let mut pool: CVOpenGLBufferPoolRef = null_mut();
82 let status = unsafe {
83 CVOpenGLBufferPoolCreate(
84 kCFAllocatorDefault,
85 pool_attributes.map_or(null(), |attrs| attrs.as_concrete_TypeRef()),
86 opengl_buffer_attributes.map_or(null(), |attrs| attrs.as_concrete_TypeRef()),
87 &mut pool,
88 )
89 };
90 if status == kCVReturnSuccess {
91 Ok(unsafe { TCFType::wrap_under_create_rule(pool) })
92 } else {
93 Err(status)
94 }
95 }
96
97 #[inline]
98 pub fn get_attributes(&self) -> Option<CFDictionary<CFString, CFType>> {
99 unsafe {
100 let attributes = CVOpenGLBufferPoolGetAttributes(self.as_concrete_TypeRef());
101 if attributes.is_null() {
102 None
103 } else {
104 Some(TCFType::wrap_under_create_rule(attributes))
105 }
106 }
107 }
108
109 #[inline]
110 pub fn get_opengl_buffer_attributes(&self) -> Option<CFDictionary<CFString, CFType>> {
111 unsafe {
112 let attributes = CVOpenGLBufferPoolGetOpenGLBufferAttributes(self.as_concrete_TypeRef());
113 if attributes.is_null() {
114 None
115 } else {
116 Some(TCFType::wrap_under_create_rule(attributes))
117 }
118 }
119 }
120
121 #[inline]
122 pub fn create_open_gl_buffer(&self) -> Result<CVOpenGLBuffer, CVReturn> {
123 let mut buffer: CVOpenGLBufferRef = null_mut();
124 let status = unsafe { CVOpenGLBufferPoolCreateOpenGLBuffer(kCFAllocatorDefault, self.as_concrete_TypeRef(), &mut buffer) };
125 if status == kCVReturnSuccess {
126 Ok(unsafe { TCFType::wrap_under_create_rule(buffer) })
127 } else {
128 Err(status)
129 }
130 }
131}