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