core_video/
opengl_buffer.rs1use std::ptr::{null, null_mut};
2
3use core_foundation::{
4 base::{kCFAllocatorDefault, CFAllocatorRef, CFType, CFTypeID, TCFType},
5 declare_TCFType,
6 dictionary::{CFDictionary, CFDictionaryRef},
7 impl_CFTypeDescription, impl_TCFType,
8 string::{CFString, CFStringRef},
9};
10use libc::size_t;
11
12use crate::{
13 buffer::TCVBuffer,
14 image_buffer::{CVImageBufferRef, TCVImageBuffer},
15 r#return::{kCVReturnSuccess, CVReturn},
16 CGLContextObj, GLenum, GLint,
17};
18
19pub type CVOpenGLBufferRef = CVImageBufferRef;
20
21extern "C" {
22 pub static kCVOpenGLBufferWidth: CFStringRef;
23 pub static kCVOpenGLBufferHeight: CFStringRef;
24 pub static kCVOpenGLBufferTarget: CFStringRef;
25 pub static kCVOpenGLBufferInternalFormat: CFStringRef;
26 pub static kCVOpenGLBufferMaximumMipmapLevel: CFStringRef;
27
28 pub fn CVOpenGLBufferGetTypeID() -> CFTypeID;
29 pub fn CVOpenGLBufferRetain(buffer: CVOpenGLBufferRef) -> CVOpenGLBufferRef;
30 pub fn CVOpenGLBufferRelease(buffer: CVOpenGLBufferRef);
31 pub fn CVOpenGLBufferCreate(
32 allocator: CFAllocatorRef,
33 width: size_t,
34 height: size_t,
35 attributes: CFDictionaryRef,
36 bufferOut: *mut CVOpenGLBufferRef,
37 ) -> CVReturn;
38 pub fn CVOpenGLBufferGetAttributes(openGLBuffer: CVOpenGLBufferRef) -> CFDictionaryRef;
39 pub fn CVOpenGLBufferAttach(openGLBuffer: CVOpenGLBufferRef, cglContext: CGLContextObj, face: GLenum, level: GLint, screen: GLint) -> CVReturn;
40}
41
42pub enum CVOpenGLBufferKeys {
43 Width,
44 Height,
45 Target,
46 InternalFormat,
47 MaximumMipmapLevel,
48}
49
50impl From<CVOpenGLBufferKeys> for CFStringRef {
51 fn from(key: CVOpenGLBufferKeys) -> Self {
52 unsafe {
53 match key {
54 CVOpenGLBufferKeys::Width => kCVOpenGLBufferWidth,
55 CVOpenGLBufferKeys::Height => kCVOpenGLBufferHeight,
56 CVOpenGLBufferKeys::Target => kCVOpenGLBufferTarget,
57 CVOpenGLBufferKeys::InternalFormat => kCVOpenGLBufferInternalFormat,
58 CVOpenGLBufferKeys::MaximumMipmapLevel => kCVOpenGLBufferMaximumMipmapLevel,
59 }
60 }
61 }
62}
63
64impl From<CVOpenGLBufferKeys> for CFString {
65 fn from(key: CVOpenGLBufferKeys) -> Self {
66 unsafe { CFString::wrap_under_get_rule(CFStringRef::from(key)) }
67 }
68}
69
70declare_TCFType!(CVOpenGLBuffer, CVOpenGLBufferRef);
71impl_TCFType!(CVOpenGLBuffer, CVOpenGLBufferRef, CVOpenGLBufferGetTypeID);
72impl_CFTypeDescription!(CVOpenGLBuffer);
73
74impl TCVBuffer for CVOpenGLBuffer {}
75impl TCVImageBuffer for CVOpenGLBuffer {}
76
77impl CVOpenGLBuffer {
78 #[inline]
79 pub fn new(width: size_t, height: size_t, attributes: Option<&CFDictionary<CFString, CFType>>) -> Result<CVOpenGLBuffer, CVReturn> {
80 let mut buffer: CVOpenGLBufferRef = null_mut();
81 let status = unsafe {
82 CVOpenGLBufferCreate(kCFAllocatorDefault, width, height, attributes.map_or(null(), |attrs| attrs.as_concrete_TypeRef()), &mut buffer)
83 };
84 if status == kCVReturnSuccess {
85 Ok(unsafe { TCFType::wrap_under_create_rule(buffer) })
86 } else {
87 Err(status)
88 }
89 }
90
91 #[inline]
92 pub fn get_attributes(&self) -> Option<CFDictionary<CFString, CFType>> {
93 unsafe {
94 let attributes = CVOpenGLBufferGetAttributes(self.as_concrete_TypeRef());
95 if attributes.is_null() {
96 None
97 } else {
98 Some(TCFType::wrap_under_create_rule(attributes))
99 }
100 }
101 }
102
103 #[inline]
104 pub unsafe fn attach(&self, cgl_context: CGLContextObj, face: GLenum, level: GLint, screen: GLint) -> Result<(), CVReturn> {
105 let status = unsafe { CVOpenGLBufferAttach(self.as_concrete_TypeRef(), cgl_context, face, level, screen) };
106 if status == kCVReturnSuccess {
107 Ok(())
108 } else {
109 Err(status)
110 }
111 }
112}