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