Skip to main content

core_video/
opengl_buffer_pool.rs

1use 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}